"use client";
import React, { useCallback, useEffect, useRef, useState } from "react";

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

export function TableOfContents({ headings }: { headings: Heading[] }) {
  const [activeId, setActiveId] = useState<string | null>(null);
  const [isOpen, setIsOpen] = useState(false);
  const isManualScrollRef = useRef(false);
  const manualScrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);

  // Get offset for fixed headers
  const getOffset = useCallback(() => {
    const header = document.querySelector(".app-header");
    const subnav = document.querySelector(".subnav-bar");
    let offset = 16; // Padding for extra safety margin
    if (header) offset += header.getBoundingClientRect().height;
    if (subnav) offset += subnav.getBoundingClientRect().height;
    return offset;
  }, []);

  // Scroll spy - track which heading is currently visible
  useEffect(() => {
    if (headings.length === 0) return;

    const updateActiveHeading = () => {
      if (isManualScrollRef.current) return;

      const offset = getOffset();
      let found: string | null = null;

      // Go through headings and find which one we're at
      for (let i = 0; i < headings.length; i++) {
        const el = document.getElementById(headings[i].id);
        if (!el) continue;

        const rect = el.getBoundingClientRect();
        // If this heading is at or above our threshold, it's the current one
        if (rect.top <= offset + 5) {
          found = headings[i].id;
        } else {
          // First heading that's below threshold - stop here
          break;
        }
      }

      // If at very top of page, select first heading
      if (!found && window.scrollY < offset + 50 && headings.length > 0) {
        found = headings[0].id;
      }

      setActiveId(found);
    };

    // Run on mount
    updateActiveHeading();

    // Throttle scroll events
    let ticking = false;
    const onScroll = () => {
      if (!ticking) {
        requestAnimationFrame(() => {
          updateActiveHeading();
          ticking = false;
        });
        ticking = true;
      }
    };

    window.addEventListener("scroll", onScroll, { passive: true });
    return () => window.removeEventListener("scroll", onScroll);
  }, [headings, getOffset]);

  // Scroll to a heading when clicked
  const scrollToHeading = useCallback((id: string) => {
    const el = document.getElementById(id);
    if (!el) return;

    // Mark as manual scroll to prevent scroll spy interference
    isManualScrollRef.current = true;
    if (manualScrollTimeoutRef.current) {
      clearTimeout(manualScrollTimeoutRef.current);
    }

    // Set active immediately for responsive feel
    setActiveId(id);
    setIsOpen(false);

    // Calculate position
    const offset = getOffset();
    const top = el.getBoundingClientRect().top + window.scrollY - offset;

    // Scroll
    window.scrollTo({ top: Math.max(0, top), behavior: "smooth" });

    // Update URL
    history.replaceState(null, "", `#${id}`);

    // Re-enable scroll spy after scroll completes
    manualScrollTimeoutRef.current = setTimeout(() => {
      isManualScrollRef.current = false;
    }, 1000);
  }, [getOffset]);

  const handleClick = useCallback((e: React.MouseEvent, id: string) => {
    e.preventDefault();
    scrollToHeading(id);
  }, [scrollToHeading]);

  // Handle hash on page load
  useEffect(() => {
    const hash = window.location.hash.slice(1);
    if (hash && headings.some(h => h.id === hash)) {
      setTimeout(() => scrollToHeading(hash), 200);
    }
  }, [headings, scrollToHeading]);

  // Cleanup
  useEffect(() => {
    return () => {
      if (manualScrollTimeoutRef.current) {
        clearTimeout(manualScrollTimeoutRef.current);
      }
    };
  }, []);

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

  return (
    <div className="toc-container">
      <button
        className="toc-toggle md:hidden"
        onClick={() => setIsOpen(!isOpen)}
        aria-expanded={isOpen}
        aria-controls="toc-nav"
      >
        <span className="toc-toggle-icon">{isOpen ? "✕" : "☰"}</span>
        <span>{isOpen ? "Fechar conteúdos" : "Mostrar conteúdos"}</span>
      </button>

      <nav
        id="toc-nav"
        aria-label="Tabela de conteúdos"
        className={`toc-nav ${isOpen ? "toc-nav--open" : ""}`}
      >
        <h2 className="toc-title">Conteúdos</h2>
        <ul className="toc-list">
          {headings.map((h) => (
            <li
              key={h.id}
              className="toc-item"
              style={{ paddingLeft: `${(h.level - 1) * 0.75}rem` }}
            >
              <a
                href={`#${h.id}`}
                onClick={(e) => handleClick(e, h.id)}
                className={`toc-link ${activeId === h.id ? "toc-link--active" : ""}`}
              >
                {h.text}
              </a>
            </li>
          ))}
        </ul>
      </nav>
    </div>
  );
}
