"use client";

import { useState, useEffect, useCallback, useRef } from "react";
import { useRouter } from "next/navigation";
import {
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
  CommandSeparator,
} from "@/components/ui/command";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover";
import {
  Search,
  LayoutDashboard,
  Activity,
  Calendar,
  Kanban,
  FolderKanban,
  FileText,
  Wrench,
  Target,
  ExternalLink,
  CheckCircle2,
  Clock,
  AlertCircle,
  Timer,
  Circle,
  Filter,
  History,
  X,
  ChevronDown,
} from "lucide-react";
import { siteUrls } from "@/lib/config/sites";
import { cn } from "@/lib/utils";

// Search result type from API - matches SearchableResult interface
type SearchResultType = "task" | "project" | "document" | "sprint";

interface SearchResultHighlight {
  field: string;
  text: string;
  matches: Array<{ start: number; end: number }>;
}

interface SearchResult {
  id: string;
  type: SearchResultType;
  title: string;
  snippet?: string;
  url: string;
  icon: string;
  status?: string;
  color?: string;
  highlights?: SearchResultHighlight[];
  score: number;
  updatedAt?: string;
}

interface SearchFilters {
  types?: SearchResultType[];
  status?: string[];
}

interface SearchHistoryItem {
  query: string;
  filters?: SearchFilters;
  timestamp: number;
  resultCount?: number;
}

const navItems = [
  { name: "Dashboard", href: "/", icon: LayoutDashboard, shortcut: "D" },
  { name: "Activity", href: "/activity", icon: Activity, shortcut: "A" },
  { name: "Calendar", href: "/calendar", icon: Calendar, shortcut: "C" },
  { name: "Tasks", href: "/tasks", icon: Kanban, shortcut: "T" },
  { name: "Projects", href: "/projects", icon: FolderKanban, shortcut: "P" },
  { name: "Documents", href: "/documents", icon: FileText, shortcut: "D" },
  { name: "Tools", href: "/tools", icon: Wrench, shortcut: "O" },
  { name: "Mission", href: "/mission", icon: Target, shortcut: "M" },
];

const quickLinks = [
  { name: "Gantt Board", url: siteUrls.ganttBoard, icon: ExternalLink },
  { name: "Blog Backup", url: siteUrls.blogBackup, icon: ExternalLink },
  { name: "Gitea", url: siteUrls.gitea, icon: ExternalLink },
];

// Icon mapping for search result types
const typeIcons: Record<SearchResultType, React.ElementType> = {
  task: Kanban,
  project: FolderKanban,
  document: FileText,
  sprint: Timer,
};

// Type labels
const typeLabels: Record<SearchResultType, string> = {
  task: "Task",
  project: "Project",
  document: "Document",
  sprint: "Sprint",
};

// Available filters
const typeFilterOptions: { value: SearchResultType; label: string; icon: React.ElementType }[] = [
  { value: "task", label: "Tasks", icon: Kanban },
  { value: "project", label: "Projects", icon: FolderKanban },
  { value: "document", label: "Documents", icon: FileText },
  { value: "sprint", label: "Sprints", icon: Timer },
];

const statusFilterOptions = [
  { value: "open", label: "Open" },
  { value: "in-progress", label: "In Progress" },
  { value: "done", label: "Done" },
  { value: "todo", label: "Todo" },
  { value: "completed", label: "Completed" },
];

function getStatusIcon(status?: string) {
  switch (status) {
    case "done":
    case "completed":
      return <CheckCircle2 className="w-4 h-4 text-green-500" />;
    case "in-progress":
      return <Clock className="w-4 h-4 text-blue-500" />;
    case "open":
    case "todo":
      return <Circle className="w-4 h-4 text-muted-foreground" />;
    default:
      return <AlertCircle className="w-4 h-4 text-muted-foreground" />;
  }
}

