import { useState, useMemo, useRef, useEffect, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { motion, AnimatePresence } from "framer-motion";
import { Search, X } from "lucide-react";
import { courseOverviews } from "@/data/courseOverviews";
import { portraitDimensions, traitMappings } from "@/data/portraitData";
import { quarters } from "@/data/curriculum";

interface SearchResult {
  type: "course" | "dimension" | "trait" | "quarter";
  title: string;
  subtitle: string;
  emoji: string;
  link?: string;
  action?: string;
}

export const GlobalSearch = () => {
  const [isOpen, setIsOpen] = useState(false);
  const [query, setQuery] = useState("");
  const inputRef = useRef<HTMLInputElement>(null);
  const panelRef = useRef<HTMLDivElement>(null);
  const triggerRef = useRef<HTMLButtonElement>(null);
  const navigate = useNavigate();

  const closeSearch = useCallback(() => {
    setIsOpen(false);
    setQuery("");
  }, []);

  const openSearch = useCallback(() => {
    setIsOpen(true);
  }, []);

  // ⌘K / Ctrl+K to open
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if ((e.metaKey || e.ctrlKey) && e.key === "k") {
        e.preventDefault();
        openSearch();
      }
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [openSearch]);

  // Escape to close while search is open
  useEffect(() => {
    if (!isOpen) return;

    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === "Escape") {
        e.preventDefault();
        e.stopPropagation();
        closeSearch();
      }
    };

    window.addEventListener("keydown", handleKeyDown, true);
    return () => window.removeEventListener("keydown", handleKeyDown, true);
  }, [isOpen, closeSearch]);

  // Close when clicking/tapping outside the search panel
  useEffect(() => {
    if (!isOpen) return;

    const handlePointerDown = (e: MouseEvent | TouchEvent) => {
      const target = e.target as Node;
      if (panelRef.current?.contains(target)) return;
      if (triggerRef.current?.contains(target)) return;
      closeSearch();
    };

    document.addEventListener("mousedown", handlePointerDown);
    document.addEventListener("touchstart", handlePointerDown);
    return () => {
      document.removeEventListener("mousedown", handlePointerDown);
      document.removeEventListener("touchstart", handlePointerDown);
    };
  }, [isOpen, closeSearch]);

  useEffect(() => {
    if (!isOpen) return;
    const previousOverflow = document.body.style.overflow;
    document.body.style.overflow = "hidden";
    return () => {
      document.body.style.overflow = previousOverflow;
    };
  }, [isOpen]);

  useEffect(() => {
    if (isOpen && inputRef.current) {
      inputRef.current.focus();
    }
  }, [isOpen]);

  const results = useMemo<SearchResult[]>(() => {
    if (!query.trim()) return [];
    const q = query.toLowerCase();

    const courseResults: SearchResult[] = courseOverviews
      .filter((c) => c.name.toLowerCase().includes(q) || c.tagline.toLowerCase().includes(q))
      .map((c) => ({
        type: "course",
        title: c.name,
        subtitle: c.type === "core" ? "Core Course" : `DNA · ${c.strand}`,
        emoji: c.emoji,
        link: `/course/${c.slug}`,
      }));

    const dimensionResults: SearchResult[] = portraitDimensions
      .filter((d) => d.title.toLowerCase().includes(q) || d.desc.toLowerCase().includes(q))
      .map((d) => ({
        type: "dimension",
        title: d.title,
        subtitle: d.desc,
        emoji: d.emoji,
        action: d.key,
      }));

    const traitResults: SearchResult[] = traitMappings
      .filter((t) => t.trait.toLowerCase().includes(q) || t.mindset.toLowerCase().includes(q))
      .reduce<SearchResult[]>((acc, t) => {
        if (!acc.find((r) => r.title === t.trait)) {
          acc.push({
            type: "trait",
            title: t.trait,
            subtitle: `Mindset: ${t.mindset}`,
            emoji: "🧠",
          });
        }
        return acc;
      }, []);

    const quarterResults: SearchResult[] = quarters
      .filter((q2) =>
        q2.title.toLowerCase().includes(q) ||
        q2.role.toLowerCase().includes(q) ||
        q2.theme.toLowerCase().includes(q)
      )
      .map((q2) => ({
        type: "quarter",
        title: `Q${q2.id}: ${q2.role}`,
        subtitle: q2.title,
        emoji: q2.emoji,
        link: `/quarter/${q2.id}`,
      }));

    return [...courseResults, ...dimensionResults, ...traitResults, ...quarterResults].slice(0, 8);
  }, [query]);

  const handleSelect = (result: SearchResult) => {
    if (result.link) {
      navigate(result.link);
    }
    closeSearch();
  };

  return (
    <>
      <button
        ref={triggerRef}
        type="button"
        onClick={openSearch}
        aria-expanded={isOpen}
        aria-haspopup="dialog"
        className="flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm text-muted-foreground hover:text-foreground hover:bg-secondary/80 transition-colors border border-border"
      >
        <Search size={14} />
        <span className="hidden sm:inline">Search...</span>
        <kbd className="hidden md:inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded bg-muted text-[10px] font-mono text-muted-foreground">
          ⌘K
        </kbd>
      </button>

      <AnimatePresence>
        {isOpen && (
          <>
            <motion.button
              type="button"
              initial={{ opacity: 0 }}
              animate={{ opacity: 1 }}
              exit={{ opacity: 0 }}
              transition={{ duration: 0.2 }}
              onClick={closeSearch}
              aria-label="Close search"
              className="fixed inset-0 bg-foreground/20 backdrop-blur-sm z-[100] cursor-default border-0 p-0"
            />
            <motion.div
              ref={panelRef}
              role="dialog"
              aria-modal="true"
              aria-label="Search"
              initial={{ opacity: 0, scale: 0.96, y: -12 }}
              animate={{ opacity: 1, scale: 1, y: 0 }}
              exit={{ opacity: 0, scale: 0.96, y: -12 }}
              transition={{ type: "spring", stiffness: 400, damping: 32 }}
              className="fixed top-[12%] sm:top-[15%] left-1/2 -translate-x-1/2 w-full max-w-lg z-[101] px-4"
              onMouseDown={(e) => e.stopPropagation()}
              onTouchStart={(e) => e.stopPropagation()}
            >
              <div className="bg-card rounded-xl border border-border shadow-2xl overflow-hidden">
                <div className="flex items-center gap-3 px-4 py-3 border-b border-border">
                  <Search size={16} className="text-muted-foreground shrink-0" aria-hidden />
                  <input
                    ref={inputRef}
                    value={query}
                    onChange={(e) => setQuery(e.target.value)}
                    placeholder="Search courses, dimensions, traits, quarters..."
                    className="flex-1 min-w-0 bg-transparent outline-none text-sm text-foreground placeholder:text-muted-foreground"
                  />
                  {query && (
                    <button
                      type="button"
                      onClick={() => setQuery("")}
                      aria-label="Clear search"
                      className="shrink-0 p-1 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
                    >
                      <X size={14} />
                    </button>
                  )}
                  <button
                    type="button"
                    onClick={closeSearch}
                    aria-label="Close search"
                    className="shrink-0 p-1.5 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted transition-colors"
                  >
                    <X size={16} />
                  </button>
                </div>

                {results.length > 0 && (
                  <div className="max-h-80 overflow-y-auto p-2">
                    {results.map((result, i) => (
                      <motion.button
                        type="button"
                        key={`${result.type}-${result.title}-${i}`}
                        initial={{ opacity: 0, x: -10 }}
                        animate={{ opacity: 1, x: 0 }}
                        transition={{ delay: i * 0.03 }}
                        onClick={() => handleSelect(result)}
                        className="w-full flex items-center gap-3 px-3 py-2.5 rounded-lg hover:bg-muted text-left transition-colors group"
                      >
                        <span className="text-lg shrink-0">{result.emoji}</span>
                        <div className="flex-1 min-w-0">
                          <p className="text-sm font-display font-semibold text-foreground truncate group-hover:text-primary transition-colors">
                            {result.title}
                          </p>
                          <p className="text-xs text-muted-foreground truncate">{result.subtitle}</p>
                        </div>
                        <span className="text-[10px] uppercase tracking-wider text-muted-foreground font-display shrink-0">
                          {result.type}
                        </span>
                      </motion.button>
                    ))}
                  </div>
                )}

                {query && results.length === 0 && (
                  <div className="px-4 py-8 text-center">
                    <p className="text-muted-foreground text-sm">No results for "{query}"</p>
                  </div>
                )}

                {!query && (
                  <div className="px-4 py-6 text-center">
                    <p className="text-muted-foreground text-xs">Type to search across courses, dimensions, traits & quarters</p>
                  </div>
                )}
              </div>
            </motion.div>
          </>
        )}
      </AnimatePresence>
    </>
  );
};
