import QtQuick
import qs.Common
import qs.Services
import qs.Widgets

DankPopout {
    id: root

    layerNamespace: "dms:notification-center-popout"
    fullHeightSurface: true

    property bool notificationHistoryVisible: false
    property var triggerScreen: null
    property real stablePopupHeight: 400
    property real _lastAlignedContentHeight: -1
    property bool _pendingSizedOpen: false
    property bool _heightUpdatePending: false

    function updateStablePopupHeight() {
        const item = contentLoader.item;
        if (item && !root.shouldBeVisible) {
            const notificationList = findChild(item, "notificationList");
            if (notificationList && typeof notificationList.forceLayout === "function") {
                notificationList.forceLayout();
            }
        }
        const target = item ? Theme.px(item.implicitHeight, dpr) : 400;
        if (Math.abs(target - _lastAlignedContentHeight) < 0.5)
            return;
        _lastAlignedContentHeight = target;
        stablePopupHeight = target;
    }

    function queueStablePopupHeightUpdate() {
        if (_heightUpdatePending)
            return;
        _heightUpdatePending = true;
        Qt.callLater(() => {
            _heightUpdatePending = false;
            updateStablePopupHeight();
        });
    }

    NotificationKeyboardController {
        id: keyboardController
        listView: null
        isOpen: root.shouldBeVisible
        onClose: () => {
            notificationHistoryVisible = false;
        }
    }

    popupWidth: 400 + Theme.spacingL
    popupHeight: stablePopupHeight
    positioning: ""
    suspendShadowWhileResizing: false

    screen: triggerScreen

    function toggle() {
        notificationHistoryVisible = !notificationHistoryVisible;
    }

    // Re-open without toggling the flag (used when retargeting to another monitor).
    function present() {
        openSized();
    }

    function openSized() {
        if (!notificationHistoryVisible)
            return;

        primeContent();
        if (contentLoader.item) {
            updateStablePopupHeight();
            _pendingSizedOpen = false;
            Qt.callLater(() => {
                if (!notificationHistoryVisible)
                    return;
                updateStablePopupHeight();
                open();
                clearPrimedContent();
            });
            return;
        }

        _pendingSizedOpen = true;
    }

    onBackgroundClicked: {
        notificationHistoryVisible = false;
    }

    onNotificationHistoryVisibleChanged: {
        if (notificationHistoryVisible) {
            openSized();
        } else {
            _pendingSizedOpen = false;
            clearPrimedContent();
            close();
        }
    }

    function setupKeyboardNavigation() {
        if (!contentLoader.item)
            return;
        contentLoader.item.externalKeyboardController = keyboardController;

        const notificationList = findChild(contentLoader.item, "notificationList");
        const notificationHeader = findChild(contentLoader.item, "notificationHeader");

        if (notificationList) {
            keyboardController.listView = notificationList;
            notificationList.keyboardController = keyboardController;
        }
        if (notificationHeader) {
            notificationHeader.keyboardController = keyboardController;
        }

        keyboardController.reset();
        keyboardController.rebuildFlatNavigation();
    }

    Connections {
        target: contentLoader
        function onLoaded() {
            root.updateStablePopupHeight();
            if (root._pendingSizedOpen && root.notificationHistoryVisible) {
                Qt.callLater(() => {
                    if (!root._pendingSizedOpen || !root.notificationHistoryVisible)
                        return;
                    root.updateStablePopupHeight();
                    root._pendingSizedOpen = false;
                    root.open();
                    root.clearPrimedContent();
                });
                return;
            }
            if (root.shouldBeVisible)
                Qt.callLater(root.setupKeyboardNavigation);
        }
    }

    Connections {
        target: contentLoader.item
        function onImplicitHeightChanged() {
            root.queueStablePopupHeightUpdate();
        }
    }

    onDprChanged: updateStablePopupHeight()

    onShouldBeVisibleChanged: {
        notificationHistoryVisible = shouldBeVisible;

        if (shouldBeVisible) {
            NotificationService.onOverlayOpen();
            updateStablePopupHeight();
            if (contentLoader.item)
                Qt.callLater(setupKeyboardNavigation);
        } else {
            NotificationService.onOverlayClose();
            keyboardController.keyboardNavigationActive = false;
            NotificationService.expandedGroups = {};
            NotificationService.expandedMessages = {};
        }
    }

    function findChild(parent, objectName) {
        if (parent.objectName === objectName) {
            return parent;
        }
        for (let i = 0; i < parent.children.length; i++) {
            const child = parent.children[i];
            const result = findChild(child, objectName);
            if (result) {
                return result;
            }
        }
        return null;
    }

    content: Component {
        Rectangle {
            id: notificationContent

            LayoutMirroring.enabled: I18n.isRtl
            LayoutMirroring.childrenInherit: true

            property var externalKeyboardController: null
            property real cachedHeaderHeight: 32
            readonly property real settingsMaxHeight: {
                const screenH = root.screen ? root.screen.height : 1080;
                const maxPopupH = screenH * 0.8;
                const overhead = cachedHeaderHeight + Theme.spacingL * 2 + Theme.spacingM * 2;
                return Math.max(200, maxPopupH - overhead - 150);
            }
            implicitHeight: {
                let baseHeight = Theme.spacingL * 2;
                baseHeight += cachedHeaderHeight;
                baseHeight += Theme.spacingM * 2;

                const settingsHeight = notificationSettings.expanded ? Math.min(notificationSettings.naturalContentHeight, settingsMaxHeight) : 0;
                const currentListHeight = root.shouldBeVisible ? notificationList.stableContentHeight : notificationList.listContentHeight;
                let listHeight = notificationHeader.currentTab === 0 ? currentListHeight : Math.max(200, NotificationService.historyList.length * 80);
                if (notificationHeader.currentTab === 0 && NotificationService.groupedNotifications.length === 0) {
                    listHeight = 200;
                }
                if (notificationHeader.currentTab === 1 && NotificationService.historyList.length === 0) {
                    listHeight = 200;
                }

                const maxContentArea = 600;
                const availableListSpace = Math.max(200, maxContentArea - settingsHeight);

                baseHeight += settingsHeight;
                baseHeight += Math.min(listHeight, availableListSpace);

                const maxHeight = root.screen ? root.screen.height * 0.8 : Screen.height * 0.8;
                return Math.max(300, Math.min(baseHeight, maxHeight));
            }

            color: "transparent"
            focus: true

            Component.onCompleted: {
                if (root.shouldBeVisible) {
                    forceActiveFocus();
                }
            }

            Keys.onPressed: event => {
                if (event.key === Qt.Key_Escape) {
                    notificationHistoryVisible = false;
                    event.accepted = true;
                    return;
                }

                if (event.key === Qt.Key_Left) {
                    if (notificationHeader.currentTab > 0) {
                        notificationHeader.currentTab = 0;
                        event.accepted = true;
                    }
                    return;
                }

                if (event.key === Qt.Key_Right) {
                    if (notificationHeader.currentTab === 0 && SettingsData.notificationHistoryEnabled) {
                        notificationHeader.currentTab = 1;
                        event.accepted = true;
                    }
                    return;
                }
                if (notificationHeader.currentTab === 1) {
                    historyList.handleKey(event);
                    return;
                }
                if (externalKeyboardController) {
                    externalKeyboardController.handleKey(event);
                }
            }

            Connections {
                function onShouldBeVisibleChanged() {
                    if (root.shouldBeVisible) {
                        Qt.callLater(() => {
                            notificationContent.forceActiveFocus();
                        });
                    } else {
                        notificationContent.focus = false;
                    }
                }
                target: root
            }

            FocusScope {
                id: contentColumn

                anchors.fill: parent
                anchors.margins: Theme.spacingL
                focus: true

                Column {
                    id: contentColumnInner
                    anchors.fill: parent
                    spacing: Theme.spacingM

                    NotificationHeader {
                        id: notificationHeader
                        objectName: "notificationHeader"
                        transientSurfaceTracker: root.transientSurfaceTracker
                        onHeightChanged: notificationContent.cachedHeaderHeight = height
                    }

                    NotificationSettings {
                        id: notificationSettings
                        transientSurfaceTracker: root.transientSurfaceTracker
                        expanded: notificationHeader.showSettings
                        maxAllowedHeight: notificationContent.settingsMaxHeight
                    }

                    Item {
                        visible: notificationHeader.currentTab === 0
                        width: parent.width
                        height: parent.height - notificationContent.cachedHeaderHeight - notificationSettings.height - contentColumnInner.spacing * 2

                        KeyboardNavigatedNotificationList {
                            id: notificationList
                            objectName: "notificationList"
                            anchors.fill: parent
                            anchors.leftMargin: -shadowHorizontalGutter
                            anchors.rightMargin: -shadowHorizontalGutter
                            anchors.topMargin: -(shadowVerticalGutter + delegateShadowGutter / 2)
                            anchors.bottomMargin: -(shadowVerticalGutter + delegateShadowGutter / 2)
                            cardAnimateExpansion: true
                            transientSurfaceTracker: root.transientSurfaceTracker
                        }
                    }

                    HistoryNotificationList {
                        id: historyList
                        visible: notificationHeader.currentTab === 1
                        width: parent.width
                        height: parent.height - notificationContent.cachedHeaderHeight - notificationSettings.height - contentColumnInner.spacing * 2
                    }
                }
            }

            NotificationKeyboardHints {
                id: keyboardHints
                anchors.bottom: parent.bottom
                anchors.left: parent.left
                anchors.right: parent.right
                anchors.margins: Theme.spacingL
                showHints: notificationHeader.currentTab === 0 ? (externalKeyboardController && externalKeyboardController.showKeyboardHints) || false : historyList.showKeyboardHints
                z: 200
            }
        }
    }
}
