// --- Theme toggle (2-state: dark ↔ light) ---
function cycleTheme() {
    var html = document.documentElement;
    var next = html.getAttribute("data-theme") === "light" ? "dark" : "light";
    html.setAttribute("data-theme", next);
    localStorage.setItem("theme", next);
}
(function() {
    var saved = localStorage.getItem("theme");
    // Migrate "auto" from old 3-state toggle
    if (saved === "auto") saved = "dark";
    if (saved) {
        document.documentElement.setAttribute("data-theme", saved);
        localStorage.setItem("theme", saved);
    }
})();

// --- Events panel ---
function toggleEventsPanel() {
    var panel = document.getElementById("events-panel");
    var overlay = document.getElementById("events-overlay");
    var isOpen = panel.getAttribute("data-open") === "true";
    panel.setAttribute("data-open", !isOpen);
    overlay.setAttribute("data-open", !isOpen);
}

// --- Toast auto-dismiss ---
document.addEventListener("htmx:oobAfterSwap", function(e) {
    if (e.detail.target && e.detail.target.closest(".toast-zone")) {
        var toast = e.detail.target.closest(".toast-zone").lastElementChild;
        if (toast) setTimeout(function() { toast.remove(); }, 5000);
    }
});

// --- Drag & drop flag for htmx polling ---
window.isDragging = false;
window.justDragged = false;

// --- Table sort tracking + persistence ---
window.tableSorted = false;
var _restoringSort = false;

document.addEventListener("click", function(e) {
    var th = e.target.closest("table.sortable thead th:not(.no-sort)");
    if (!th || _restoringSort) return;
    window.tableSorted = true;

    // Save sort state after the library has applied classes
    setTimeout(function() {
        var container = th.closest("[id$='-content']");
        if (!container) return;
        var page = container.id.replace("-content", "");
        var ths = Array.from(th.closest("thead tr").children);
        var col = ths.indexOf(th);
        var dir = th.classList.contains("dir-u") ? "u" : "d";
        localStorage.setItem("sort_" + page, JSON.stringify({col: col, dir: dir}));
    }, 10);
});

// --- Restore sort after htmx content swap ---
document.addEventListener("htmx:afterSwap", function(e) {
    initSortableGrids();

    var target = e.detail.target;
    if (!target || !target.id || !target.id.endsWith("-content")) return;
    var page = target.id.replace("-content", "");
    var saved = localStorage.getItem("sort_" + page);
    if (!saved) return;
    try {
        var sort = JSON.parse(saved);
        var table = target.querySelector("table.sortable");
        if (!table) return;
        var th = table.querySelectorAll("thead th")[sort.col];
        if (!th || th.classList.contains("no-sort")) return;
        _restoringSort = true;
        // First click sorts ascending (dir-d in this library means descending)
        th.click();
        // Library defaults to dir-d on first click; if we need dir-u, click again
        if (sort.dir === "u") {
            setTimeout(function() { th.click(); _restoringSort = false; }, 10);
        } else {
            setTimeout(function() { _restoringSort = false; }, 10);
        }
    } catch(ex) { _restoringSort = false; }
});

function initSortableGrids() {
    document.querySelectorAll(".card-grid").forEach(function(grid) {
        if (grid._sortable) return;
        grid._sortable = new Sortable(grid, {
            animation: 150,
            ghostClass: "sortable-ghost",
            onStart: function() { window.isDragging = true; },
            onEnd: function() {
                window.justDragged = true;
                setTimeout(function() { window.justDragged = false; }, 200);
                saveOrder().then(function() {
                    window.isDragging = false;
                });
            }
        });
    });
}

function saveOrder() {
    var grids = document.querySelectorAll(".card-grid");
    var order = [];
    grids.forEach(function(g) {
        g.querySelectorAll("[data-repo]").forEach(function(card) {
            order.push(card.dataset.repo);
        });
    });
    return fetch("/action/reorder", {
        method: "POST",
        headers: {"Content-Type": "application/json", "HX-Request": "true"},
        body: JSON.stringify({order: order})
    });
}

function resetOrder() {
    fetch("/action/reorder", {
        method: "POST",
        headers: {"Content-Type": "application/json", "HX-Request": "true"},
        body: JSON.stringify({order: []})
    }).then(function() {
        htmx.ajax("GET", "/fragment/dashboard", {target: "#dashboard-content", swap: "innerHTML"});
    });
}

// --- Desktop notifications ---
function toggleDesktopNotifications(enabled) {
    if (enabled && Notification.permission === "default") {
        Notification.requestPermission().then(function(perm) {
            if (perm !== "granted") {
                document.getElementById("desktop-notif-toggle").checked = false;
                localStorage.setItem("desktop_notif", "false");
                return;
            }
            localStorage.setItem("desktop_notif", "true");
        });
    } else {
        localStorage.setItem("desktop_notif", enabled ? "true" : "false");
    }
}

var _prevUnseenCount = null;

function _updateBellBadge(count) {
    var bell = document.getElementById("events-bell");
    if (!bell) return;
    var badge = bell.querySelector(".badge");
    if (count > 0) {
        if (!badge) {
            badge = document.createElement("sup");
            badge.className = "badge";
            bell.appendChild(badge);
        }
        badge.textContent = count;
    } else if (badge) {
        badge.remove();
    }
}

