/**
 * Themis Time Picker — DaisyUI time selection widget.
 *
 * Activates on inputs with class:
 *   - "themis-time-picker"      → time only
 *   - "themis-datetime-picker"  → date + time (date handled by date-picker.js)
 *
 * Reads user preferences from body data attributes:
 *   data-user-time-format  — "24-hour" or "12-hour"
 *
 * Internal value uses HH:MM (24-hour) for Django compatibility.
 * Display value respects the user's 12/24-hour preference.
 */
(function () {
    "use strict";

    // ── Preferences ──────────────────────────────────────────────────
    var body = document.body;
    var timeFormat = body.getAttribute("data-user-time-format") || "24-hour";
    var is12Hour = timeFormat === "12-hour";

    // ── Format helpers ───────────────────────────────────────────────

    function zeroPad(n) {
        return n < 10 ? "0" + n : "" + n;
    }

    /** Format hour/minute to display string. */
    function formatTime(hour, minute) {
        if (is12Hour) {
            var period = hour >= 12 ? "PM" : "AM";
            var h12 = hour % 12;
            if (h12 === 0) h12 = 12;
            return h12 + ":" + zeroPad(minute) + " " + period;
        }
        return zeroPad(hour) + ":" + zeroPad(minute);
    }

    /** Format to 24-hour HH:MM for internal value. */
    function formatTime24(hour, minute) {
        return zeroPad(hour) + ":" + zeroPad(minute);
    }

    /** Parse a time string (12-hour or 24-hour) → { hour, minute } or null. */
    function parseTime(str) {
        if (!str) return null;
        str = str.trim();

        // Try 12-hour: "3:30 PM" or "3:30PM"
        var match12 = str.match(/^(\d{1,2}):(\d{2})\s*(AM|PM)$/i);
        if (match12) {
            var h = +match12[1];
            var m = +match12[2];
            var period = match12[3].toUpperCase();
            if (period === "PM" && h !== 12) h += 12;
            if (period === "AM" && h === 12) h = 0;
            if (h >= 0 && h <= 23 && m >= 0 && m <= 59) {
                return { hour: h, minute: m };
            }
        }

        // Try 24-hour: "15:30"
        var match24 = str.match(/^(\d{1,2}):(\d{2})$/);
        if (match24) {
            var h24 = +match24[1];
            var m24 = +match24[2];
            if (h24 >= 0 && h24 <= 23 && m24 >= 0 && m24 <= 59) {
                return { hour: h24, minute: m24 };
            }
        }

        return null;
    }

    // ── Popup builder ────────────────────────────────────────────────

    function createTimePopup(input) {
        var popup = document.createElement("div");
        popup.className = "themis-picker-popup card bg-base-200 shadow-xl";
        popup.style.position = "absolute";
        popup.style.zIndex = "9999";
        popup.style.minWidth = "auto";

        // Parse existing value
        var existingTime = null;
        var inputVal = input.value || "";

        // For datetime inputs, extract the time part after the space
        if (input.classList.contains("themis-datetime-picker")) {
            var spaceIdx = inputVal.indexOf(" ");
            if (spaceIdx > -1) {
                existingTime = parseTime(inputVal.substring(spaceIdx + 1));
            }
        } else {
            existingTime = parseTime(inputVal);
        }

        var currentHour = existingTime ? existingTime.hour : 12;
        var currentMinute = existingTime ? existingTime.minute : 0;
        var currentPeriod = currentHour >= 12 ? "PM" : "AM";

        function applyValue() {
            var displayStr = formatTime(currentHour, currentMinute);
            if (input.classList.contains("themis-datetime-picker")) {
                // Replace only the time portion, keeping the date
                var spIdx = input.value ? input.value.indexOf(" ") : -1;
                var datePart = "";
                if (spIdx > -1) {
                    datePart = input.value.substring(0, spIdx);
                } else if (input.value) {
                    datePart = input.value;
                }
                input.value = datePart ? datePart + " " + displayStr : displayStr;
            } else {
                input.value = displayStr;
            }
            input.dispatchEvent(new Event("change", { bubbles: true }));
        }

        function render() {
            popup.innerHTML = "";

            var container = document.createElement("div");
            container.className = "flex flex-col items-center gap-3 p-1";

            // ── Time display ──
            var displayRow = document.createElement("div");
            displayRow.className = "text-2xl font-mono font-bold";
            displayRow.textContent = formatTime(currentHour, currentMinute);
            container.appendChild(displayRow);

            // ── Controls row ──
            var controlsRow = document.createElement("div");
            controlsRow.className = "flex items-center gap-2";

            // Hour column
            var hourCol = document.createElement("div");
            hourCol.className = "flex flex-col items-center gap-1";

            var hourUpBtn = document.createElement("button");
            hourUpBtn.type = "button";
            hourUpBtn.className = "btn btn-ghost btn-xs btn-square";
            hourUpBtn.innerHTML = "&#9650;";
            hourUpBtn.title = "Hour up";
            hourUpBtn.addEventListener("click", function (e) {
                e.preventDefault();
                e.stopPropagation();
                if (is12Hour) {
                    // In 12-hour mode, cycle within AM/PM
                    var h12 = currentHour % 12;
                    h12 = (h12 + 1) % 12;
                    currentHour = currentPeriod === "PM" ? (h12 === 0 ? 12 : h12 + 12) : h12;
                    if (currentHour === 24) currentHour = 12;
                } else {
                    currentHour = (currentHour + 1) % 24;
                }
                currentPeriod = currentHour >= 12 ? "PM" : "AM";
                render();
            });

            var hourDownBtn = document.createElement("button");
            hourDownBtn.type = "button";
            hourDownBtn.className = "btn btn-ghost btn-xs btn-square";
            hourDownBtn.innerHTML = "&#9660;";
            hourDownBtn.title = "Hour down";
            hourDownBtn.addEventListener("click", function (e) {
                e.preventDefault();
                e.stopPropagation();
                if (is12Hour) {
                    var h12 = currentHour % 12;
                    h12 = (h12 - 1 + 12) % 12;
                    currentHour = currentPeriod === "PM" ? (h12 === 0 ? 12 : h12 + 12) : h12;
                    if (currentHour === 24) currentHour = 12;
                } else {
                    currentHour = (currentHour - 1 + 24) % 24;
                }
                currentPeriod = currentHour >= 12 ? "PM" : "AM";
                render();
            });

            var hourDisplay = document.createElement("input");
            hourDisplay.type = "text";
            hourDisplay.className = "input input-bordered input-sm w-14 text-center font-mono";
            hourDisplay.readOnly = true;
            if (is12Hour) {
                var dh = currentHour % 12;
                if (dh === 0) dh = 12;
                hourDisplay.value = zeroPad(dh);
            } else {
                hourDisplay.value = zeroPad(currentHour);
            }

            hourCol.appendChild(hourUpBtn);
            hourCol.appendChild(hourDisplay);
            hourCol.appendChild(hourDownBtn);
            controlsRow.appendChild(hourCol);

            // Separator
            var sep = document.createElement("span");
            sep.className = "text-xl font-bold";
            sep.textContent = ":";
            controlsRow.appendChild(sep);

            // Minute column
            var minuteCol = document.createElement("div");
            minuteCol.className = "flex flex-col items-center gap-1";

            var minUpBtn = document.createElement("button");
            minUpBtn.type = "button";
            minUpBtn.className = "btn btn-ghost btn-xs btn-square";
            minUpBtn.innerHTML = "&#9650;";
            minUpBtn.title = "Minute up";
            minUpBtn.addEventListener("click", function (e) {
                e.preventDefault();
                e.stopPropagation();
                currentMinute = (currentMinute + 1) % 60;
                render();
            });

            var minDownBtn = document.createElement("button");
            minDownBtn.type = "button";
            minDownBtn.className = "btn btn-ghost btn-xs btn-square";
            minDownBtn.innerHTML = "&#9660;";
            minDownBtn.title = "Minute down";
            minDownBtn.addEventListener("click", function (e) {
                e.preventDefault();
                e.stopPropagation();
                currentMinute = (currentMinute - 1 + 60) % 60;
                render();
            });

            var minDisplay = document.createElement("input");
            minDisplay.type = "text";
            minDisplay.className = "input input-bordered input-sm w-14 text-center font-mono";
            minDisplay.readOnly = true;
            minDisplay.value = zeroPad(currentMinute);

            minuteCol.appendChild(minUpBtn);
            minuteCol.appendChild(minDisplay);
            minuteCol.appendChild(minDownBtn);
            controlsRow.appendChild(minuteCol);

            // AM/PM toggle (12-hour only)
            if (is12Hour) {
                var periodCol = document.createElement("div");
                periodCol.className = "flex flex-col items-center gap-1";

                var periodUpBtn = document.createElement("button");
                periodUpBtn.type = "button";
                periodUpBtn.className = "btn btn-ghost btn-xs btn-square";
                periodUpBtn.innerHTML = "&#9650;";
                periodUpBtn.title = "Toggle AM/PM";
                periodUpBtn.addEventListener("click", function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    togglePeriod();
                    render();
                });

                var periodDownBtn = document.createElement("button");
                periodDownBtn.type = "button";
                periodDownBtn.className = "btn btn-ghost btn-xs btn-square";
                periodDownBtn.innerHTML = "&#9660;";
                periodDownBtn.title = "Toggle AM/PM";
                periodDownBtn.addEventListener("click", function (e) {
                    e.preventDefault();
                    e.stopPropagation();
                    togglePeriod();
                    render();
                });

                var periodDisplay = document.createElement("div");
                periodDisplay.className = "btn btn-sm btn-outline font-mono w-14";
                periodDisplay.textContent = currentPeriod;

                periodCol.appendChild(periodUpBtn);
                periodCol.appendChild(periodDisplay);
                periodCol.appendChild(periodDownBtn);
                controlsRow.appendChild(periodCol);
            }

            container.appendChild(controlsRow);

            // ── Quick-select minute buttons ──
            var quickRow = document.createElement("div");
            quickRow.className = "flex gap-1 flex-wrap justify-center";
            var quickMinutes = [0, 15, 30, 45];
            for (var qi = 0; qi < quickMinutes.length; qi++) {
                (function (qm) {
                    var qBtn = document.createElement("button");
                    qBtn.type = "button";
                    qBtn.className = "btn btn-ghost btn-xs";
                    if (currentMinute === qm) {
                        qBtn.classList.remove("btn-ghost");
                        qBtn.classList.add("btn-primary");
                    }
                    qBtn.textContent = ":" + zeroPad(qm);
                    qBtn.addEventListener("click", function (e) {
                        e.preventDefault();
                        e.stopPropagation();
                        currentMinute = qm;
                        render();
                    });
                    quickRow.appendChild(qBtn);
                })(quickMinutes[qi]);
            }
            container.appendChild(quickRow);

            // ── Action buttons ──
            var actionRow = document.createElement("div");
            actionRow.className = "flex gap-2 mt-1";

            var okBtn = document.createElement("button");
            okBtn.type = "button";
            okBtn.className = "btn btn-primary btn-sm";
            okBtn.textContent = "OK";
            okBtn.addEventListener("click", function (e) {
                e.preventDefault();
                e.stopPropagation();
                applyValue();
                closePopup();
            });

            var nowBtn = document.createElement("button");
            nowBtn.type = "button";
            nowBtn.className = "btn btn-ghost btn-sm";
            nowBtn.textContent = "Now";
            nowBtn.addEventListener("click", function (e) {
                e.preventDefault();
                e.stopPropagation();
                var now = new Date();
                currentHour = now.getHours();
                currentMinute = now.getMinutes();
                currentPeriod = currentHour >= 12 ? "PM" : "AM";
                applyValue();
                closePopup();
            });

            var clearBtn = document.createElement("button");
            clearBtn.type = "button";
            clearBtn.className = "btn btn-ghost btn-sm";
            clearBtn.textContent = "Clear";
            clearBtn.addEventListener("click", function (e) {
                e.preventDefault();
                e.stopPropagation();
                if (input.classList.contains("themis-datetime-picker")) {
                    // Only clear the time portion
                    var spIdx = input.value ? input.value.indexOf(" ") : -1;
                    if (spIdx > -1) {
                        input.value = input.value.substring(0, spIdx);
                    }
                } else {
                    input.value = "";
                }
                input.dispatchEvent(new Event("change", { bubbles: true }));
                closePopup();
            });

            actionRow.appendChild(okBtn);
            actionRow.appendChild(nowBtn);
            actionRow.appendChild(clearBtn);
            container.appendChild(actionRow);

            popup.appendChild(container);
        }

        function togglePeriod() {
            if (currentPeriod === "AM") {
                currentHour += 12;
                if (currentHour >= 24) currentHour -= 24;
                currentPeriod = "PM";
            } else {
                currentHour -= 12;
                if (currentHour < 0) currentHour += 24;
                currentPeriod = "AM";
            }
        }

        function closePopup() {
            if (popup.parentNode) {
                popup.parentNode.removeChild(popup);
            }
            document.removeEventListener("click", onDocumentClick, true);
            document.removeEventListener("keydown", onEscape, true);
        }

        function onDocumentClick(e) {
            if (!popup.contains(e.target) && e.target !== input) {
                closePopup();
            }
        }

        function onEscape(e) {
            if (e.key === "Escape") {
                closePopup();
            }
        }

        render();

        // Position relative to input
        var wrapper = input.parentNode;
        if (getComputedStyle(wrapper).position === "static") {
            wrapper.style.position = "relative";
        }
        wrapper.appendChild(popup);

        setTimeout(function () {
            document.addEventListener("click", onDocumentClick, true);
            document.addEventListener("keydown", onEscape, true);
        }, 0);

        return { popup: popup, close: closePopup };
    }

    // ── Attach to inputs ─────────────────────────────────────────────

    function attachTimePicker(input) {
        var activePopup = null;

        // Set placeholder
        if (!input.placeholder) {
            input.placeholder = is12Hour ? "HH:MM AM/PM" : "HH:MM";
        }

        // For standalone time inputs, make read-only
        if (!input.classList.contains("themis-datetime-picker")) {
            input.setAttribute("readonly", "readonly");
            input.style.cursor = "pointer";
        }

        // Format existing 24-hour value to display format on load
        if (input.value && !input.classList.contains("themis-datetime-picker")) {
            var parsed = parseTime(input.value);
            if (parsed) {
                input.value = formatTime(parsed.hour, parsed.minute);
            }
        }

        input.addEventListener("click", function (e) {
            // For datetime inputs, only open time picker on a dedicated icon/action
            if (input.classList.contains("themis-datetime-picker")) {
                return; // date-picker.js handles the click
            }
            e.preventDefault();
            if (activePopup) {
                activePopup.close();
                activePopup = null;
                return;
            }
            activePopup = createTimePopup(input);
        });

        if (!input.classList.contains("themis-datetime-picker")) {
            input.addEventListener("focus", function () {
                if (!activePopup) {
                    activePopup = createTimePopup(input);
                }
            });
        }
    }

    // ── Init ─────────────────────────────────────────────────────────

    document.querySelectorAll(".themis-time-picker").forEach(function (el) {
        attachTimePicker(el);
    });

    // For datetime pickers, add a clock icon button next to the input
    document.querySelectorAll(".themis-datetime-picker").forEach(function (input) {
        var wrapper = input.parentNode;

        // Create a clock button for the time portion
        var clockBtn = document.createElement("button");
        clockBtn.type = "button";
        clockBtn.className = "btn btn-ghost btn-sm btn-square absolute right-1 top-1/2 -translate-y-1/2";
        clockBtn.innerHTML = "&#128339;"; // clock emoji
        clockBtn.title = "Set time";
        clockBtn.style.zIndex = "10";

        // Ensure wrapper is positioned
        if (getComputedStyle(wrapper).position === "static") {
            wrapper.style.position = "relative";
        }
        // Add padding-right to input for the button
        input.style.paddingRight = "2.5rem";

        var activePopup = null;
        clockBtn.addEventListener("click", function (e) {
            e.preventDefault();
            e.stopPropagation();
            if (activePopup) {
                activePopup.close();
                activePopup = null;
                return;
            }
            activePopup = createTimePopup(input);
        });

        wrapper.appendChild(clockBtn);
    });

})();