// Highlight text component
function HighlightedText({ 
  text, 
  matches, 
  className 
}: { 
  text: string; 
  matches: Array<{ start: number; end: number }>;
  className?: string;
}) {
  if (!matches || matches.length === 0) {
    return <span className={className}>{text}</span>;
  }

  const parts: React.ReactNode[] = [];
  let lastEnd = 0;

  matches.forEach((match, index) => {
    // Add text before match
    if (match.start > lastEnd) {
      parts.push(
        <span key={`text-${index}`}>{text.substring(lastEnd, match.start)}</span>
      );
    }
    // Add highlighted match
    parts.push(
      <mark 
        key={`mark-${index}`} 
        className="bg-yellow-200 dark:bg-yellow-900/50 text-inherit rounded px-0.5"
      >
        {text.substring(match.start, match.end)}
      </mark>
    );
    lastEnd = match.end;
  });

  // Add remaining text
  if (lastEnd < text.length) {
    parts.push(<span key="text-end">{text.substring(lastEnd)}</span>);
  }

  return <span className={className}>{parts}</span>;
}

const SEARCH_HISTORY_KEY = "mission-control-search-history";
const MAX_HISTORY_ITEMS = 10;

export function QuickSearch() {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const [results, setResults] = useState<SearchResult[]>([]);
  const [loading, setLoading] = useState(false);
  const [filters, setFilters] = useState<SearchFilters>({});
  const [showFilters, setShowFilters] = useState(false);
  const [searchHistory, setSearchHistory] = useState<SearchHistoryItem[]>([]);
  const [showHistory, setShowHistory] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);
  const router = useRouter();

  // Load search history from localStorage
  useEffect(() => {
    try {
      const saved = localStorage.getItem(SEARCH_HISTORY_KEY);
      if (saved) {
        const parsed = JSON.parse(saved);
        // Filter out items older than 30 days
        const thirtyDaysAgo = Date.now() - 30 * 24 * 60 * 60 * 1000;
        setSearchHistory(parsed.filter((item: SearchHistoryItem) => item.timestamp > thirtyDaysAgo));
      }
    } catch (e) {
      console.error("Failed to load search history:", e);
    }
  }, []);

  // Save search history to localStorage
  const saveToHistory = useCallback((query: string, resultCount: number, filters?: SearchFilters) => {
    if (!query.trim()) return;
    
    try {
      const newItem: SearchHistoryItem = {
        query: query.trim(),
        filters: Object.keys(filters || {}).length > 0 ? filters : undefined,
        timestamp: Date.now(),
        resultCount,
      };
      
      setSearchHistory(prev => {
        // Remove duplicate queries
        const filtered = prev.filter(item => item.query.toLowerCase() !== query.toLowerCase());
        // Add new item at the beginning
        const updated = [newItem, ...filtered].slice(0, MAX_HISTORY_ITEMS);
        localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(updated));
        return updated;
      });
    } catch (e) {
      console.error("Failed to save search history:", e);
    }
  }, []);

  // Clear search history
  const clearHistory = useCallback(() => {
    localStorage.removeItem(SEARCH_HISTORY_KEY);
    setSearchHistory([]);
  }, []);

  // Remove single history item
  const removeHistoryItem = useCallback((index: number) => {
    setSearchHistory(prev => {
      const updated = prev.filter((_, i) => i !== index);
      localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(updated));
      return updated;
    });
  }, []);

  // Debounced search
  useEffect(() => {
    if (!open || query.length < 2) {
      setResults([]);
      setLoading(false);
      setShowHistory(query.length === 0);
      return;
    }

    setShowHistory(false);
    setLoading(true);
    setResults([]);
    let cancelled = false;
    
    const timer = setTimeout(async () => {
      try {
        const params = new URLSearchParams();
        params.set("q", query);
        if (filters.types?.length) params.set("types", filters.types.join(","));
        if (filters.status?.length) params.set("status", filters.status.join(","));
        
        const res = await fetch(`/api/search?${params.toString()}`);
        if (!res.ok) {
          throw new Error(`Search request failed with status ${res.status}`);
        }
        const data = (await res.json()) as { results?: SearchResult[]; total?: number };
        if (!cancelled) {
          setResults(Array.isArray(data.results) ? data.results : []);
          // Save to history if we got results
          if (data.total && data.total > 0) {
            saveToHistory(query, data.total, filters);
          }
        }
      } catch (err) {
        console.error("Search error:", err);
        if (!cancelled) {
          setResults([]);
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    }, 150); // 150ms debounce

    return () => {
      cancelled = true;
      clearTimeout(timer);
    };
  }, [query, open, filters, saveToHistory]);

  // Keyboard shortcut
  useEffect(() => {
    const down = (e: KeyboardEvent) => {
      if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
        e.preventDefault();
        setOpen((open) => !open);
      }
    };
    document.addEventListener("keydown", down);
    return () => document.removeEventListener("keydown", down);
  }, []);

  const runCommand = useCallback((command: () => void) => {
    setOpen(false);
    setQuery("");
    setShowHistory(false);
    command();
  }, []);

  const handleResultSelect = (result: SearchResult) => {
    runCommand(() => {
      if (result.url?.startsWith("http")) {
        window.open(result.url, "_blank");
      } else if (result.url) {
        router.push(result.url);
      }
    });
  };

  const handleHistorySelect = (item: SearchHistoryItem) => {
    setQuery(item.query);
    if (item.filters) {
      setFilters(item.filters);
    }
    setShowHistory(false);
    // Focus input after selection
    inputRef.current?.focus();
  };

  const toggleTypeFilter = (type: SearchResultType) => {
    setFilters(prev => ({
      ...prev,
      types: prev.types?.includes(type)
        ? prev.types.filter(t => t !== type)
        : [...(prev.types || []), type]
    }));
  };

  const toggleStatusFilter = (status: string) => {
    setFilters(prev => ({
      ...prev,
      status: prev.status?.includes(status)
        ? prev.status.filter(s => s !== status)
        : [...(prev.status || []), status]
    }));
  };

  const clearFilters = () => {
    setFilters({});
  };

  const activeFilterCount = (filters.types?.length || 0) + (filters.status?.length || 0);

  // Group results by type
  const groupedResults = results.reduce((acc, result) => {
    if (!acc[result.type]) acc[result.type] = [];
    acc[result.type].push(result);
    return acc;
  }, {} as Record<SearchResultType, SearchResult[]>);

  // Get ordered list of types that have results
  const activeTypes = (Object.keys(groupedResults) as SearchResultType[]).filter(
    (type) => groupedResults[type]?.length > 0
  );

  // Get title highlight for a result
  const getTitleHighlight = (result: SearchResult) => {
    const titleHighlight = result.highlights?.find(h => h.field === "title");
    if (titleHighlight && titleHighlight.matches.length > 0) {
      return titleHighlight;
    }
    return { text: result.title, matches: [] };
  };

  // Get snippet highlight for a result
  const getSnippetHighlight = (result: SearchResult) => {
    const snippetField = result.type === "sprint" ? "goal" : 
                        result.type === "document" ? "content" : "description";
    return result.highlights?.find(h => h.field === snippetField);
  };

  return (
    <>
      {/* Search Button Trigger */}
      <button
        onClick={() => setOpen(true)}
        className="flex items-center gap-2 px-3 py-1.5 text-sm text-muted-foreground bg-muted hover:bg-muted/80 rounded-md border border-border/50 transition-colors"
        aria-label="Open search (⌘K)"
      >
        <Search className="w-4 h-4" aria-hidden="true" />
        <span className="hidden sm:inline">Search...</span>
        <kbd className="hidden sm:inline-flex h-5 select-none items-center gap-1 rounded border bg-background px-1.5 font-mono text-[10px] font-medium text-muted-foreground" aria-hidden="true">
          <span className="text-xs">⌘</span>K
        </kbd>
      </button>

      {/* Command Dialog */}
      <CommandDialog open={open} onOpenChange={setOpen}>
        <div className="flex items-center gap-2 px-3 border-b">
          <Search className="w-4 h-4 text-muted-foreground shrink-0" />
          <CommandInput 
            ref={inputRef}
            placeholder="Search tasks, projects, sprints, documents..." 
            value={query}
            onValueChange={setQuery}
            className="flex-1 border-0"
          />
          {/* Filter Button */}
          <Popover open={showFilters} onOpenChange={setShowFilters}>
            <PopoverTrigger asChild>
              <Button 
                variant="ghost" 
                size="sm" 
                className={cn(
                  "h-8 gap-1",
                  activeFilterCount > 0 && "bg-primary/10 text-primary"
                )}
              >
                <Filter className="w-4 h-4" />
                {activeFilterCount > 0 && (
                  <Badge variant="secondary" className="h-5 px-1 text-xs">
                    {activeFilterCount}
                  </Badge>
                )}
                <ChevronDown className="w-3 h-3" />
              </Button>
            </PopoverTrigger>
            <PopoverContent className="w-80" align="end">
              <div className="space-y-4">
                <div className="flex items-center justify-between">
                  <h4 className="font-medium text-sm">Filters</h4>
                  {activeFilterCount > 0 && (
                    <Button variant="ghost" size="sm" onClick={clearFilters}>
                      Clear all
                    </Button>
                  )}
                </div>
                
                {/* Type Filters */}
                <div className="space-y-2">
                  <label className="text-xs font-medium text-muted-foreground">Type</label>
                  <div className="flex flex-wrap gap-2">
                    {typeFilterOptions.map(option => {
                      const Icon = option.icon;
                      const isActive = filters.types?.includes(option.value);
                      return (
                        <Button
                          key={option.value}
                          variant={isActive ? "default" : "outline"}
                          size="sm"
                          onClick={() => toggleTypeFilter(option.value)}
                          className="h-7 gap-1"
                        >
                          <Icon className="w-3 h-3" />
                          {option.label}
                        </Button>
                      );
                    })}
                  </div>
                </div>
                
                {/* Status Filters */}
                <div className="space-y-2">
                  <label className="text-xs font-medium text-muted-foreground">Status</label>
                  <div className="flex flex-wrap gap-2">
                    {statusFilterOptions.map(option => {
                      const isActive = filters.status?.includes(option.value);
                      return (
                        <Button
                          key={option.value}
                          variant={isActive ? "default" : "outline"}
                          size="sm"
                          onClick={() => toggleStatusFilter(option.value)}
                          className="h-7"
                        >
                          {option.label}
                        </Button>
                      );
                    })}
                  </div>
                </div>
              </div>
            </PopoverContent>
          </Popover>
        </div>

        <CommandList>
          {/* Search History */}
          {showHistory && searchHistory.length > 0 && !loading && (
            <CommandGroup heading="Recent Searches">
              {searchHistory.slice(0, 5).map((item, index) => (
                <CommandItem
                  key={index}
                  value={`history-${item.query}`}
                  onSelect={() => handleHistorySelect(item)}
                  className="group"
                >
                  <History className="w-4 h-4 mr-2 text-muted-foreground" />
                  <div className="flex flex-col flex-1 min-w-0">
                    <span className="truncate">{item.query}</span>
                    {item.filters && (
                      <span className="text-xs text-muted-foreground">
                        {item.filters.types?.map(t => typeLabels[t]).join(", ")}
                        {item.filters.status && ` • ${item.filters.status.join(", ")}`}
                      </span>
                    )}
                  </div>
                  {item.resultCount !== undefined && (
                    <span className="text-xs text-muted-foreground ml-2">
                      {item.resultCount} results
                    </span>
                  )}
                  <Button
                    variant="ghost"
                    size="icon"
                    className="h-6 w-6 opacity-0 group-hover:opacity-100 ml-2"
                    onClick={(e) => {
                      e.stopPropagation();
                      removeHistoryItem(index);
                    }}
                  >
                    <X className="w-3 h-3" />
                  </Button>
                </CommandItem>
              ))}
              <CommandItem
                onSelect={clearHistory}
                className="text-muted-foreground"
              >
                <X className="w-4 h-4 mr-2" />
                Clear search history
              </CommandItem>
            </CommandGroup>
          )}

          <CommandEmpty>
            {loading ? (
              <div className="flex items-center justify-center py-6">
                <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-primary" />
              </div>
            ) : query.length < 2 ? (
              "Type to search..."
            ) : (
              <div className="py-6 text-center">
                <p>No results found{activeFilterCount > 0 ? " with current filters" : ""}</p>
                {activeFilterCount > 0 && (
                  <Button 
                    variant="link" 
                    size="sm" 
                    onClick={clearFilters}
                    className="mt-2"
                  >
                    Clear filters
                  </Button>
                )}
              </div>
            )}
          </CommandEmpty>

          {/* Show search results when query exists */}
          {query.length >= 2 && activeTypes.length > 0 && (
            <>
              {activeTypes.map((type) => {
                const Icon = typeIcons[type];
                const typeResults = groupedResults[type];
                
                return (
                  <CommandGroup key={type} heading={`${typeLabels[type]}s (${typeResults.length})`}>
                    {typeResults.slice(0, 5).map((result) => {
                      const titleHighlight = getTitleHighlight(result);
                      const snippetHighlight = getSnippetHighlight(result);
                      
                      return (
                        <CommandItem
                          key={`${result.type}-${result.id}`}
                          value={`${result.title} ${result.snippet ?? ""} ${result.status ?? ""} ${typeLabels[result.type]}`}
                          keywords={[query]}
                          onSelect={() => handleResultSelect(result)}
                        >
                          {result.type === "task" ? (
                            getStatusIcon(result.status)
                          ) : result.type === "project" && result.color ? (
                            <div 
                              className="w-3 h-3 rounded-full mr-2" 
                              style={{ backgroundColor: result.color }}
                            />
                          ) : (
                            <Icon className="w-4 h-4 mr-2" />
                          )}
                          
                          <div className="flex flex-col flex-1 min-w-0">
                            <span className="truncate">
                              <HighlightedText 
                                text={titleHighlight.text} 
                                matches={titleHighlight.matches}
                              />
                            </span>
                            {snippetHighlight && (
                              <span className="text-xs text-muted-foreground truncate">
                                <HighlightedText 
                                  text={snippetHighlight.text} 
                                  matches={snippetHighlight.matches}
                                />
                              </span>
                            )}
                          </div>
                          
                          {result.status && result.type !== "task" && (
                            <span className="text-xs text-muted-foreground ml-2 capitalize">
                              {result.status}
                            </span>
                          )}
                        </CommandItem>
                      );
                    })}
                  </CommandGroup>
                );
              })}
              <CommandSeparator />
            </>
          )}

          {/* Navigation */}
          <CommandGroup heading="Navigation">
            {navItems.map((item) => {
              const Icon = item.icon;
              return (
                <CommandItem
                  key={item.href}
                  onSelect={() => runCommand(() => router.push(item.href))}
                >
                  <Icon className="w-4 h-4 mr-2" />
                  <span>{item.name}</span>
                </CommandItem>
              );
            })}
          </CommandGroup>

          <CommandSeparator />

          {/* Quick Links */}
          <CommandGroup heading="Quick Links">
            {quickLinks.map((link) => {
              const Icon = link.icon;
              return (
                <CommandItem
                  key={link.url}
                  onSelect={() => runCommand(() => window.open(link.url, "_blank"))}
                >
                  <Icon className="w-4 h-4 mr-2" />
                  <span>{link.name}</span>
                </CommandItem>
              );
            })}
          </CommandGroup>
        </CommandList>
      </CommandDialog>
    </>
  );
}
