// The month grid from GNOME's date menu.
//
// Six week rows always, so the grid height never changes as you page through
// months and the panel below it never jumps. Days belonging to the neighboring
// months fill the edges, dimmed. Today wears the accent.
//
// Days become real navigation targets now that Evolution Data Server backs the
// panel. Up to three source-colored markers show whether a date has events.

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

Item {
    id: root

    signal dateActivated(date value)
    signal visibleMonthChanged(int year, int month)

    implicitHeight: body.implicitHeight

    // Cells divide the available width evenly; the height is fixed so the grid
    // stays roughly square regardless of how wide the panel gets.
    readonly property real cellWidth: root.width / 7
    readonly property int cellHeight: 32

    // Hours precision is enough: the only thing that has to change on its own
    // is which cell counts as "today", and that only moves at midnight.
    SystemClock {
        id: clock
        precision: SystemClock.Hours
    }

    readonly property int todayYear: clock.date.getFullYear()
    readonly property int todayMonth: clock.date.getMonth()
    readonly property int todayDay: clock.date.getDate()

    // The month currently on screen. DateMenu calls showToday() every time the
    // panel opens, so it never comes back showing wherever you paged off to.
    property int viewYear: root.todayYear
    property int viewMonth: root.todayMonth
    property date selectedDate: CalendarAgenda.selectedDate

    readonly property bool onCurrentMonth: root.viewYear === root.todayYear && root.viewMonth === root.todayMonth

    function showToday(): void {
        root.viewYear = root.todayYear;
        root.viewMonth = root.todayMonth;
    }

    function stepMonth(delta: int): void {
        // Built through Date rather than by hand so December -> January rolls
        // the year over for us.
        const d = new Date(root.viewYear, root.viewMonth + delta, 1);
        root.viewYear = d.getFullYear();
        root.viewMonth = d.getMonth();
    }

    function activateCell(model: var): void {
        if (!model.current) {
            root.viewYear = model.date.getFullYear();
            root.viewMonth = model.date.getMonth();
        }
        root.dateActivated(model.date);
    }

    onViewYearChanged: root.visibleMonthChanged(root.viewYear, root.viewMonth)
    onViewMonthChanged: root.visibleMonthChanged(root.viewYear, root.viewMonth)

    readonly property var cells: {
        const first = new Date(root.viewYear, root.viewMonth, 1);
        const offset = first.getDay(); // 0 = Sunday, matching the header row

        const out = [];
        for (let i = 0; i < 42; i++) {
            const date = new Date(root.viewYear, root.viewMonth, i - offset + 1);
            out.push({
                date: date,
                day: date.getDate(),
                current: date.getMonth() === root.viewMonth && date.getFullYear() === root.viewYear
            });
        }
        return out;
    }

    Column {
        id: body
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.top: parent.top
        spacing: 6

        // ── Month header ────────────────────────────────────────────────────
        // Both arrows sit on the right so the left slot is free for the "Today"
        // affordance, which only exists while you are looking at another month.
        Item {
            width: parent.width
            height: 30

            Rectangle {
                id: todayPill
                anchors.left: parent.left
                anchors.verticalCenter: parent.verticalCenter
                width: todayLabel.implicitWidth + 18
                height: 24
                radius: Theme.pillRadius
                border.width: 0
                visible: !root.onCurrentMonth
                color: todayMouse.containsMouse ? Theme.alpha(Theme.accent, 0.30) : Theme.alpha(Theme.accent, 0.16)

                Behavior on color {
                    ColorAnimation {
                        duration: todayMouse.containsMouse ? Theme.durFast : Theme.durNormal
                    }
                }

                Text {
                    id: todayLabel
                    anchors.centerIn: parent
                    text: "Today"
                    color: Theme.accent
                    font.family: Theme.fontFamily
                    font.pixelSize: Theme.fontSizeSmall
                    font.weight: Font.Medium
                }

                MouseArea {
                    id: todayMouse
                    anchors.fill: parent
                    hoverEnabled: true
                    cursorShape: Qt.PointingHandCursor
                    onClicked: root.showToday()
                }
            }

            // Centered on the row rather than between the pill and the arrows,
            // so it does not shift sideways when the pill appears.
            Text {
                anchors.centerIn: parent
                text: Qt.formatDateTime(new Date(root.viewYear, root.viewMonth, 1), "MMMM yyyy")
                font.family: Theme.fontFamily
                // The year ticks in place when you page across a boundary.
                font.features: Theme.tabularFigures
                font.pixelSize: Theme.fontSizeLarge
                font.weight: Font.DemiBold
                color: Theme.fg
            }

            Row {
                anchors.right: parent.right
                anchors.verticalCenter: parent.verticalCenter
                spacing: 2

                MonthArrow {
                    glyph: "\u{F0141}"   // md-chevron_left
                    onActivated: root.stepMonth(-1)
                }

                MonthArrow {
                    glyph: "\u{F0142}"   // md-chevron_right
                    onActivated: root.stepMonth(1)
                }
            }
        }

        // ── Weekday header ──────────────────────────────────────────────────
        Row {
            width: parent.width

            Repeater {
                model: ["S", "M", "T", "W", "T", "F", "S"]

                delegate: Text {
                    required property string modelData

                    width: root.cellWidth
                    height: 22
                    text: modelData
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                    font.family: Theme.fontFamily
                    font.pixelSize: Theme.fontSizeSmall
                    font.weight: Font.Medium
                    color: Theme.fgMuted
                }
            }
        }

        // ── Day grid ────────────────────────────────────────────────────────
        Grid {
            width: parent.width
            columns: 7

            Repeater {
                model: root.cells

                delegate: Item {
                    id: cell

                    required property var modelData

                    readonly property bool isToday: cell.modelData.current && cell.modelData.day === root.todayDay && root.onCurrentMonth
                    readonly property bool isSelected: CalendarAgenda.dateKey(cell.modelData.date) === CalendarAgenda.dateKey(root.selectedDate)
                    readonly property var markers: CalendarAgenda.markersForDate(cell.modelData.date).slice(0, 3)

                    width: root.cellWidth
                    height: root.cellHeight

                    Rectangle {
                        anchors.centerIn: parent
                        width: root.cellHeight - 4
                        height: root.cellHeight - 4
                        radius: width / 2
                        border.width: 0
                        visible: cell.isToday || cell.isSelected || cellMouse.containsMouse
                        color: {
                            if (cell.isToday)
                                return Theme.accent;
                            if (cell.isSelected)
                                return Theme.alpha(Theme.accent, 0.20);
                            return Theme.alpha(Theme.fg, 0.08);
                        }

                        Behavior on color {
                            ColorAnimation { duration: Theme.durFast }
                        }
                    }

                    Text {
                        anchors.centerIn: parent
                        text: cell.modelData.day
                        font.family: Theme.fontFamily
                        font.features: Theme.tabularFigures
                        font.pixelSize: Theme.fontSize
                        font.weight: cell.isToday ? Font.DemiBold : Font.Normal

                        color: {
                            if (cell.isToday)
                                return Theme.bgDark;
                            if (cell.isSelected)
                                return Theme.accent;
                            return cell.modelData.current ? Theme.fg : Theme.fgMuted;
                        }
                    }

                    Row {
                        anchors.horizontalCenter: parent.horizontalCenter
                        anchors.bottom: parent.bottom
                        anchors.bottomMargin: 1
                        spacing: 2

                        Repeater {
                            model: cell.markers

                            Rectangle {
                                required property var modelData

                                width: 3
                                height: 3
                                radius: 2
                                border.width: 0
                                color: cell.isToday ? Theme.bgDark : modelData.color
                            }
                        }
                    }

                    MouseArea {
                        id: cellMouse
                        anchors.fill: parent
                        hoverEnabled: true
                        cursorShape: Qt.PointingHandCursor
                        onClicked: root.activateCell(cell.modelData)
                    }
                }
            }
        }
    }

    Component.onCompleted: root.visibleMonthChanged(root.viewYear, root.viewMonth)
}
