function parseJsonAttr(el, name, fallback) {
    const raw = el.getAttribute(name);
    if (!raw) return fallback;
    try {
        return JSON.parse(raw);
    } catch (e) {
        return fallback;
    }
}

async function postAjax(url, data) {
    const body = new URLSearchParams();

    const baseObj = (data.base && typeof data.base === "object") ? data.base : {};
    const filtersObj = (data.filters && typeof data.filters === "object") ? data.filters : {};

    body.set("action", data.action);
    body.set("nonce", data.nonce);
    body.set("page", String(data.page || 1));

    // NEW: send how many pages are currently loaded so server can return the correct count on filter changes
    body.set("loaded_pages", String(data.loadedPages || 1));

    body.set("base", JSON.stringify(baseObj));
    body.set("filters", JSON.stringify(filtersObj));

    const res = await fetch(url, {
        method: "POST",
        headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" },
        body,
        credentials: "same-origin",
    });

    return res.json();
}

function setActivePill(container, selector, activeEl) {
    const pills = container.querySelectorAll(selector);
    pills.forEach((p) => {
        const isActive = p === activeEl;
        p.classList.toggle("is-active", isActive);
        p.setAttribute("aria-pressed", isActive ? "true" : "false");
    });
}

function initLatestPostsBlockGrid(root = document) {
    const blocks = root.querySelectorAll('[data-lpgg="1"]');

    blocks.forEach((block) => {
        const ajaxUrl = block.getAttribute("data-lpgg-ajax-url") || "";
        const action = block.getAttribute("data-lpgg-action") || "";
        const nonce = block.getAttribute("data-lpgg-nonce") || "";
        const base = parseJsonAttr(block, "data-lpgg-base", {});

        const grid = block.querySelector("[data-lpgg-grid]");
        const moreBtn = block.querySelector("[data-lpgg-more]");
        const sentinel = block.querySelector("[data-lpgg-sentinel]");

        const termFilter = block.querySelector("[data-lpgg-term-filter]");
        const authorFilter = block.querySelector("[data-lpgg-author-filter]");

        if (!ajaxUrl || !action || !nonce || !grid) return;

        let pageToFetch = 2;     // next page when appending (page 1 is initial render)
        let loadedPages = 1;     // how many pages worth of results are currently shown
        let hasMore = true;
        let isLoading = false;

        let currentFilters = {
            term: null,
            author: null,
        };

        const loadMoreMode = block.getAttribute("data-lpgg-loadmore-mode") || "button";
        const loadMoreEnabled = (block.getAttribute("data-lpgg-loadmore") || "0") === "1";

        async function fetchPage(nextPage, opts) {
            if (isLoading) return;
            isLoading = true;

            const mode = (opts && opts.mode) || "replace"; // replace|append

            try {
                const payload = {
                    action,
                    nonce,
                    page: nextPage,
                    loadedPages,
                    base: {
                        ...base,
                        enable_infinite_scroll_load_more: loadMoreEnabled ? 1 : 0,
                    },
                    filters: currentFilters,
                };

                const json = await postAjax(ajaxUrl, payload);
                if (!json || !json.success || !json.data) {
                    throw new Error("Bad AJAX response");
                }

                const html = json.data.html || "";
                hasMore = !!json.data.hasMore;

                if (mode === "append") {
                    grid.insertAdjacentHTML("beforeend", html);
                    loadedPages += 1;
                    pageToFetch = loadedPages + 1;
                } else {
                    // IMPORTANT: do NOT reset loadedPages.
                    // Server returns the first (loadedPages * perPage) items when replacing.
                    grid.innerHTML = html;
                    pageToFetch = loadedPages + 1;
                }

                if (moreBtn) moreBtn.disabled = !hasMore;
            } catch (e) {
                // optional: show an error state
            } finally {
                isLoading = false;
            }
        }

        function refetchKeepingProgress() {
            // Replace results but keep how far the user had progressed.
            fetchPage(1, { mode: "replace" });
        }

        // Term pills
        if (termFilter) {
            termFilter.addEventListener("click", (e) => {
                const btn = e.target && e.target.closest("[data-lpgg-term]");
                if (!btn) return;

                const raw = btn.getAttribute("data-lpgg-term");
                currentFilters.term = raw && raw !== "" ? raw : null;

                setActivePill(termFilter, "[data-lpgg-term]", btn);
                refetchKeepingProgress();
            });
        }

        // Author pills
        if (authorFilter) {
            authorFilter.addEventListener("click", (e) => {
                const btn = e.target && e.target.closest("[data-lpgg-author]");
                if (!btn) return;

                const raw = btn.getAttribute("data-lpgg-author");
                currentFilters.author = raw && raw !== "" ? raw : null;

                setActivePill(authorFilter, "[data-lpgg-author]", btn);
                refetchKeepingProgress();
            });
        }

        // Button load more
        if (moreBtn && loadMoreEnabled) {
            moreBtn.addEventListener("click", () => {
                if (!hasMore) return;
                fetchPage(pageToFetch, { mode: "append" });
            });
        }

        // Scroll load more
        if (sentinel && loadMoreEnabled && loadMoreMode === "scroll" && "IntersectionObserver" in window) {
            const io = new IntersectionObserver(
                (entries) => {
                    entries.forEach((entry) => {
                        if (!entry.isIntersecting) return;
                        if (!hasMore) return;
                        fetchPage(pageToFetch, { mode: "append" });
                    });
                },
                { rootMargin: "200px 0px" }
            );

            io.observe(sentinel);
        }
    });
}

document.addEventListener("DOMContentLoaded", () => initLatestPostsBlockGrid());