import Quickshell
import Quickshell.Io
import Quickshell.Services.Notifications
import Quickshell.Wayland
import QtQuick
import QtQuick.Layouts
import "../shared" as Shared

Scope {
    id: root

    // Expose for NC popout
    property alias trackedNotifications: server.trackedNotifications
    property bool dnd: false

    // External access (used by hyprlock notification widget via `qs ipc call notifications count`)
    IpcHandler {
        target: "notifications"
        function count(): int { return server.trackedNotifications.values.length }
    }

    // Toast IDs currently showing as popups (capped to avoid overflow)
    readonly property int maxToasts: 4
    property var toastIds: []
    property var timestamps: ({})  // notification id → arrival epoch ms

    NotificationServer {
        id: server
        keepOnReload: true
        bodySupported: true
        bodyMarkupSupported: false
        actionsSupported: true
        imageSupported: true
        persistenceSupported: true

        onNotification: notification => {
            notification.tracked = true;
            root.timestamps[notification.id] = Date.now();
            root.timestampsChanged();

            // Suppress toasts in DnD mode (still tracked for history)
            if (root.dnd) return;

            // Add to toast list, evict oldest if at capacity
            let ids = root.toastIds.slice();
            if (ids.length >= root.maxToasts) {
                let evicted = ids.shift();
                delete toastTimer.pending[evicted];
            }
            ids.push(notification.id);
            root.toastIds = ids;

            // Schedule toast removal (not notification removal)
            let timeout = notification.expireTimeout > 0 ? notification.expireTimeout * 1000 : 5000;
            if (notification.urgency !== NotificationUrgency.Critical) {
                toastTimer.createTimer(notification.id, timeout);
            }
        }
    }

    // Toast timer manager
    QtObject {
        id: toastTimer
        property var pending: ({})

        function createTimer(id, timeout) {
            pending[id] = Date.now() + timeout;
        }
    }

    Timer {
        interval: 500
        running: root.toastIds.length > 0
        repeat: true
        onTriggered: {
            let now = Date.now();
            let changed = false;
            let ids = root.toastIds.slice();

            for (let id in toastTimer.pending) {
                if (now >= toastTimer.pending[id]) {
                    let idx = ids.indexOf(parseInt(id));
                    if (idx >= 0) { ids.splice(idx, 1); changed = true; }
                    delete toastTimer.pending[id];
                }
            }

            if (changed) root.toastIds = ids;
        }
    }

    // Prune stale timestamps to prevent unbounded growth
    Timer {
        interval: 60000
        running: true
        repeat: true
        onTriggered: {
            let tracked = server.trackedNotifications;
            let live = new Set();
            for (let i = 0; i < tracked.values.length; i++)
                live.add(tracked.values[i].id);
            let ts = root.timestamps;
            let pruned = false;
            for (let id in ts) {
                if (!live.has(parseInt(id))) { delete ts[id]; pruned = true; }
            }
            if (pruned) root.timestampsChanged();
        }
    }

    // Toast popup window — shows only active toasts
    Variants {
        model: Quickshell.screens

        delegate: Component {
            PanelWindow {
                required property var modelData
                screen: modelData
                WlrLayershell.namespace: "quickshell:notifications"
                surfaceFormat { opaque: false }

                visible: modelData.name === Shared.Config.monitor && root.toastIds.length > 0

                anchors {
                    top: true
                    right: true
                }

                exclusionMode: ExclusionMode.Ignore
                implicitWidth: 380
                implicitHeight: toastColumn.implicitHeight + 20
                color: "transparent"

                margins {
                    right: Shared.Theme.barWidth + 12
                    top: 8
                }

                ColumnLayout {
                    id: toastColumn
                    anchors.top: parent.top
                    anchors.right: parent.right
                    anchors.topMargin: 10
                    anchors.rightMargin: 10
                    width: 360
                    spacing: 8

                    Repeater {
                        model: server.trackedNotifications

                        Loader {
                            required property var modelData
                            active: root.toastIds.indexOf(modelData.id) >= 0
                            visible: active
                            Layout.fillWidth: true

                            sourceComponent: NotificationPopup {
                                notification: modelData
                            }
                        }
                    }
                }
            }
        }
    }
}
