'use client';

import React, { useEffect, useState, useCallback } from 'react';
import { List, ChevronRight } from 'lucide-react';

type ThemeKey = 'default' | 'warm' | 'professional' | 'ocean' | 'forest';

interface ThemeStyles {
  card: string;
  titleColor: string;
  titleIcon: string;
  titleBorder: string;
  itemBg: string;
  itemHover: string;
  itemNumber: string;
  itemText: string;
  itemArrow: string;
  subItemBg: string;
  subItemHover: string;
  subItemText: string;
  subItemDot: string;
  subItemLine: string;
}

const THEMES: Record<ThemeKey, ThemeStyles> = {
  default: {
    card: 'bg-white rounded-2xl border border-slate-200 shadow-sm',
    titleColor: 'text-slate-800',
    titleIcon: 'text-crimson-red',
    titleBorder: 'border-b border-slate-200',
    itemBg: 'bg-white',
    itemHover: 'hover:bg-slate-50 hover:border-crimson-red/30',
    itemNumber: 'bg-crimson-red text-white',
    itemText: 'text-slate-700 group-hover:text-crimson-red',
    itemArrow: 'text-slate-300 group-hover:text-crimson-red group-hover:translate-x-1',
    subItemBg: 'bg-slate-50/50',
    subItemHover: 'hover:bg-slate-100/50',
    subItemText: 'text-slate-600 group-hover:text-crimson-red',
    subItemDot: 'bg-crimson-red/40 group-hover:bg-crimson-red',
    subItemLine: 'border-l-2 border-slate-200',
  },
  warm: {
    card: 'bg-white rounded-2xl border border-orange-200 shadow-sm',
    titleColor: 'text-slate-800',
    titleIcon: 'text-orange-500',
    titleBorder: 'border-b border-orange-200',
    itemBg: 'bg-white',
    itemHover: 'hover:bg-orange-50 hover:border-orange-300',
    itemNumber: 'bg-gradient-to-br from-orange-500 to-red-500 text-white',
    itemText: 'text-slate-800 group-hover:text-orange-600',
    itemArrow: 'text-slate-300 group-hover:text-orange-500 group-hover:translate-x-1',
    subItemBg: 'bg-orange-50/30',
    subItemHover: 'hover:bg-orange-50',
    subItemText: 'text-slate-600 group-hover:text-orange-600',
    subItemDot: 'bg-orange-300 group-hover:bg-orange-500',
    subItemLine: 'border-l-2 border-orange-200',
  },
  professional: {
    card: 'bg-white rounded-2xl border border-slate-200 shadow-sm',
    titleColor: 'text-slate-800',
    titleIcon: 'text-slate-700',
    titleBorder: 'border-b border-slate-200',
    itemBg: 'bg-white',
    itemHover: 'hover:bg-slate-50 hover:border-slate-300',
    itemNumber: 'bg-slate-800 text-white',
    itemText: 'text-slate-700 group-hover:text-slate-900',
    itemArrow: 'text-slate-300 group-hover:text-slate-700 group-hover:translate-x-1',
    subItemBg: 'bg-slate-50/50',
    subItemHover: 'hover:bg-slate-100/50',
    subItemText: 'text-slate-500 group-hover:text-slate-800',
    subItemDot: 'bg-slate-400 group-hover:bg-slate-700',
    subItemLine: 'border-l-2 border-slate-200',
  },
  ocean: {
    card: 'bg-white rounded-2xl border border-blue-200 shadow-sm',
    titleColor: 'text-slate-800',
    titleIcon: 'text-blue-600',
    titleBorder: 'border-b border-blue-200',
    itemBg: 'bg-white',
    itemHover: 'hover:bg-blue-50 hover:border-blue-300',
    itemNumber: 'bg-gradient-to-br from-blue-600 to-indigo-600 text-white',
    itemText: 'text-slate-800 group-hover:text-blue-600',
    itemArrow: 'text-slate-300 group-hover:text-blue-500 group-hover:translate-x-1',
    subItemBg: 'bg-blue-50/30',
    subItemHover: 'hover:bg-blue-50',
    subItemText: 'text-slate-600 group-hover:text-blue-600',
    subItemDot: 'bg-blue-300 group-hover:bg-blue-600',
    subItemLine: 'border-l-2 border-blue-200',
  },
  forest: {
    card: 'bg-white rounded-2xl border border-emerald-200 shadow-sm',
    titleColor: 'text-slate-800',
    titleIcon: 'text-emerald-600',
    titleBorder: 'border-b border-emerald-200',
    itemBg: 'bg-white',
    itemHover: 'hover:bg-emerald-50 hover:border-emerald-300',
    itemNumber: 'bg-gradient-to-br from-emerald-600 to-teal-600 text-white',
    itemText: 'text-slate-800 group-hover:text-emerald-600',
    itemArrow: 'text-slate-300 group-hover:text-emerald-500 group-hover:translate-x-1',
    subItemBg: 'bg-emerald-50/30',
    subItemHover: 'hover:bg-emerald-50',
    subItemText: 'text-slate-600 group-hover:text-emerald-600',
    subItemDot: 'bg-emerald-300 group-hover:bg-emerald-600',
    subItemLine: 'border-l-2 border-emerald-200',
  },
};

