// The banner stack: newest at the top, tucked under the bar on the right.
//
// The window is exactly as wide and tall as the stack, so everything outside
// it stays clickable; the mask trims it further to the cards themselves.

import QtQuick
import Quickshell
import Quickshell.Wayland
import qs.config
import qs.services

PanelWindow {
    id: root

    visible: !Notifs.doNotDisturb && Notifs.popups.length > 0
    color: "transparent"

    anchors.top: true
    anchors.right: true
    // The gap ALONE, not the bar height plus the gap. exclusiveZone 0 means
    // "reserve nothing, but respect what others reserved", so this surface
    // already begins below the bar's zone -- adding the bar height here counted
    // it twice and left the surface floating 48px under the bar instead of 12.
    margins.top: Theme.barGap * 2
    margins.right: Theme.barSideMargin
    exclusiveZone: 0

    implicitWidth: 400
    implicitHeight: Math.max(1, stack.implicitHeight)

    WlrLayershell.namespace: "qs-notifications"
    WlrLayershell.layer: WlrLayer.Overlay

    // Normally inert so banners never steal a keystroke. An open inline reply
    // is the one case where the surface has to be typeable.
    WlrLayershell.keyboardFocus: root.replyFocused ? WlrKeyboardFocus.OnDemand : WlrKeyboardFocus.None

    property bool replyFocused: false

    mask: Region {
        item: stack
    }

    Column {
        id: stack
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.right: parent.right
        spacing: Theme.itemSpacing

        Repeater {
            // Notifs.popups.slice() is a fresh array on every change (a new
            // arrival, a dismissal, a sibling toast timing out). Handing that
            // straight to Repeater would reset the model and rebuild every
            // delegate each time, blowing away whichever toast has a reply
            // field mid-typing. ScriptModel diffs by object identity
            // (Notification instances are unique QObjects), so only genuinely
            // added/removed notifications add/remove delegates — unrelated
            // toasts, and their slide-in animations, are untouched.
            model: ScriptModel {
                values: Notifs.popups.slice(0, Settings.maxVisibleToasts)
            }

            Toast {
                required property var modelData

                width: stack.width
                notification: modelData
                onReplyFocusChanged: focused => root.replyFocused = focused
            }
        }
    }
}
