/*
 *   SPDX-FileCopyrightText: 2024 Micah Stanley <stanleymicah@proton.me>
 *
 *   SPDX-License-Identifier: LGPL-2.0-or-later
 */

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.1

import org.kde.plasma.clock
import org.kde.plasma.components 3.0 as PlasmaComponents
import org.kde.plasma.private.mobileshell as MobileShell
import org.kde.plasma.private.mobileshell.shellsettingsplugin as ShellSettings
import org.kde.kirigami as Kirigami

Item {
    id: root

    required property var actionDrawer
    required property var contentContainer
    required property var swipeArea

    property alias mediaControlsWidget: notificationWidget.header
    property alias notificationWidget: notificationWidget
    property real contentY: notificationWidget.listView.contentY

    // The sibling toolbar whose height must be subtracted from the available space.
    property Item toolButtonsItem: null

    property real topPadding: {
        if (actionDrawer.mode == MobileShell.ActionDrawer.Portrait)
            return Kirigami.Units.largeSpacing;
        if (ShellSettings.Settings.convergenceModeEnabled)
            return Kirigami.Units.largeSpacing;
        return date.y + date.height + Kirigami.Units.smallSpacing * 6;
    }
    property real topMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? actionDrawer.offsetResistance + 1 : 0

    readonly property real minWidthHeight: Math.min(actionDrawer.width, actionDrawer.height)
    readonly property bool hasNotifications: notificationWidget.hasNotifications
    readonly property bool listOverflowing: notificationWidget.listView.listOverflowing

    // External cap for convergence mode; -1 means uncapped.
    property real maximumHeight: -1

    height: {
        let toolH = toolButtonsItem ? toolButtonsItem.height : 0;
        let h = Math.min(actionDrawer.height - toolH, notificationWidget.listView.contentHeight + Kirigami.Units.largeSpacing + topMargin);
        return maximumHeight > 0 ? Math.min(h, maximumHeight) : h;
    }

    // time source for the time and date whenin landscape mode
    Clock {
        id: clockSource
    }

    MobileShell.VelocityCalculator {
        id: velocityCalculator
    }

    // notification list widget
    // margin adjusted to fit and position into the action drawer
    MobileShell.NotificationsWidget {
        id: notificationWidget
        anchors.fill: parent
        anchors.topMargin: root.topMargin
        anchors.rightMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : Math.max(root.width - Kirigami.Units.gridUnit * 25, 0)
        anchors.leftMargin: actionDrawer.mode == MobileShell.ActionDrawer.Portrait ? 0 : -Kirigami.Units.gridUnit

        historyModel: actionDrawer.notificationModel
        historyModelType: actionDrawer.notificationModelType
        notificationSettings: actionDrawer.notificationSettings
        actionsRequireUnlock: actionDrawer.restrictedPermissions
        onUnlockRequested: actionDrawer.permissionsRequested()
        topPadding: root.topPadding
        showHeader: actionDrawer.mode != MobileShell.ActionDrawer.Portrait
        listView.interactive: !actionDrawer.dragging && root.listOverflowing

        cardColorScheme: Kirigami.Theme.View

        Connections {
            target: actionDrawer

            function onRunPendingNotificationAction() {
                notificationWidget.runPendingAction();
            }
        }

        // the first swipe when at the top of the notification list is handled using a MouseArea, not the flickable
        // this is so one can swipe down from the top of the notification drawer to expand the action drawer
        DragHandler {
            id: dragHandler
            // disable the draghandler when we are not at the top of the notification list as it can interfere with the notification scrolling
            yAxis.enabled: notificationWidget.listView.atYBeginning || active
            xAxis.enabled: false

            property bool startActive: false

            property real startOffset: 0
            property real startMouseY: 0
            property real lastMouseY: 0

            property bool startedAtYBeginning: false
            property bool startedAtYEnd: false
            property bool drawerDrag: true

            property string currentState

            onTranslationChanged: {
                if (startActive) {
                    dragHandler.startedAtYBeginning = notificationWidget.listView.atYBeginning;
                    dragHandler.startedAtYEnd = notificationWidget.listView.atYEnd;
                    startActive = false;

                    if (notificationWidget.listView.atYBeginning) {
                        currentState = actionDrawer.state;
                        actionDrawer.cancelAnimations();
                        actionDrawer.dragging = true;
                        actionDrawer.opened = true;
                        dragHandler.startOffset = actionDrawer.offset;
                        dragHandler.startMouseY = translation.y;
                        dragHandler.lastMouseY = dragHandler.startMouseY;
                        dragHandler.drawerDrag = true;

                        velocityCalculator.startMeasure();
                        velocityCalculator.changePosition(notificationWidget.listView.contentY);
                    }
                }

                if (!actionDrawer.dragging) {
                    return;
                }

                if (!(dragHandler.startedAtYBeginning && dragHandler.startedAtYEnd) && ((dragHandler.startedAtYBeginning && (dragHandler.startMouseY - translation.y) > 0) || (dragHandler.startedAtYEnd && (translation.y - dragHandler.startMouseY) > 0))) {
                    actionDrawer.state = currentState;
                    dragHandler.drawerDrag = false;
                }

                if (dragHandler.drawerDrag) {
                    actionDrawer.offset = dragHandler.startOffset - (dragHandler.startMouseY - translation.y);
                } else {
                    let contentY = notificationWidget.listView.contentY - (translation.y - dragHandler.lastMouseY);

                    notificationWidget.listView.contentY = contentY;
                    velocityCalculator.changePosition(notificationWidget.listView.contentY);
                    dragHandler.lastMouseY = translation.y;
                }
            }

            onActiveChanged: {
                startActive = active;

                if (!active) { // release event
                    if (actionDrawer.dragging) {
                        if (dragHandler.drawerDrag) {
                            actionDrawer.updateState();
                        } else {
                            notificationWidget.listView.flick(0, -velocityCalculator.velocity);
                        }
                    }
                    actionDrawer.dragging = false;
                    dragHandler.drawerDrag = true;
                }
            }
        }

    }

    // time and date displayed in landscape mode
    Item {
        id: landscapeModeHeader
        anchors.fill: parent
        visible: actionDrawer.mode != MobileShell.ActionDrawer.Portrait
                 && !ShellSettings.Settings.convergenceModeEnabled

        transform: [
            Translate {
                y: -notificationWidget.listView.contentY + notificationWidget.listView.originY
            }
        ]

        PlasmaComponents.Label {
            id: clock
            text: Qt.formatTime(clockSource.dateTime, MobileShell.ShellUtil.isSystem24HourFormat ? "h:mm" : "h:mm ap")
            verticalAlignment: Qt.AlignVCenter

            anchors {
                left: parent.left
                top: parent.top
                topMargin: minWidthHeight * 0.03
            }

            font.pixelSize: Math.min(40, minWidthHeight * 0.1)
            font.weight: Font.ExtraLight
            elide: Text.ElideRight
        }

        PlasmaComponents.Label {
            id: date
            text: Qt.formatDate(clockSource.dateTime, "ddd MMMM d")
            verticalAlignment: Qt.AlignTop
            color: Kirigami.Theme.disabledTextColor

            anchors {
                left: parent.left
                top: clock.bottom
                topMargin: Kirigami.Units.smallSpacing
            }

            font.pixelSize: Math.min(20, minWidthHeight * 0.05)
            font.weight: Font.Light
        }
    }
}