type TOCItem = {
  id: string;
  text: string;
  tagName: string;
  children: TOCItem[];
};

function debounce<T extends (...args: any[]) => void>(fn: T, delay: number) {
  let timeoutId: ReturnType<typeof setTimeout>;
  return function (...args: Parameters<T>) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn(...args), delay);
  };
}

function safeId(text: string, index: number): string {
  let id = text
    .toString()
    .trim()
    .replace(/\s+/g, '-')
    .replace(/[#?&%"'<>\\]/g, ''); 
  
  if (!id) {
    id = `heading-${index}`;
  }
  return `toc-${id}-${index}`;
}

interface TableOfContentsProps {
  className?: string;
  title?: string;
  showNumbers?: boolean;
  theme?: ThemeKey;
}

export function TableOfContents({ className = '', title = '目次', showNumbers = true, theme = 'default' }: TableOfContentsProps) {
  const [items, setItems] = useState<TOCItem[]>([]);
  const t = THEMES[theme] || THEMES.default;

  const scanHeadings = useCallback(() => {
    const selector = 'h2:not(header h2):not(footer h2):not([data-toc-ignore]), h3:not(header h3):not(footer h3):not([data-toc-ignore])';
    const elements = document.querySelectorAll(selector);
    
    const toc: TOCItem[] = [];
    let currentH2: TOCItem | null = null;

    elements.forEach((el, index) => {
      if (!el.id) {
        el.id = safeId(el.textContent || '', index);
      }
      
      const item: TOCItem = {
        id: el.id,
        text: el.textContent || '',
        tagName: el.tagName.toLowerCase(),
        children: [],
      };

      if (item.tagName === 'h2') {
        toc.push(item);
        currentH2 = item;
      } else if (item.tagName === 'h3') {
        if (currentH2) {
          currentH2.children.push(item);
        } else {
          toc.push(item);
        }
      }
    });

    setItems(toc);
  }, []);

  useEffect(() => {
    const debouncedScan = debounce(scanHeadings, 500);

    debouncedScan();

    const observer = new MutationObserver((mutations) => {
      let shouldScan = false;
      for (const mutation of mutations) {
        if (mutation.type === 'childList' || mutation.type === 'characterData') {
          shouldScan = true;
          break;
        }
      }
      if (shouldScan) {
        debouncedScan();
      }
    });

    observer.observe(document.body, {
      childList: true,
      subtree: true,
      characterData: true,
    });

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

  const handleClick = (e: React.MouseEvent<HTMLButtonElement>, id: string) => {
    e.preventDefault();
    const el = document.getElementById(id);
    if (el) {
      const top = el.getBoundingClientRect().top + window.scrollY - 80;
      window.scrollTo({ top, behavior: 'smooth' });
      window.history.pushState(null, '', `#${id}`);
    }
  };

  if (items.length === 0) {
    return null;
  }

  return (
    <section className={`w-full py-8 ${className}`} data-toc-ignore>
      <div className="container max-w-5xl mx-auto px-4 sm:px-6 lg:px-8">
        <div className={`${t.card} overflow-hidden`}>
          {/* Title */}
          <div className={`px-6 py-4 flex items-center gap-3 ${t.titleBorder}`}>
            <List className={`w-5 h-5 ${t.titleIcon}`} />
            <h2 className={`text-lg font-bold ${t.titleColor}`} data-toc-ignore>{title}</h2>
          </div>

          {/* Items */}
          <div className="p-3">
            {items.map((item, i) => (
              <div key={item.id}>
                {/* Main item */}
                <button
                  onClick={(e) => handleClick(e, item.id)}
                  className={`group w-full flex items-center gap-4 px-4 py-3.5 rounded-xl border border-transparent transition-all duration-200 text-left ${t.itemBg} ${t.itemHover}`}
                >
                  {showNumbers && (
                    <span className={`flex-shrink-0 w-8 h-8 rounded-lg flex items-center justify-center text-sm font-bold ${t.itemNumber}`}>
                      {i + 1}
                    </span>
                  )}
                  <span className={`flex-1 text-sm font-medium transition-colors duration-200 ${t.itemText}`}>
                    {item.text}
                  </span>
                  <ChevronRight className={`w-4 h-4 flex-shrink-0 transition-all duration-200 ${t.itemArrow}`} />
                </button>

                {/* Sub-items */}
                {item.children.length > 0 && (
                  <div className={`ml-8 pl-4 mb-2 ${t.subItemLine}`}>
                    {item.children.map((subItem) => (
                      <button
                        key={subItem.id}
                        onClick={(e) => handleClick(e, subItem.id)}
                        className={`group w-full flex items-center gap-3 px-4 py-2.5 rounded-lg transition-all duration-200 text-left ${t.subItemBg} ${t.subItemHover}`}
                      >
                        <span className={`flex-shrink-0 w-2 h-2 rounded-full transition-colors duration-200 ${t.subItemDot}`} />
                        <span className={`flex-1 text-xs font-medium transition-colors duration-200 ${t.subItemText}`}>
                          {subItem.text}
                        </span>
                        <ChevronRight className={`w-3 h-3 flex-shrink-0 transition-all duration-200 opacity-0 group-hover:opacity-100 ${t.itemArrow}`} />
                      </button>
                    ))}
                  </div>
                )}
              </div>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}
