pragma Singleton
import Quickshell
import Quickshell.Services.Notifications
import QtQuick

Singleton {
    id: root

    property bool panelOpen:   false
    property int  unreadCount: 0

    property ListModel notifications: ListModel {}
    property var       _refs:         ({}) // maps nid to the live Notification object

    property ListModel toasts: ListModel {}

    // Runs every 100ms while toasts are active, decrementing progress (1.0 to 0.0 over 5s)
    // and removing any toast that has expired
    Timer {
        id:       toastTick
        interval: 100
        repeat:   true
        running:  root.toasts.count > 0

        onTriggered: {
            let i = 0
            while (i < root.toasts.count) {
                const p = root.toasts.get(i).progress - 0.02
                if (p <= 0) {
                    root.toasts.remove(i, 1)
                } else {
                    root.toasts.setProperty(i, "progress", p)
                    i++
                }
            }
        }
    }

    NotificationServer {
        keepOnReload: true

        onNotification: notif => {
            const ts  = Date.now()
            const day = root._dayLabel(ts)

            root.notifications.insert(0, {
                nid:       notif.id,
                appName:   notif.appName  || "Unknown",
                summary:   notif.summary  || "",
                body:      notif.body     || "",
                appIcon:   notif.appIcon  || "",
                urgency:   notif.urgency  || 1,
                timestamp: ts,
                day:       day
            })

            const r = root._refs
            r[notif.id] = notif
            root._refs = r

            if (!root.panelOpen) root.unreadCount++

            root.toasts.insert(0, {
                tid:      notif.id,
                appName:  notif.appName  || "Unknown",
                summary:  notif.summary  || "",
                body:     notif.body     || "",
                appIcon:  notif.appIcon  || "",
                urgency:  notif.urgency  || 1,
                progress: 1.0
            })
        }
    }

    function dismiss(index) {
        if (index < 0 || index >= notifications.count) return
        const entry = notifications.get(index)
        const ref   = _refs[entry.nid]
        if (ref) {
            try { ref.close() } catch (_) {}
            const r = _refs
            delete r[entry.nid]
            _refs = r
        }
        notifications.remove(index, 1)
    }

    function dismissAll() {
        for (let i = 0; i < notifications.count; i++) {
            const ref = _refs[notifications.get(i).nid]
            if (ref) { try { ref.close() } catch (_) {} }
        }
        notifications.clear()
        _refs = {}
        unreadCount = 0
    }

    // Invokes the "default" action on a notification, falling back to the first action
    function invokeDefault(nid) {
        const ref = _refs[nid]
        if (!ref) return
        const actions = ref.actions
        if (!actions || actions.length === 0) return
        for (let i = 0; i < actions.length; i++) {
            if (actions[i].identifier === "default") {
                try { actions[i].invoke() } catch (_) {}
                return
            }
        }
        try { actions[0].invoke() } catch (_) {}
    }

    function dismissToast(tid) {
        for (let i = 0; i < toasts.count; i++) {
            if (toasts.get(i).tid === tid) {
                toasts.remove(i, 1)
                return
            }
        }
    }

    function togglePanel() {
        panelOpen = !panelOpen
        if (panelOpen) unreadCount = 0
    }

    function formatTime(ts) {
        return Qt.formatDateTime(new Date(ts), "hh:mm")
    }

    function _dayLabel(ts) {
        const now       = new Date()
        const date      = new Date(ts)
        const today     = new Date(now.getFullYear(),  now.getMonth(),  now.getDate())
        const yesterday = new Date(today.getTime() - 86400000)
        const day       = new Date(date.getFullYear(), date.getMonth(), date.getDate())

        if (day.getTime() === today.getTime())     return "Today"
        if (day.getTime() === yesterday.getTime()) return "Yesterday"
        return Qt.formatDateTime(date, "dd/MM/yyyy")
    }
}
