import QtQuick
import qs.Services

QtObject {
    id: controller

    property var listView: null
    property bool isOpen: false
    property var onClose: null

    property int selectionVersion: 0

    property bool keyboardNavigationActive: false
    property int selectedFlatIndex: 0
    property var flatNavigation: []
    property bool showKeyboardHints: false

    property string selectedNotificationId: ""
    property string selectedGroupKey: ""
    property string selectedItemType: ""
    property bool isTogglingGroup: false
    property bool isRebuilding: false

    function rebuildFlatNavigation() {
        isRebuilding = true;

        const nav = [];
        const groups = NotificationService.groupedNotifications;

        for (var i = 0; i < groups.length; i++) {
            const group = groups[i];
            const isExpanded = NotificationService.expandedGroups[group.key] || false;

            nav.push({
                "type": "group",
                "groupIndex": i,
                "notificationIndex": -1,
                "groupKey": group.key,
                "notificationId": ""
            });

            if (isExpanded) {
                const notifications = group.notifications || [];
                const maxNotifications = Math.min(notifications.length, 10);
                for (var j = 0; j < maxNotifications; j++) {
                    const notifId = String(notifications[j] && notifications[j].notification && notifications[j].notification.id ? notifications[j].notification.id : "");
                    nav.push({
                        "type": "notification",
                        "groupIndex": i,
                        "notificationIndex": j,
                        "groupKey": group.key,
                        "notificationId": notifId
                    });
                }
            }
        }

        flatNavigation = nav;
        updateSelectedIndexFromId();
        isRebuilding = false;
    }

    function updateSelectedIndexFromId() {
        if (!keyboardNavigationActive) {
            return;
        }

        for (var i = 0; i < flatNavigation.length; i++) {
            const item = flatNavigation[i];

            if (selectedItemType === "group" && item.type === "group" && item.groupKey === selectedGroupKey) {
                selectedFlatIndex = i;
                selectionVersion++; // Trigger UI update
                return;
            } else if (selectedItemType === "notification" && item.type === "notification" && String(item.notificationId) === String(selectedNotificationId)) {
                selectedFlatIndex = i;
                selectionVersion++; // Trigger UI update
                return;
            }
        }

        // If not found, try to find the same group but select the group header instead
        if (selectedItemType === "notification") {
            for (var j = 0; j < flatNavigation.length; j++) {
                const groupItem = flatNavigation[j];
                if (groupItem.type === "group" && groupItem.groupKey === selectedGroupKey) {
                    selectedFlatIndex = j;
                    selectedItemType = "group";
                    selectedNotificationId = "";
                    selectionVersion++; // Trigger UI update
                    return;
                }
            }
        }

        // If still not found, clamp to valid range and update
        if (flatNavigation.length > 0) {
            selectedFlatIndex = Math.min(selectedFlatIndex, flatNavigation.length - 1);
            selectedFlatIndex = Math.max(selectedFlatIndex, 0);
            updateSelectedIdFromIndex();
            selectionVersion++; // Trigger UI update
        }
    }

    function updateSelectedIdFromIndex() {
        if (selectedFlatIndex >= 0 && selectedFlatIndex < flatNavigation.length) {
            const item = flatNavigation[selectedFlatIndex];
            selectedItemType = item.type;
            selectedGroupKey = item.groupKey;
            selectedNotificationId = item.notificationId;
        }
    }

    function reset() {
        selectedFlatIndex = 0;
        keyboardNavigationActive = false;
        showKeyboardHints = false;
        // Reset keyboardActive when modal is reset
        if (listView) {
            listView.keyboardActive = false;
        }
        rebuildFlatNavigation();
    }

    function selectNext() {
        keyboardNavigationActive = true;
        if (flatNavigation.length === 0)
            return;

        // Re-enable auto-scrolling when arrow keys are used
        if (listView && listView.enableAutoScroll) {
            listView.enableAutoScroll();
        }

        selectedFlatIndex = Math.min(selectedFlatIndex + 1, flatNavigation.length - 1);
        updateSelectedIdFromIndex();
        selectionVersion++;
        ensureVisible();
    }

    function selectNextWrapping() {
        keyboardNavigationActive = true;
        if (flatNavigation.length === 0)
            return;

        // Re-enable auto-scrolling when arrow keys are used
        if (listView && listView.enableAutoScroll) {
            listView.enableAutoScroll();
        }

        selectedFlatIndex = (selectedFlatIndex + 1) % flatNavigation.length;
        updateSelectedIdFromIndex();
        selectionVersion++;
        ensureVisible();
    }

    function selectPrevious() {
        keyboardNavigationActive = true;
        if (flatNavigation.length === 0)
            return;

        // Re-enable auto-scrolling when arrow keys are used
        if (listView && listView.enableAutoScroll) {
            listView.enableAutoScroll();
        }

        selectedFlatIndex = Math.max(selectedFlatIndex - 1, 0);
        updateSelectedIdFromIndex();
        selectionVersion++;
        ensureVisible();
    }

    function toggleGroupExpanded() {
        if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
            return;
        const currentItem = flatNavigation[selectedFlatIndex];
        const groups = NotificationService.groupedNotifications;
        const group = groups[currentItem.groupIndex];
        if (!group)
            return;

        // Prevent expanding groups with < 2 notifications
        const notificationCount = group.notifications ? group.notifications.length : 0;
        if (notificationCount < 2)
            return;
        const wasExpanded = NotificationService.expandedGroups[group.key] || false;
        const groupIndex = currentItem.groupIndex;

        isTogglingGroup = true;
        NotificationService.toggleGroupExpansion(group.key);
        rebuildFlatNavigation();

        // Smart selection after toggle
        if (!wasExpanded) {
            // Just expanded - move to first notification in the group
            for (var i = 0; i < flatNavigation.length; i++) {
                if (flatNavigation[i].type === "notification" && flatNavigation[i].groupIndex === groupIndex) {
                    selectedFlatIndex = i;
                    break;
                }
            }
        } else {
            // Just collapsed - stay on the group header
            for (var i = 0; i < flatNavigation.length; i++) {
                if (flatNavigation[i].type === "group" && flatNavigation[i].groupIndex === groupIndex) {
                    selectedFlatIndex = i;
                    break;
                }
            }
        }

        isTogglingGroup = false;
    }

    function handleEnterKey() {
        if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
            return;
        const currentItem = flatNavigation[selectedFlatIndex];
        const groups = NotificationService.groupedNotifications;
        const group = groups[currentItem.groupIndex];
        if (!group)
            return;
        if (currentItem.type === "group") {
            const notificationCount = group.notifications ? group.notifications.length : 0;
            if (notificationCount >= 2) {
                toggleGroupExpanded();
            } else {
                executeAction(0);
            }
        } else if (currentItem.type === "notification") {
            executeAction(0);
        }
    }

    function toggleTextExpanded() {
        if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
            return;
        const currentItem = flatNavigation[selectedFlatIndex];
        const groups = NotificationService.groupedNotifications;
        const group = groups[currentItem.groupIndex];
        if (!group)
            return;
        let messageId = "";

        if (currentItem.type === "group") {
            messageId = group.latestNotification?.notification?.id + "_desc";
        } else if (currentItem.type === "notification" && currentItem.notificationIndex >= 0 && currentItem.notificationIndex < group.notifications.length) {
            messageId = group.notifications[currentItem.notificationIndex]?.notification?.id + "_desc";
        }

        if (messageId) {
            NotificationService.toggleMessageExpansion(messageId);
        }
    }

    function executeAction(actionIndex) {
        if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
            return;
        const currentItem = flatNavigation[selectedFlatIndex];
        const groups = NotificationService.groupedNotifications;
        const group = groups[currentItem.groupIndex];
        if (!group)
            return;
        let actions = [];

        if (currentItem.type === "group") {
            actions = group.latestNotification?.actions || [];
        } else if (currentItem.type === "notification" && currentItem.notificationIndex >= 0 && currentItem.notificationIndex < group.notifications.length) {
            actions = group.notifications[currentItem.notificationIndex]?.actions || [];
        }

        if (actionIndex >= 0 && actionIndex < actions.length) {
            const action = actions[actionIndex];
            if (action.invoke) {
                action.invoke();
                if (onClose)
                    onClose();
            }
        }
    }

    function clearSelected() {
        if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length)
            return;
        const currentItem = flatNavigation[selectedFlatIndex];
        const groups = NotificationService.groupedNotifications;
        const group = groups[currentItem.groupIndex];
        if (!group)
            return;
        if (currentItem.type === "group") {
            NotificationService.dismissGroup(group.key);
        } else if (currentItem.type === "notification") {
            const notification = group.notifications[currentItem.notificationIndex];
            NotificationService.dismissNotification(notification);
        }

        rebuildFlatNavigation();

        if (flatNavigation.length === 0) {
            keyboardNavigationActive = false;
            if (listView) {
                listView.keyboardActive = false;
            }
        } else {
            selectedFlatIndex = Math.min(selectedFlatIndex, flatNavigation.length - 1);
            updateSelectedIdFromIndex();
            ensureVisible();
        }
    }

    function findRepeater(parent) {
        if (!parent || !parent.children) {
            return null;
        }
        for (var i = 0; i < parent.children.length; i++) {
            const child = parent.children[i];
            if (child.objectName === "notificationRepeater") {
                return child;
            }
            const found = findRepeater(child);
            if (found) {
                return found;
            }
        }
        return null;
    }

    function ensureVisible() {
        if (flatNavigation.length === 0 || selectedFlatIndex >= flatNavigation.length || !listView)
            return;
        const currentItem = flatNavigation[selectedFlatIndex];

        if (keyboardNavigationActive && currentItem && currentItem.groupIndex >= 0) {
            if (currentItem.type === "notification") {
                const groupDelegate = listView.itemAtIndex(currentItem.groupIndex);
                if (groupDelegate && groupDelegate.children && groupDelegate.children.length > 0) {
                    const notificationCard = groupDelegate.children[0];
                    const repeater = findRepeater(notificationCard);

                    if (repeater && currentItem.notificationIndex < repeater.count) {
                        const notificationItem = repeater.itemAt(currentItem.notificationIndex);
                        if (notificationItem) {
                            const itemPos = notificationItem.mapToItem(listView.contentItem, 0, 0);
                            const itemY = itemPos.y;
                            const itemHeight = notificationItem.height;

                            const viewportTop = listView.contentY;
                            const viewportBottom = listView.contentY + listView.height;

                            if (itemY < viewportTop) {
                                listView.contentY = itemY - 20;
                            } else if (itemY + itemHeight > viewportBottom) {
                                listView.contentY = itemY + itemHeight - listView.height + 20;
                            }
                        }
                    }
                }
            } else {
                listView.positionViewAtIndex(currentItem.groupIndex, ListView.Contain);
            }

            listView.forceLayout();
        }
    }

    function handleKey(event) {
        if ((event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) && (event.modifiers & Qt.ShiftModifier)) {
            NotificationService.clearAllNotifications();
            rebuildFlatNavigation();
            if (flatNavigation.length === 0) {
                keyboardNavigationActive = false;
                if (listView) {
                    listView.keyboardActive = false;
                }
            } else {
                selectedFlatIndex = 0;
                updateSelectedIdFromIndex();
            }
            selectionVersion++;
            event.accepted = true;
            return;
        }

        if (event.key === Qt.Key_Escape) {
            if (keyboardNavigationActive) {
                keyboardNavigationActive = false;
                event.accepted = true;
            } else {
                if (onClose)
                    onClose();
                event.accepted = true;
            }
        } else if (event.key === Qt.Key_Down || event.key === 16777237) {
            if (!keyboardNavigationActive) {
                keyboardNavigationActive = true;
                rebuildFlatNavigation(); // Ensure we have fresh navigation data
                selectedFlatIndex = 0;
                updateSelectedIdFromIndex();
                // Set keyboardActive on listView to show highlight
                if (listView) {
                    listView.keyboardActive = true;
                }
                selectionVersion++;
                ensureVisible();
                event.accepted = true;
            } else {
                selectNext();
                event.accepted = true;
            }
        } else if (event.key === Qt.Key_Up || event.key === 16777235) {
            if (!keyboardNavigationActive) {
                keyboardNavigationActive = true;
                rebuildFlatNavigation(); // Ensure we have fresh navigation data
                selectedFlatIndex = 0;
                updateSelectedIdFromIndex();
                // Set keyboardActive on listView to show highlight
                if (listView) {
                    listView.keyboardActive = true;
                }
                selectionVersion++;
                ensureVisible();
                event.accepted = true;
            } else if (selectedFlatIndex === 0) {
                keyboardNavigationActive = false;
                // Reset keyboardActive when navigation is disabled
                if (listView) {
                    listView.keyboardActive = false;
                }
                selectionVersion++;
                event.accepted = true;
                return;
            } else {
                selectPrevious();
                event.accepted = true;
            }
        } else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
            if (!keyboardNavigationActive) {
                keyboardNavigationActive = true;
                rebuildFlatNavigation();
                selectedFlatIndex = 0;
                updateSelectedIdFromIndex();
                if (listView) {
                    listView.keyboardActive = true;
                }
                selectionVersion++;
                ensureVisible();
            } else {
                selectNext();
            }
            event.accepted = true;
        } else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
            if (!keyboardNavigationActive) {
                keyboardNavigationActive = true;
                rebuildFlatNavigation();
                selectedFlatIndex = 0;
                updateSelectedIdFromIndex();
                if (listView) {
                    listView.keyboardActive = true;
                }
                selectionVersion++;
                ensureVisible();
            } else if (selectedFlatIndex === 0) {
                keyboardNavigationActive = false;
                if (listView) {
                    listView.keyboardActive = false;
                }
                selectionVersion++;
            } else {
                selectPrevious();
            }
            event.accepted = true;
        } else if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
            if (!keyboardNavigationActive) {
                keyboardNavigationActive = true;
                rebuildFlatNavigation();
                selectedFlatIndex = 0;
                updateSelectedIdFromIndex();
                if (listView) {
                    listView.keyboardActive = true;
                }
                selectionVersion++;
                ensureVisible();
            } else {
                selectNext();
            }
            event.accepted = true;
        } else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
            if (!keyboardNavigationActive) {
                keyboardNavigationActive = true;
                rebuildFlatNavigation();
                selectedFlatIndex = 0;
                updateSelectedIdFromIndex();
                if (listView) {
                    listView.keyboardActive = true;
                }
                selectionVersion++;
                ensureVisible();
            } else if (selectedFlatIndex === 0) {
                keyboardNavigationActive = false;
                if (listView) {
                    listView.keyboardActive = false;
                }
                selectionVersion++;
            } else {
                selectPrevious();
            }
            event.accepted = true;
        } else if (keyboardNavigationActive) {
            if (event.key === Qt.Key_Space) {
                toggleGroupExpanded();
                event.accepted = true;
            } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
                handleEnterKey();
                event.accepted = true;
            } else if (event.key === Qt.Key_E) {
                toggleTextExpanded();
                event.accepted = true;
            } else if (event.key === Qt.Key_Delete || event.key === Qt.Key_Backspace) {
                clearSelected();
                event.accepted = true;
            } else if (event.key === Qt.Key_Tab) {
                selectNext();
                event.accepted = true;
            } else if (event.key === Qt.Key_Backtab) {
                selectPrevious();
                event.accepted = true;
            } else if (event.key >= Qt.Key_1 && event.key <= Qt.Key_9) {
                const actionIndex = event.key - Qt.Key_1;
                executeAction(actionIndex);
                event.accepted = true;
            }
        }

        if (event.key === Qt.Key_F10) {
            showKeyboardHints = !showKeyboardHints;
            event.accepted = true;
        }
    }

    // Get current selection info for UI
    function getCurrentSelection() {
        if (!keyboardNavigationActive || selectedFlatIndex < 0 || selectedFlatIndex >= flatNavigation.length) {
            return {
                "type": "",
                "groupIndex": -1,
                "notificationIndex": -1
            };
        }
        const result = flatNavigation[selectedFlatIndex] || {
            "type": "",
            "groupIndex": -1,
            "notificationIndex": -1
        };
        return result;
    }
}