document.addEventListener("htmx:afterSwap", function(e) {
    if (!e.detail.target || e.detail.target.id !== "events-panel") return;

    // Restore notification toggle
    var toggle = document.getElementById("desktop-notif-toggle");
    if (toggle) toggle.checked = localStorage.getItem("desktop_notif") === "true";

    // Update bell badge from panel content
    var items = e.detail.target.querySelectorAll(".event-item");
    var count = items.length;
    _updateBellBadge(count);

    // Desktop notification for new events (single notification)
    if (localStorage.getItem("desktop_notif") !== "true") return;
    if (typeof Notification === "undefined" || Notification.permission !== "granted") return;
    if (_prevUnseenCount !== null && count > _prevUnseenCount) {
        var newCount = count - _prevUnseenCount;
        var body;
        if (newCount === 1 && items[0]) {
            var summary = items[0].querySelector("p");
            body = summary ? summary.textContent.trim() : "New event";
        } else {
            var cwd = document.title || "project-hub";
            body = cwd + ": " + newCount + " new events";
        }
        new Notification("project-hub", { body: body, tag: "project-hub-batch" });
    }
    _prevUnseenCount = count;
});

// --- Filter toggle ---
function setFilter(page, mode) {
    localStorage.setItem("filter_" + page, mode);
    window.tableSorted = false;
    updateFilterButtons();
    var target = document.getElementById(page + "-content");
    if (target) htmx.trigger(target, "do-refresh");
}

var _filterDefaults = { vulns: "active" };

function updateFilterButtons() {
    document.querySelectorAll(".filter-toggle").forEach(function(group) {
        group.querySelectorAll("button[data-filter]").forEach(function(btn) {
            var page = btn.dataset.filterPage;
            var mode = btn.dataset.filter;
            var fallback = _filterDefaults[page] || "all";
            var current = localStorage.getItem("filter_" + page) || fallback;
            btn.classList.toggle("filter-active", mode === current);
        });
    });
}

document.addEventListener("DOMContentLoaded", updateFilterButtons);

// --- CSP-safe dynamic filter values (replaces hx-vals="js:...") ---
document.body.addEventListener("htmx:configRequest", function(e) {
    var elt = e.detail.elt;
    if (!elt || !elt.id) return;
    var filter;
    switch (elt.id) {
        case "mrs-content":
            filter = localStorage.getItem("filter_mrs") || "all";
            break;
        case "issues-content":
            filter = localStorage.getItem("filter_issues") || "all";
            break;
        case "vulns-content":
            filter = typeof getVulnFilter === "function" ? getVulnFilter() : "active";
            break;
        case "pipelines-content":
            filter = typeof getPipelineFilter === "function" ? getPipelineFilter() : "all";
            break;
    }
    if (filter) e.detail.parameters.filter = filter;
});

// --- Skip polling when tab is hidden or drag/sort in progress (replaces hx-trigger conditionals) ---
document.body.addEventListener("htmx:beforeRequest", function(e) {
    var elt = e.detail.elt;
    if (!elt) return;
    // Skip all polling when tab is hidden
    if (document.visibilityState !== "visible") { e.preventDefault(); return; }
    // Skip dashboard polling while dragging
    if (elt.id === "dashboard-content" && window.isDragging) { e.preventDefault(); return; }
    // Skip table polling when user has manually sorted
    var tableIds = {"mrs-content":1, "issues-content":1, "vulns-content":1, "pipelines-content":1};
    if (tableIds[elt.id] && window.tableSorted) { e.preventDefault(); }
});

// --- Centralized data-after handler (CSP-safe, replaces hx-on::after-request) ---
document.body.addEventListener("htmx:afterRequest", function(e) {
    var elt = e.detail.elt;
    var path = (e.detail.pathInfo || {}).requestPath || "";
    var action = elt ? elt.dataset.after : null;

    // Events panel refresh after dismiss
    if (path.indexOf("/action/dismiss-") === 0) {
        htmx.ajax("GET", "/fragment/events-panel", {target: "#events-panel", swap: "innerHTML"});
        return;
    }

    if (!action) return;

    if (action === "refresh-dashboard") {
        htmx.ajax("GET", "/fragment/dashboard", {target: "#dashboard-content", swap: "innerHTML"});
    } else if (action === "refresh-polls") {
        document.querySelectorAll("[hx-trigger*='do-refresh']").forEach(function(el) {
            htmx.trigger(el, "do-refresh");
        });
    } else if (action === "feedback") {
        var done = elt.dataset.feedbackDone || "Done";
        var idle = elt.dataset.feedbackIdle || elt.textContent;
        elt.textContent = done;
        setTimeout(function() { elt.textContent = idle; }, 3000);
    } else if (action === "reload") {
        setTimeout(function() { window.location.reload(); }, 500);
    } else if (action === "redirect") {
        window.location = elt.dataset.redirect || "/";
    }
});

// --- Initial events panel load (fallback if htmx load trigger misses) ---
setTimeout(function() {
    var panel = document.getElementById("events-panel");
    if (panel && !panel.querySelector("header")) {
        htmx.ajax("GET", "/fragment/events-panel", {target: "#events-panel", swap: "innerHTML"});
    }
}, 200);
