import { useEffect, useState } from 'react';
import { useAppStore } from '../../store/appStore';
import { useScripts } from '../../hooks/useScripts';
import type { ClassSummary, NamespaceTree } from '../../types/scripts';
import styles from './ScriptTree.module.css';

interface Props {
  search: string;
}

export default function ScriptTree({ search }: Props) {
  const { setSelectedClass, setCenterMode } = useAppStore();
  const { tree, loading, error, loadTree, search: searchScripts } = useScripts();
  const [searchResults, setSearchResults] = useState<ClassSummary[] | null>(null);
  const [expanded, setExpanded] = useState<Set<string>>(new Set());

  useEffect(() => {
    loadTree();
  }, []);

  useEffect(() => {
    if (!search.trim()) {
      setSearchResults(null);
      return;
    }
    const timer = setTimeout(async () => {
      const results = await searchScripts(search);
      setSearchResults(results);
    }, 250);
    return () => clearTimeout(timer);
  }, [search]);

  function toggleNamespace(ns: string) {
    setExpanded((prev) => {
      const next = new Set(prev);
      next.has(ns) ? next.delete(ns) : next.add(ns);
      return next;
    });
  }

  function selectClass(cls: ClassSummary) {
    setSelectedClass(cls);
    setCenterMode('script_class');
  }

  if (loading && tree.length === 0) {
    return <div className={styles.empty}>Loading scripts…</div>;
  }
  if (error) {
    return <div className={styles.error}>{error}</div>;
  }
  if (!loading && tree.length === 0) {
    return (
      <div className={styles.empty}>
        No scripts indexed yet.
        <br />
        Set your Scripts path in Config and click [Index Scripts].
      </div>
    );
  }

  // Search mode
  if (searchResults !== null) {
    return (
      <div className={styles.list}>
        {searchResults.length === 0 && (
          <div className={styles.empty}>No results for "{search}"</div>
        )}
        {searchResults.map((cls) => (
          <ClassRow key={cls.name} cls={cls} onSelect={selectClass} showNamespace />
        ))}
      </div>
    );
  }

  return (
    <div className={styles.list}>
      {tree.map((ns) => (
        <NamespaceGroup
          key={ns.namespace}
          ns={ns}
          expanded={expanded.has(ns.namespace)}
          onToggle={() => toggleNamespace(ns.namespace)}
          onSelect={selectClass}
        />
      ))}
    </div>
  );
}

function NamespaceGroup({
  ns,
  expanded,
  onToggle,
  onSelect,
}: {
  ns: NamespaceTree;
  expanded: boolean;
  onToggle: () => void;
  onSelect: (cls: ClassSummary) => void;
}) {
  const shortNs = ns.namespace.split('.').pop() ?? ns.namespace;

  return (
    <div className={styles.namespace}>
      <button className={styles.nsHeader} onClick={onToggle}>
        <span className={styles.nsChevron}>{expanded ? '▾' : '▸'}</span>
        <span className={styles.nsName}>{shortNs}</span>
        <span className={styles.nsCount}>{ns.classes.length}</span>
      </button>
      {expanded && (
        <div className={styles.nsClasses}>
          {ns.classes.map((cls) => (
            <ClassRow key={cls.name} cls={cls} onSelect={onSelect} />
          ))}
        </div>
      )}
    </div>
  );
}

function ClassRow({
  cls,
  onSelect,
  showNamespace,
}: {
  cls: ClassSummary;
  onSelect: (cls: ClassSummary) => void;
  showNamespace?: boolean;
}) {
  const badge = cls.isGump ? 'G' : cls.isMobile ? 'M' : cls.isItem ? 'I' : null;
  const badgeClass = cls.isGump
    ? styles.badgeGump
    : cls.isMobile
    ? styles.badgeMobile
    : styles.badgeItem;

  return (
    <button className={styles.classRow} onClick={() => onSelect(cls)}>
      {badge && <span className={`${styles.badge} ${badgeClass}`}>{badge}</span>}
      <span className={styles.className}>{cls.name}</span>
      {showNamespace && (
        <span className={styles.classNs}>{cls.namespace.split('.').pop()}</span>
      )}
    </button>
  );
}
