// ── BurgerSpec.js ────────────────────────────────────────────────────────────
//
// Unit specs for burger-btn.js — the room.html corner-menu btn + its 5-btn
// fanning arc (sky, earth, sea, voice, text).
//
// DOM contract assumed by the module:
//   #id_burger_btn   — the burger btn
//   #id_burger_fan   — the fan container (sibling)
//   .burger-fan-btn  — each sub-btn (5 of them)
//   #id_kit_btn      — kit btn (optional)
//   #id_kit_bag_dialog — kit dialog (optional)
//   #id_bud_btn      — bud btn (optional)
//
// Public API under test (window.bindBurger):
//   var ac = bindBurger();  // returns an AbortController for cleanup
//
// Behaviours:
//   • Click toggles .active class on #id_burger_btn.
//   • Escape closes when open.
//   • Click outside closes when open.
//   • Opening burger closes the kit dialog + the bud panel if either is open.
//
// ─────────────────────────────────────────────────────────────────────────────

describe("Burger", () => {
    let burgerBtn, fan, ac;

    beforeEach(() => {
        burgerBtn = document.createElement("button");
        burgerBtn.id = "id_burger_btn";
        document.body.appendChild(burgerBtn);

        fan = document.createElement("div");
        fan.id = "id_burger_fan";
        document.body.appendChild(fan);

        ac = bindBurger();
    });

    afterEach(() => {
        if (ac) ac.abort();
        burgerBtn.remove();
        fan.remove();
        // Clean up any test-added kit/bud elements + classes.
        ["id_kit_btn", "id_kit_bag_dialog", "id_bud_btn"].forEach(id => {
            const el = document.getElementById(id);
            if (el) el.remove();
        });
        document.documentElement.classList.remove("bud-open");
    });

    describe("bindBurger()", () => {
        it("returns an AbortController when DOM is present", () => {
            expect(ac).not.toBeNull();
            expect(ac.abort).toBeDefined();
        });

        it("returns null when #id_burger_btn is absent", () => {
            burgerBtn.remove();
            const ac2 = bindBurger();
            expect(ac2).toBeNull();
        });

        it("returns null when #id_burger_fan is absent", () => {
            fan.remove();
            const ac2 = bindBurger();
            expect(ac2).toBeNull();
        });
    });

    describe("click toggle", () => {
        it("first click adds .active to #id_burger_btn", () => {
            burgerBtn.click();
            expect(burgerBtn.classList.contains("active")).toBe(true);
        });

        it("first click sets aria-expanded='true'", () => {
            burgerBtn.click();
            expect(burgerBtn.getAttribute("aria-expanded")).toBe("true");
        });

        it("first click sets fan aria-hidden='false'", () => {
            burgerBtn.click();
            expect(fan.getAttribute("aria-hidden")).toBe("false");
        });

        it("second click removes .active (closes)", () => {
            burgerBtn.click();
            burgerBtn.click();
            expect(burgerBtn.classList.contains("active")).toBe(false);
        });

        it("second click resets aria-expanded='false'", () => {
            burgerBtn.click();
            burgerBtn.click();
            expect(burgerBtn.getAttribute("aria-expanded")).toBe("false");
        });
    });

    describe("Escape key", () => {
        it("closes burger when open", () => {
            burgerBtn.click();
            const evt = new KeyboardEvent("keydown", { key: "Escape" });
            document.dispatchEvent(evt);
            expect(burgerBtn.classList.contains("active")).toBe(false);
        });

        it("no-op when burger already closed", () => {
            const evt = new KeyboardEvent("keydown", { key: "Escape" });
            document.dispatchEvent(evt);
            expect(burgerBtn.classList.contains("active")).toBe(false);
        });
    });

    describe("click-outside", () => {
        it("closes burger on click outside btn + fan", () => {
            burgerBtn.click();
            const outsider = document.createElement("div");
            document.body.appendChild(outsider);
            outsider.click();
            expect(burgerBtn.classList.contains("active")).toBe(false);
            outsider.remove();
        });

        it("does NOT close on click inside fan", () => {
            burgerBtn.click();
            const subBtn = document.createElement("button");
            subBtn.className = "burger-fan-btn";
            fan.appendChild(subBtn);
            subBtn.click();
            expect(burgerBtn.classList.contains("active")).toBe(true);
        });
    });

    describe("opening burger closes other corner panels", () => {
        it("clicks #id_kit_btn when kit dialog is open", () => {
            const kitBtn = document.createElement("button");
            kitBtn.id = "id_kit_btn";
            const kitClickSpy = jasmine.createSpy("kitClick");
            kitBtn.addEventListener("click", kitClickSpy);
            document.body.appendChild(kitBtn);

            const dialog = document.createElement("dialog");
            dialog.id = "id_kit_bag_dialog";
            dialog.setAttribute("open", "");
            document.body.appendChild(dialog);

            burgerBtn.click();
            expect(kitClickSpy).toHaveBeenCalled();
        });

        it("does NOT click #id_kit_btn when kit dialog is closed", () => {
            const kitBtn = document.createElement("button");
            kitBtn.id = "id_kit_btn";
            const kitClickSpy = jasmine.createSpy("kitClick");
            kitBtn.addEventListener("click", kitClickSpy);
            document.body.appendChild(kitBtn);

            const dialog = document.createElement("dialog");
            dialog.id = "id_kit_bag_dialog";
            // no open attribute
            document.body.appendChild(dialog);

            burgerBtn.click();
            expect(kitClickSpy).not.toHaveBeenCalled();
        });

        it("clicks #id_bud_btn when html.bud-open is set", () => {
            const budBtn = document.createElement("button");
            budBtn.id = "id_bud_btn";
            const budClickSpy = jasmine.createSpy("budClick");
            budBtn.addEventListener("click", budClickSpy);
            document.body.appendChild(budBtn);

            document.documentElement.classList.add("bud-open");

            burgerBtn.click();
            expect(budClickSpy).toHaveBeenCalled();
        });

        it("does NOT click #id_bud_btn when html.bud-open is absent", () => {
            const budBtn = document.createElement("button");
            budBtn.id = "id_bud_btn";
            const budClickSpy = jasmine.createSpy("budClick");
            budBtn.addEventListener("click", budClickSpy);
            document.body.appendChild(budBtn);

            burgerBtn.click();
            expect(budClickSpy).not.toHaveBeenCalled();
        });

        it("ignores missing kit/bud btns w.o. error", () => {
            // No kit, no bud — opening should still succeed.
            expect(() => burgerBtn.click()).not.toThrow();
            expect(burgerBtn.classList.contains("active")).toBe(true);
        });
    });

    describe("inactive sub-btn flash", () => {
        let subBtn;

        beforeEach(() => {
            subBtn = document.createElement("button");
            subBtn.className = "burger-fan-btn";
            fan.appendChild(subBtn);
            jasmine.clock().install();
        });

        afterEach(() => {
            jasmine.clock().uninstall();
        });

        it("adds .flash-inactive to inactive sub-btn on click", () => {
            subBtn.click();
            expect(subBtn.classList.contains("flash-inactive")).toBe(true);
        });

        it("removes .flash-inactive after the ON window (~180ms)", () => {
            subBtn.click();
            jasmine.clock().tick(200);
            expect(subBtn.classList.contains("flash-inactive")).toBe(false);
        });

        it("pulses twice — second ON window arrives after off+on cycle (~480ms)", () => {
            subBtn.click();
            // First pulse cycle: 180ms ON + 120ms OFF = 300ms. Second pulse ON starts.
            jasmine.clock().tick(310);
            expect(subBtn.classList.contains("flash-inactive")).toBe(true);
        });

        it("settles back to default after 2 pulses (~700ms total)", () => {
            subBtn.click();
            jasmine.clock().tick(800);
            expect(subBtn.classList.contains("flash-inactive")).toBe(false);
        });

        it("does NOT flash when sub-btn carries .active class", () => {
            subBtn.classList.add("active");
            subBtn.click();
            expect(subBtn.classList.contains("flash-inactive")).toBe(false);
        });
    });

    describe("AbortController teardown", () => {
        it("detaches click handler when ac.abort() is called", () => {
            ac.abort();
            burgerBtn.click();
            expect(burgerBtn.classList.contains("active")).toBe(false);
        });
    });
});
