"use client";

import { useEffect, useState } from "react";
import { motion } from "motion/react";
import type { TocItem } from "@/lib/blog/process-article";

export function ArticleTOC({ toc }: { toc: TocItem[] }) {
  const [activeId, setActiveId] = useState<string>("");

  useEffect(() => {
    if (toc.length === 0) return;
    const headings = toc
      .map((t) => document.getElementById(t.id))
      .filter((el): el is HTMLElement => el !== null);
    if (headings.length === 0) return;

    const observer = new IntersectionObserver(
      (entries) => {
        const visible = entries
          .filter((e) => e.isIntersecting)
          .sort((a, b) => a.boundingClientRect.top - b.boundingClientRect.top);
        if (visible[0]) setActiveId(visible[0].target.id);
      },
      { rootMargin: "-120px 0px -60% 0px", threshold: [0, 1] }
    );

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

  return (
    <nav className="relative mt-4 border-l border-[var(--color-line)]">
      {toc.map((item) => {
        const isActive = item.id === activeId;
        return (
          <a
            key={item.id}
            href={`#${item.id}`}
            className={`relative block py-1.5 text-[13px] leading-snug transition-all duration-200 ${
              item.level === 2 ? "pl-4 font-semibold" : "pl-7"
            } ${
              isActive
                ? "text-[var(--color-blue)]"
                : "text-[var(--color-slate)] hover:text-[var(--color-blue)]"
            }`}
          >
            {isActive && (
              <motion.span
                layoutId="toc-active"
                className="absolute left-[-1px] top-0 h-full w-[2px] bg-[var(--color-blue)]"
                transition={{ type: "spring", stiffness: 380, damping: 30 }}
              />
            )}
            {item.text}
          </a>
        );
      })}
    </nav>
  );
}
