// ═══════════════════════════════════════════════════════════════════
//  NeonDateRangePicker — pick a start + end date on one calendar
// ═══════════════════════════════════════════════════════════════════
//
//  Single calendar grid where the user clicks two days to define
//  a range. The first click sets `start-day`; the second sets
//  `end-day`. Clicking a third day resets to a fresh range
//  starting at the new day.
//
//  Months are navigated via ← / → buttons. The "view month"
//  (`view-year` / `view-month`) is independent of the range —
//  flipping the month doesn't lose the picked dates.
//
//  Outputs:
//    start-year, start-month, start-day  → -1 each when unset.
//    end-year,   end-month,   end-day    → -1 each when unset.
//    is-valid: bool                      → true when both ends set
//                                          and start <= end.
//
//  Signals:
//    range-changed → fires after each click that mutates the range.
//
//  The calendar layout reuses the 6×7 grid pattern from
//  NeonDatePicker; the range highlight is computed inline by
//  comparing each cell's (year, month, day) tuple against the
//  ordered start/end pair.
//
// ═══════════════════════════════════════════════════════════════════

import { Theme } from "../theme.slint";

export component NeonDateRangePicker inherits Rectangle {
    // ── View state (independent of the picked range) ─────────────
    in-out property <int> view-year: 2026;
    in-out property <int> view-month: 5;  // 1..12

    // ── Output: picked range ─────────────────────────────────────
    in-out property <int> start-year: -1;
    in-out property <int> start-month: -1;
    in-out property <int> start-day: -1;
    in-out property <int> end-year: -1;
    in-out property <int> end-month: -1;
    in-out property <int> end-day: -1;

    in property <string> label: "";
    in property <bool> enabled: true;

    callback range-changed;

    // ── Derived: month metadata ──────────────────────────────────
    property <int> safe-month: clamp(root.view-month, 1, 12);
    property <int> safe-year: clamp(root.view-year, 1900, 2100);

    property <bool> is-leap:
        mod(root.safe-year, 4) == 0
        && (mod(root.safe-year, 100) != 0 || mod(root.safe-year, 400) == 0);
    property <int> days-in-month:
        root.safe-month == 2 ? (root.is-leap ? 29 : 28)
        : root.safe-month == 4 || root.safe-month == 6
            || root.safe-month == 9 || root.safe-month == 11
        ? 30 : 31;

    property <[string]> month-names: [
        "Ene", "Feb", "Mar", "Abr", "May", "Jun",
        "Jul", "Ago", "Sep", "Oct", "Nov", "Dic",
    ];
    property <[string]> day-headers: ["Do", "Lu", "Ma", "Mi", "Ju", "Vi", "Sa"];

    // ── Zeller-ish first-day-of-month index (0=Sunday) ───────────
    property <int> cal-m: root.safe-month < 3
        ? root.safe-month + 12 : root.safe-month;
    property <int> cal-yr: root.safe-month < 3
        ? root.safe-year - 1 : root.safe-year;
    property <int> first-dow:
        mod(1 + 13 * (root.cal-m + 1) / 5
            + mod(root.cal-yr, 100)
            + mod(root.cal-yr, 100) / 4
            + root.cal-yr / 400
            - 2 * (root.cal-yr / 100)
            + 700,
            7);

    // ── Range comparison helpers ─────────────────────────────────
    /// Pack (y, m, d) into a sortable int. `y * 10000 + m * 100 + d`
    /// works for any year ≥ 0 and never overflows i32 in our range.
    pure function pack(y: int, m: int, d: int) -> int {
        return y * 10000 + m * 100 + d;
    }
    property <int> start-key: root.start-day < 0
        ? -1 : root.pack(root.start-year, root.start-month, root.start-day);
    property <int> end-key: root.end-day < 0
        ? -1 : root.pack(root.end-year, root.end-month, root.end-day);
    property <int> range-min: root.start-key >= 0 && root.end-key >= 0
        ? min(root.start-key, root.end-key) : -1;
    property <int> range-max: root.start-key >= 0 && root.end-key >= 0
        ? max(root.start-key, root.end-key) : -1;

    out property <bool> is-valid:
        root.start-day >= 0 && root.end-day >= 0
        && root.start-key <= root.end-key;

    // ── Click handler — picks start or extends to end ────────────
    function on-day-clicked(d: int) {
        if (!root.enabled) { return; }
        if (root.start-day < 0 || (root.start-day >= 0 && root.end-day >= 0)) {
            // No selection yet OR range fully picked → start fresh.
            root.start-year = root.safe-year;
            root.start-month = root.safe-month;
            root.start-day = d;
            root.end-year = -1;
            root.end-month = -1;
            root.end-day = -1;
        } else {
            // Start is set, end is not → set end. If end < start,
            // swap so the range is always start ≤ end.
            root.end-year = root.safe-year;
            root.end-month = root.safe-month;
            root.end-day = d;
            if (root.pack(root.end-year, root.end-month, root.end-day)
                < root.pack(root.start-year, root.start-month, root.start-day))
            {
                // Swap.
                root.end-year = root.start-year;
                root.end-month = root.start-month;
                root.end-day = root.start-day;
                root.start-year = root.safe-year;
                root.start-month = root.safe-month;
                root.start-day = d;
            }
        }
        root.range-changed();
    }

    function nav-prev() {
        if (root.view-month == 1) {
            root.view-month = 12;
            root.view-year = root.view-year - 1;
        } else {
            root.view-month = root.view-month - 1;
        }
    }
    function nav-next() {
        if (root.view-month == 12) {
            root.view-month = 1;
            root.view-year = root.view-year + 1;
        } else {
            root.view-month = root.view-month + 1;
        }
    }

    background: transparent;

    VerticalLayout {
        spacing: Theme.sp-1;

        if (root.label != ""): Text {
            text: root.label;
            font-size: Theme.font-sm;
            color: root.enabled ? Theme.text-muted : Theme.text-dim;
        }

        Rectangle {
            border-radius: Theme.radius-md;
            border-width: 1px;
            border-color: Theme.border;
            background: root.enabled ? Theme.bg-surface : Theme.bg-elevated;
            opacity: root.enabled ? 1.0 : 0.4;

            VerticalLayout {
                padding: Theme.sp-2;
                spacing: Theme.sp-1;

                // Header — month nav + selection summary
                HorizontalLayout {
                    spacing: Theme.sp-2;
                    alignment: stretch;

                    Rectangle {
                        width: 28px;
                        height: 28px;
                        border-radius: Theme.radius-sm;
                        background: prev-touch.has-hover ? Theme.bg-hover : transparent;
                        Text {
                            text: "‹";
                            font-size: Theme.font-lg;
                            color: Theme.text-primary;
                            horizontal-alignment: center;
                            vertical-alignment: center;
                            width: parent.width;
                            height: parent.height;
                        }
                        prev-touch := TouchArea {
                            clicked => { root.nav-prev(); }
                            enabled: root.enabled;
                            mouse-cursor: pointer;
                            accessible-role: button;
                            accessible-label: "Mes anterior";
                        }
                    }
                    Text {
                        text: root.month-names[root.safe-month - 1] + " " + root.safe-year;
                        font-size: Theme.font-sm;
                        font-weight: 600;
                        color: Theme.text-primary;
                        horizontal-stretch: 1;
                        horizontal-alignment: center;
                        vertical-alignment: center;
                    }
                    Rectangle {
                        width: 28px;
                        height: 28px;
                        border-radius: Theme.radius-sm;
                        background: next-touch.has-hover ? Theme.bg-hover : transparent;
                        Text {
                            text: "›";
                            font-size: Theme.font-lg;
                            color: Theme.text-primary;
                            horizontal-alignment: center;
                            vertical-alignment: center;
                            width: parent.width;
                            height: parent.height;
                        }
                        next-touch := TouchArea {
                            clicked => { root.nav-next(); }
                            enabled: root.enabled;
                            mouse-cursor: pointer;
                            accessible-role: button;
                            accessible-label: "Mes siguiente";
                        }
                    }
                }

                // Day-of-week headers
                HorizontalLayout {
                    spacing: 0;
                    for dh in root.day-headers: Rectangle {
                        horizontal-stretch: 1;
                        Text {
                            text: dh;
                            font-size: Theme.font-xs;
                            color: Theme.text-dim;
                            horizontal-alignment: center;
                            vertical-alignment: center;
                        }
                    }
                }

                // 6×7 calendar grid
                for row in [1, 2, 3, 4, 5, 6]: HorizontalLayout {
                    spacing: 0;
                    for col in [0, 1, 2, 3, 4, 5, 6]: Rectangle {
                        property <int> day-num: (row - 1) * 7 + col + 1 - root.first-dow;
                        property <bool> in-month: day-num >= 1 && day-num <= root.days-in-month;
                        property <int> cell-key: day-num >= 1
                            ? root.pack(root.safe-year, root.safe-month, day-num)
                            : -1;
                        property <bool> is-start: cell-key == root.start-key;
                        property <bool> is-end:   cell-key == root.end-key;
                        property <bool> in-range: cell-key >= root.range-min
                            && cell-key <= root.range-max && root.range-min >= 0;
                        horizontal-stretch: 1;
                        min-height: 28px;
                        // Range highlight: solid for endpoints, soft for in-between.
                        background:
                            !in-month ? transparent
                            : is-start || is-end
                                ? (root.enabled ? Theme.neon-cyan : Theme.text-dim)
                                : in-range ? Theme.glow-cyan
                                : (cell-touch.has-hover ? Theme.bg-hover : transparent);
                        border-radius: Theme.radius-sm;
                        Text {
                            text: in-month ? day-num : "";
                            font-size: Theme.font-xs;
                            font-weight: is-start || is-end ? 700 : 400;
                            color: !in-month ? Theme.text-dim
                                : (is-start || is-end) ? Theme.text-inverse
                                : Theme.text-primary;
                            horizontal-alignment: center;
                            vertical-alignment: center;
                        }
                        cell-touch := TouchArea {
                            clicked => { if (in-month) { root.on-day-clicked(day-num); } }
                            enabled: root.enabled && in-month;
                            mouse-cursor: in-month ? MouseCursor.pointer : MouseCursor.default;
                        }
                    }
                }

                // Selection summary
                if (root.start-day >= 0 || root.end-day >= 0): Rectangle {
                    height: 1px;
                    background: Theme.border;
                }
                if (root.start-day >= 0 || root.end-day >= 0): HorizontalLayout {
                    spacing: Theme.sp-2;
                    padding-top: Theme.sp-1;
                    Text {
                        text: root.start-day >= 0
                            ? (root.start-day + " " + root.month-names[root.start-month - 1] + " " + root.start-year)
                            : "—";
                        font-size: Theme.font-xs;
                        color: Theme.neon-cyan;
                        horizontal-stretch: 1;
                    }
                    Text {
                        text: "→";
                        font-size: Theme.font-xs;
                        color: Theme.text-dim;
                    }
                    Text {
                        text: root.end-day >= 0
                            ? (root.end-day + " " + root.month-names[root.end-month - 1] + " " + root.end-year)
                            : "elegí fin";
                        font-size: Theme.font-xs;
                        color: root.end-day >= 0 ? Theme.neon-cyan : Theme.text-dim;
                        horizontal-stretch: 1;
                        horizontal-alignment: right;
                    }
                }
            }
        }
    }
}
