'use client';

import { useState, useEffect } from 'react';
import { usePathname } from 'next/navigation';
import styles from './TableOfContents.module.css';

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

type TableOfContentsProps = {
  locale: 'en' | 'vi';
};

export default function TableOfContents({ locale }: TableOfContentsProps) {
  const [headings, setHeadings] = useState<HeadingItem[]>([]);
  const [activeId, setActiveId] = useState<string>('');
  const pathname = usePathname();

  // Extract headings from content
  useEffect(() => {
    const extractHeadings = (): HeadingItem[] => {
      const content = document.querySelector('[data-docs-content]');
      if (!content) return [];

      const headingElements = content.querySelectorAll('h1, h2, h3, h4, h5, h6');
      const headingItems: HeadingItem[] = [];

      headingElements.forEach((heading) => {
        const text = heading.textContent?.trim() || '';
        const id = heading.id;

        if (id && text) {
          const level = parseInt(heading.tagName.charAt(1));
          headingItems.push({ id, text, level });
        }
      });

      return headingItems;
    };

    // Function to update headings
    const updateHeadings = () => {
      const headingItems = extractHeadings();
      setHeadings(headingItems);
      // Reset active ID if we have no headings (e.g. page transition)
      if (headingItems.length === 0) {
        setActiveId('');
      }
    };

    // Set up MutationObserver to watch for content changes
    const content = document.querySelector('[data-docs-content]');
    let observer: MutationObserver | null = null;
    let timers: NodeJS.Timeout[] = [];

    const cleanup = () => {
      if (observer) {
        observer.disconnect();
        observer = null;
      }
      timers.forEach(t => clearTimeout(t));
      timers = [];
    };

    // Try extracting immediately
    const initialTimer = setTimeout(updateHeadings, 0);
    timers.push(initialTimer);

    if (content) {
      // Watch for changes in the content structure (loading, hydration)
      observer = new MutationObserver(() => {
        updateHeadings();
      });

      observer.observe(content, {
        childList: true,
        subtree: true,
        // No longer watching attributes since we don't modify them
      });
    }

    // Try periodically for dynamic content
    const tryMultipleTimes = [100, 300, 500, 1000];
    tryMultipleTimes.forEach((delay) => {
      const timer = setTimeout(updateHeadings, delay);
      timers.push(timer);
    });

    return cleanup;
  }, [pathname]); // Re-run when pathname changes

  // Set up intersection observer for active heading
  useEffect(() => {
    if (headings.length === 0) return;

    const observerOptions = {
      root: null,
      rootMargin: '-80px 0px -80% 0px',
      threshold: 0,
    };

    const observerCallback = (entries: IntersectionObserverEntry[]) => {
      entries.forEach((entry) => {
        if (entry.isIntersecting) {
          setActiveId(entry.target.id);
        }
      });
    };

    const observer = new IntersectionObserver(observerCallback, observerOptions);

    // Observe all headings
    headings.forEach((item) => {
      const element = document.getElementById(item.id);
      if (element) {
        observer.observe(element);
      }
    });

    return () => {
      observer.disconnect();
    };
  }, [headings]);

  // Always render TOC container, even if empty (for debugging and layout consistency)

  const handleClick = (e: React.MouseEvent<HTMLAnchorElement>, id: string) => {
    e.preventDefault();
    const element = document.getElementById(id);
    if (element) {
      const offsetTop = element.getBoundingClientRect().top + window.pageYOffset - 80;
      window.scrollTo({
        top: offsetTop,
        behavior: 'smooth',
      });
      setActiveId(id);
    }
  };

  return (
    <aside className={styles.toc}>
      <div className={styles.tocHeader}>
        {locale === 'en' ? 'On this page' : 'Mục lục'}
      </div>
      {headings.length > 0 ? (
        <nav className={styles.tocNav}>
          <ul className={styles.tocList}>
            {headings.map((heading) => (
              <li
                key={heading.id}
                className={`${styles.tocItem} ${styles[`tocLevel${heading.level}`]} ${activeId === heading.id ? styles.tocItemActive : ''
                  }`}
              >
                <a
                  href={`#${heading.id}`}
                  onClick={(e) => handleClick(e, heading.id)}
                  className={styles.tocLink}
                >
                  {heading.text}
                </a>
              </li>
            ))}
          </ul>
        </nav>
      ) : null}
    </aside>
  );
}

