// retoor <retoor@molodetz.nl>

export class OverflowTabs {
    constructor() {
        this.instances = [];
        document.querySelectorAll("[data-overflow-tabs]").forEach((root) => {
            const instance = this.create(root);
            if (instance) {
                this.instances.push(instance);
            }
        });
    }

    create(root) {
        const more = root.querySelector(".overflow-tabs-more");
        const strip = root.querySelector(".overflow-tabs-strip");
        if (!more || !strip) {
            return null;
        }
        const tabs = Array.from(strip.children).filter(
            (el) => !el.classList.contains("overflow-tabs-more")
        );
        if (!tabs.length) {
            return null;
        }

        const state = {
            root,
            strip,
            more,
            tabs,
            overflow: [],
        };

        state.sync = () => {
            void strip.offsetWidth;
        };

        state.stripOverflows = () => strip.scrollWidth > strip.clientWidth + 1;

        state.layout = () => {
            tabs.forEach((tab) => {
                tab.hidden = false;
            });
            more.hidden = true;
            state.sync();

            if (!state.stripOverflows()) {
                state.overflow = [];
                return;
            }

            more.hidden = false;
            state.sync();

            while (state.stripOverflows()) {
                const victim = tabs
                    .filter((tab) => !tab.hidden && !tab.classList.contains("active"))
                    .pop();
                if (!victim) {
                    break;
                }
                victim.hidden = true;
                state.sync();
            }

            state.overflow = tabs.filter((tab) => tab.hidden);
            if (state.overflow.length > 0 || state.stripOverflows()) {
                more.hidden = false;
            }
        };

        state.open = (event) => {
            event.preventDefault();
            event.stopPropagation();
            const items = state.overflow.map((tab) => ({
                icon: tab.dataset.menuIcon || "",
                label: tab.dataset.menuLabel || tab.textContent.trim(),
                onSelect: () => tab.click(),
            }));
            if (!items.length) {
                return;
            }
            const rect = more.getBoundingClientRect();
            window.app.contextMenu.open(rect.left, rect.bottom + 4, items);
        };

        root.classList.add("tabs-managed");
        more.addEventListener("click", (event) => state.open(event));
        for (const tab of tabs) {
            tab.addEventListener("click", () => {
                requestAnimationFrame(() => state.layout());
            });
        }

        const scheduleLayout = () => {
            requestAnimationFrame(() => state.layout());
        };

        window.addEventListener("resize", scheduleLayout);
        if (typeof ResizeObserver !== "undefined") {
            state.resizeObserver = new ResizeObserver(scheduleLayout);
            state.resizeObserver.observe(root);
            state.resizeObserver.observe(strip);
        }

        scheduleLayout();
        if (document.fonts?.ready) {
            document.fonts.ready.then(scheduleLayout);
        }
        window.addEventListener("load", scheduleLayout, { once: true });

        return state;
    }
}