import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell
import Quickshell.Wayland
import Quickshell.Services.Notifications

import "../../config"       as Cfg
import "../../notifications" as Notif

Rectangle {
    id: root

    property real panelRadius: Cfg.Config.radius / 2
    property int  borderWidth: Cfg.Config.panelBorderWidth
    property bool isTop:        true
    property var  targetScreen: null
    property int  barHeight:    Cfg.Config.barHeight
    property int  barMargin:    Cfg.Config.margin
    readonly property var t: Cfg.Config.theme

    property int  unreadCount:  0
    property bool doNotDisturb: false
    property bool historyOpen:  historyPopup.popupOpen

    width:  35
    height: 40
    radius: panelRadius
    clip:   true

    color:        hoverHandler.hovered ? t.notifBgHover : t.notifBg
    border.color: root.doNotDisturb
                      ? t.notifDnd
                      : ((hoverHandler.hovered || historyOpen) ? t.notifBorderActive : t.notifBorder)
    border.width: borderWidth

    Behavior on color        { ColorAnimation  { duration: 150 } }
    Behavior on border.color { ColorAnimation  { duration: 150 } }
    Behavior on width        { NumberAnimation { duration: 200; easing.type: Easing.OutCubic } }

    HoverHandler { id: hoverHandler; cursorShape: Qt.PointingHandCursor; onHoveredChanged: if (hovered) bellRingAnim.start() }
    TapHandler {
        onTapped: {
            if (historyPopup.popupOpen) {
                historyPopup.close()
            } else {
                root.unreadCount = 0
                historyPopup.open()
            }
        }
    }

    Item {
        anchors.centerIn: parent
        width:  Cfg.Config.notifIconSize + 10
        height: Cfg.Config.notifIconSize + 10

        Text {
            id: bellIcon
            anchors.centerIn: parent
            text:           root.doNotDisturb ? "󰂛" : "󰂚"
            color:          root.doNotDisturb
                                ? t.notifDnd
                                : (root.unreadCount > 0 ? t.notifIconActive : t.notifIcon)
            font.pixelSize: Cfg.Config.notifIconSize
            Behavior on color { ColorAnimation { duration: 150 } }

            rotation:        0
            transformOrigin: Item.Top

            SequentialAnimation {
                id: bellRingAnim
                NumberAnimation { target: bellIcon; property: "rotation"; to: -18; duration: 80;  easing.type: Easing.OutQuad }
                NumberAnimation { target: bellIcon; property: "rotation"; to:  20; duration: 100; easing.type: Easing.OutQuad }
                NumberAnimation { target: bellIcon; property: "rotation"; to: -10; duration: 80;  easing.type: Easing.OutQuad }
                NumberAnimation { target: bellIcon; property: "rotation"; to:  10; duration: 70;  easing.type: Easing.OutQuad }
                NumberAnimation { target: bellIcon; property: "rotation"; to:   0; duration: 80;  easing.type: Easing.OutCubic }
            }
        }

        Rectangle {
            visible:       root.unreadCount > 0
            anchors.top:   parent.top
            anchors.right: parent.right
            width:         Math.max(14, badgeLabel.implicitWidth + 6)
            height:        14
            radius:        7
            color:         t.notifBadgeBg

            Behavior on width { NumberAnimation { duration: 150; easing.type: Easing.OutCubic } }

            Text {
                id: badgeLabel
                anchors.centerIn: parent
                text:           root.unreadCount > 99 ? "99+" : root.unreadCount.toString()
                color:          t.notifBadgeText
                font.pixelSize: 8
                font.bold:      true
            }
        }
    }

    ListModel { id: notifHistory }
    ListModel { id: activeToasts }

    function removeToast(toastId) {
        for (var i = 0; i < activeToasts.count; i++) {
            if (activeToasts.get(i).toastId === toastId) {
                activeToasts.remove(i)
                return
            }
        }
    }

    function urgencyColor(urgency) {
        if (urgency === NotificationUrgency.Critical) return t.notifUrgencyCritical
        if (urgency === NotificationUrgency.Normal)   return t.notifUrgencyNormal
        return t.notifUrgencyLow
    }

    function urgencyIcon(urgency) {
        if (urgency === NotificationUrgency.Critical) return "󰀪"
        if (urgency === NotificationUrgency.Normal)   return "󰋼"
        return "󰵙"
    }

    NotificationServer {
        id: notifServer
        keepOnReload: false
        actionIconsSupported: true
        bodyMarkupSupported:  true
        bodySupported:        true
        persistenceSupported: true
        imageSupported:       true

        onNotification: function(notif) {
            notif.tracked = true
            bellRingAnim.start()
            var timeStr = new Date().toLocaleTimeString(Qt.locale(), "HH:mm")
            var toastId = notif.id + "_" + Date.now()

            notifHistory.insert(0, {
                nid:     notif.id,
                appName: notif.appName  || "Unknown",
                summary: notif.summary || "",
                body:    notif.body    || "",
                urgency: notif.urgency,
                timeStr: timeStr
            })
            while (notifHistory.count > Cfg.Config.notificationHistorySize)
                notifHistory.remove(notifHistory.count - 1)

            var cfgTimeout = notif.urgency === NotificationUrgency.Critical
                ? Cfg.Config.notifTimeoutCritical
                : (notif.urgency === NotificationUrgency.Low
                    ? Cfg.Config.notifTimeoutLow
                    : Cfg.Config.notifTimeoutNormal)

            var finalTimeout = (notif.expireTimeout > 0) ? notif.expireTimeout : cfgTimeout

            var toastEntry = {
                toastId: toastId,
                nid:     notif.id,
                appName: notif.appName  || "Unknown",
                summary: notif.summary || "",
                body:    notif.body    || "",
                urgency: notif.urgency,
                timeStr: timeStr,
                timeout: finalTimeout
            }
            if (!root.doNotDisturb) {
                if (toastLayer.atBottom) activeToasts.append(toastEntry)
                else activeToasts.insert(0, toastEntry)
                if (!root.historyOpen) root.unreadCount++
            }
        }
    }

    PanelWindow {
        id: toastLayer
        screen:  root.targetScreen
        visible: activeToasts.count > 0
        color:   "transparent"

        readonly property string pos:      Cfg.Config.notificationPosition
        readonly property bool   atRight:  pos === "topright" || pos === "bottomright"
        readonly property bool   atBottom: pos === "bottomleft" || pos === "bottomright"

        anchors { top: true; bottom: true; right: atRight; left: !atRight }
        implicitWidth: 350 + root.barMargin + 4

        WlrLayershell.layer:         WlrLayer.Overlay
        WlrLayershell.namespace:     "main-shell-notifications-toasts"
        WlrLayershell.exclusiveZone: -1
        WlrLayershell.keyboardFocus: WlrKeyboardFocus.None

        mask: Region { item: toastCol }

        readonly property bool shareEdge: (root.isTop && !atBottom) || (!root.isTop && atBottom)
        readonly property int  edgeGap:   shareEdge ? root.barMargin + root.barHeight + 10 : root.barMargin + 10

        Column {
            id: toastCol
            x:       !toastLayer.atRight  ? 4 : 4
            y:       !toastLayer.atBottom ? toastLayer.edgeGap : parent.height - toastLayer.edgeGap - toastCol.height
            spacing: 8
            width:   350

            Repeater {
                model: activeToasts
                Notif.NotificationCard {
                    width:        toastCol.width
                    toastId:      model.toastId
                    appName:      model.appName
                    summary:      model.summary
                    body:         model.body
                    urgency:      model.urgency
                    timeStr:      model.timeStr
                    timeout:      model.timeout
                    t:            root.t
                    urgencyColor: root.urgencyColor
                    urgencyIcon:  root.urgencyIcon
                    onDismissed:  (id) => root.removeToast(id)
                }
            }
        }
    }

    PanelWindow {
        id: historyPopup
        screen:  root.targetScreen
        visible: false
        color:   "transparent"

        property bool popupOpen: false

        function open()  { hideTimer.stop(); visible = true; popupOpen = true }
        function close() { popupOpen = false; hideTimer.restart() }

        Timer {
            id: hideTimer
            interval: Cfg.Config.popupAnimDuration + 70
            onTriggered: historyPopup.visible = false
        }

        anchors { top: true; bottom: true; left: true; right: true }
        WlrLayershell.layer:         WlrLayer.Top
        WlrLayershell.namespace:     "main-shell-notifications-history"
        WlrLayershell.exclusiveZone: -1
        mask: popupOpen ? null : _noInput
        Region { id: _noInput }

        MouseArea {
            anchors.fill: parent
            onClicked: historyPopup.close()
        }

        Item {
            id: histClipContainer
            readonly property int cardW:     340
            readonly property int screenPad: root.barMargin + 10

            x: {
                var cx = root.mapToItem(null, 0, 0).x + root.width / 2
                return Math.max(screenPad, Math.min(cx - cardW / 2, parent.width - cardW - screenPad))
            }
            width: cardW

            anchors.top:          root.isTop ? parent.top    : undefined
            anchors.bottom:       root.isTop ? undefined     : parent.bottom
            anchors.topMargin:    root.isTop ? (root.barHeight + 10) : 0
            anchors.bottomMargin: root.isTop ? 0 : (root.barHeight + 10)
            height: parent.height - root.barHeight - 10

            clip: true

            Rectangle {
                id: historyCard
                width:  parent.width
                height: Math.min(histHeader.implicitHeight + 56 + (notifHistory.count > 0 ? notifHistory.count * 76 : 90), 520)

                anchors.top:    root.isTop ? parent.top    : undefined
                anchors.bottom: root.isTop ? undefined     : parent.bottom

                transform: Translate {
                    y: historyPopup.popupOpen ? 0 : (root.isTop ? -historyCard.height : historyCard.height)
                    
                    Behavior on y { 
                        NumberAnimation { 
                            duration: Cfg.Config.popupAnimDuration; 
                            easing.type: Easing.OutExpo 
                        }
                        enabled: historyPopup.visible
                    }
                }

                opacity: historyPopup.popupOpen ? 1.0 : 0.0
                Behavior on opacity { NumberAnimation { duration: 200 } }

                color:        t.notifHistoryBg
                radius:       Cfg.Config.popupRadius
                border.color: t.notifHistoryBorder
                border.width: Cfg.Config.popupBorderWidth
                layer.enabled: true

                MouseArea { anchors.fill: parent; propagateComposedEvents: false }

                RowLayout {
                    id: histHeader
                    anchors { left: parent.left; right: parent.right; top: parent.top }
                    anchors.topMargin: 20; anchors.leftMargin: 20; anchors.rightMargin: 20
                    spacing: 10

                    Text { text: "󰂚"; color: t.notifToastAppName; font.pixelSize: 18; Layout.alignment: Qt.AlignVCenter }
                    Text {
                        text: "Notifications"; color: t.notifToastAppName; font.pixelSize: 15; font.bold: true
                        Layout.fillWidth: true; Layout.alignment: Qt.AlignVCenter
                    }

                    // ── Do Not Disturb toggle ─────────────────────────────
                    Rectangle {
                        Layout.alignment: Qt.AlignVCenter
                        width:  dndRow.implicitWidth + 16
                        height: 24
                        radius: 12
                        color:  root.doNotDisturb
                                    ? Qt.rgba(t.notifDnd.r, t.notifDnd.g, t.notifDnd.b, 0.18)
                                    : (dndHover.hovered ? t.notifHistoryHover : "transparent")
                        border.color: root.doNotDisturb ? t.notifDnd : "transparent"
                        border.width: Cfg.Config.popupBorderWidth
                        Behavior on color        { ColorAnimation { duration: 150 } }
                        Behavior on border.color { ColorAnimation { duration: 150 } }

                        Row {
                            id: dndRow
                            anchors.centerIn: parent
                            spacing: 4
                            Text {
                                text:           "󰂛"
                                color:          root.doNotDisturb ? t.notifDnd : t.notifToastDim
                                font.pixelSize: 12
                                anchors.verticalCenter: parent.verticalCenter
                                Behavior on color { ColorAnimation { duration: 150 } }
                            }
                            Text {
                                text:           root.doNotDisturb ? "On" : "Off"
                                color:          root.doNotDisturb ? t.notifDnd : t.notifToastDim
                                font.pixelSize: 11
                                font.bold:      root.doNotDisturb
                                anchors.verticalCenter: parent.verticalCenter
                                Behavior on color { ColorAnimation { duration: 150 } }
                            }
                        }

                        HoverHandler { id: dndHover; cursorShape: Qt.PointingHandCursor }
                        TapHandler   { onTapped: root.doNotDisturb = !root.doNotDisturb }
                    }

                    Rectangle {
                        visible:          notifHistory.count > 0
                        Layout.alignment: Qt.AlignVCenter
                        width:            clearText.implicitWidth + 16
                        height:           24
                        radius:           12
                        color:            clearHover.hovered ? t.notifHistoryHover : "transparent"
                        Behavior on color { ColorAnimation { duration: 150 } }

                        Text { id: clearText; anchors.centerIn: parent; text: "Clear all"; color: t.notifToastDim; font.pixelSize: 11 }
                        HoverHandler { id: clearHover; cursorShape: Qt.PointingHandCursor }
                        TapHandler   { onTapped: clearAllAnim.start() }
                    }
                }

                Rectangle {
                    id: histDivider
                    anchors { left: parent.left; right: parent.right; top: histHeader.bottom }
                    anchors.topMargin: 12; height: 1; color: t.notifSeparator
                }

                SequentialAnimation {
                    id: clearAllAnim
                    ParallelAnimation {
                        NumberAnimation {
                            target: histCol; property: "opacity"
                            to: 0; duration: 220; easing.type: Easing.OutCubic
                        }
                        NumberAnimation {
                            target: clearShift; property: "y"
                            to: -16; duration: 220; easing.type: Easing.OutCubic
                        }
                    }
                    ScriptAction {
                        script: { notifHistory.clear(); root.unreadCount = 0 }
                    }
                    ParallelAnimation {
                        NumberAnimation { target: histCol;    property: "opacity"; to: 1; duration: 0 }
                        NumberAnimation { target: clearShift; property: "y";       to: 0; duration: 0 }
                    }
                }

                Flickable {
                    id: histFlick
                    anchors { left: parent.left; right: parent.right; top: histDivider.bottom; bottom: parent.bottom }
                    anchors.leftMargin: 2; anchors.rightMargin: 8
                    anchors.topMargin: 6; anchors.bottomMargin: 8; clip: true
                    contentHeight: histCol.implicitHeight
                    flickableDirection: Flickable.VerticalFlick
                    ScrollBar.vertical: ScrollBar { policy: ScrollBar.AsNeeded }

                    Column {
                        id: histCol
                        opacity: 1
                        transform: Translate { id: clearShift; y: 0 }
                        width: histFlick.width; spacing: 2; topPadding: 4; bottomPadding: 4; leftPadding: 2; rightPadding: 8

                        Item {
                            width: histCol.width - 16; height: 90; visible: notifHistory.count === 0
                            ColumnLayout {
                                anchors.centerIn: parent; spacing: 8
                                Text { text: "󰂚"; color: t.notifHistoryEmpty; font.pixelSize: 30; Layout.alignment: Qt.AlignHCenter }
                                Text { text: "No notifications"; color: t.notifHistoryEmpty; font.pixelSize: 12; Layout.alignment: Qt.AlignHCenter }
                            }
                        }

                        Repeater {
                            model: notifHistory
                            Notif.HistoryCard {
                                width:       histCol.width - 10; x: 2; itemIndex: index
                                appName:     model.appName; summary: model.summary; body: model.body; urgency: model.urgency; timeStr: model.timeStr
                                t:           root.t; urgencyColor: root.urgencyColor; urgencyIcon: root.urgencyIcon
                                onDismissed: (idx) => notifHistory.remove(idx)
                            }
                        }
                    }
                }
            }
        }
    }
}

