document.addEventListener("DOMContentLoaded", () =>
{
    const setupKangarooEye = () => {
        const heroGraphic = document.querySelector("main > header > svg");
        const eye = heroGraphic?.querySelector("#eye");
        const pupil = heroGraphic?.querySelector("#pupil");

        if (!heroGraphic || !eye || !pupil) {
            return;
        }

        const limits = {
            left: 4,
            right: 2,
            vertical: 4,
        };

        let frame = null;
        let pointer = null;

        const render = () => {
            frame = null;

            if (!pointer) {
                pupil.setAttribute("transform", "translate(0 0)");
                return;
            }

            const rect = heroGraphic.getBoundingClientRect();
            const eyeRect = eye.getBoundingClientRect();

            if (!rect.width || !rect.height || !eyeRect.width || !eyeRect.height) {
                return;
            }

            const eyeCenterX = eyeRect.left + (eyeRect.width / 2);
            const eyeCenterY = eyeRect.top + (eyeRect.height / 2);
            const normalizedX = (pointer.x - eyeCenterX) / (rect.width / 2);
            const normalizedY = (pointer.y - eyeCenterY) / (rect.height / 2);
            const clampedX = Math.max(-1, Math.min(1, normalizedX));
            const clampedY = Math.max(-1, Math.min(1, normalizedY));
            const moveX = clampedX < 0 ? clampedX * limits.left : clampedX * limits.right;
            const moveY = clampedY * limits.vertical;

            pupil.setAttribute("transform", `translate(${moveX.toFixed(2)} ${moveY.toFixed(2)})`);
        };

        const requestRender = () => {
            if (frame !== null) {
                return;
            }

            frame = window.requestAnimationFrame(render);
        };

        window.addEventListener("mousemove", (event) => {
            pointer = { x: event.clientX, y: event.clientY };
            requestRender();
        }, { passive: true });

        window.addEventListener("mouseleave", () => {
            pointer = null;
            requestRender();
        });

        requestRender();
    };

    const setupToc = () => {
        const toc = document.querySelector("nav");
        const content = document.querySelector("article");
        const list = toc?.querySelector("ol");

        if (!toc || !content || !list) {
            return;
        }

        const links = Array.from(toc.querySelectorAll('a[href^="#"]'));
        const sections = Array.from(content.querySelectorAll("section[id]"));
        let activeId = null;

        if (!links.length || !sections.length) {
            return;
        }

        const linksById = new Map(
            links.map((link) => [decodeURIComponent(link.getAttribute("href").slice(1)), link]),
        );

        const scrollActiveItemIntoView = (link, behavior = "auto") => {
            if (!link) {
                return;
            }

            const hasHorizontalOverflow = list.scrollWidth > list.clientWidth;

            if (!hasHorizontalOverflow) {
                return;
            }

            const listRect = list.getBoundingClientRect();
            const linkRect = link.getBoundingClientRect();
            const itemLeft = linkRect.left - listRect.left + list.scrollLeft;
            const itemCenter = itemLeft + (linkRect.width / 2);
            const maxScrollLeft = list.scrollWidth - list.clientWidth;
            const targetLeft = Math.max(0, Math.min(maxScrollLeft, itemCenter - (list.clientWidth / 2)));

            list.scrollTo({
                behavior,
                left: targetLeft,
            });
        };

        const setActive = (id, behavior = "auto") => {
            const activeLink = linksById.get(id);

            links.forEach((link) => {
                link.closest("li")?.classList.toggle("active", activeLink === link);
            });

            if (activeLink && activeId !== id) {
                activeId = id;
                scrollActiveItemIntoView(activeLink, behavior);
            }
        };

        const updateActive = (behavior = "auto") => {
            const threshold = window.innerHeight * 0.25;
            let current = sections[0];

            sections.forEach((section) => {
                if (section.getBoundingClientRect().top <= threshold) {
                    current = section;
                }
            });

            if (current?.id) {
                setActive(current.id, behavior);
            }
        };

        updateActive();
        links.forEach((link) => {
            link.addEventListener("click", () => scrollActiveItemIntoView(link, "smooth"));
        });
        window.addEventListener("scroll", () => updateActive("smooth"), { passive: true });
        window.addEventListener("resize", updateActive);
    };

    setupKangarooEye();
    setupToc();
});
