'use client';

import { useEffect, useState } from 'react';

type Heading = {
    id: string;
    text: string;
    level: number;
};

export function TableOfContents({ headings }: { headings: Heading[] }) {
    const [activeId, setActiveId] = useState<string>(() => headings[0]?.id ?? '');

    useEffect(() => {
        const elements = headings
            .map((heading) => document.getElementById(heading.id))
            .filter((element): element is HTMLElement => Boolean(element));

        if (elements.length === 0) return;

        const observer = new IntersectionObserver((entries) => {
            const visible = entries
                .filter((entry) => entry.isIntersecting)
                .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);

            if (visible[0]?.target.id) {
                setActiveId(visible[0].target.id);
            }
        }, {
            rootMargin: '-20% 0px -65% 0px',
            threshold: 0,
        });

        elements.forEach((element) => observer.observe(element));
        return () => observer.disconnect();
    }, [headings]);

    if (headings.length === 0) return null;

    return (
        <nav aria-label="Table of contents" className="text-left">
            <h4 className="eyebrow mb-4">Contents</h4>
            <ul className="space-y-2">
                {Array.isArray(headings) && headings.map((heading) => (
                    <li key={heading.id} className={heading.level > 2 ? 'pl-3' : undefined}>
                        <a
                            href={`#${heading.id}`}
                            className={`block text-[0.82rem] leading-6 transition-colors ${activeId === heading.id
                                ? 'text-ink'
                                : 'text-muted hover:text-ink'
                                }`}
                        >
                            {heading.text}
                        </a>
                    </li>
                ))}
            </ul>
        </nav>
    );
}
