import { FileText, Globe, Search, User } from 'lucide-react';

import { useCallback, useEffect, useState } from 'react';

import { router } from '@inertiajs/react';

import {
  CommandDialog,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/Components/ui/command';

interface SearchResult {
  type: string;
  id: number;
  label: string;
  description: string;
  url: string;
}

interface AdminCommandPaletteProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

const typeIcons: Record<string, typeof User> = {
  user: User,
  site: Globe,
  audit_log: FileText,
};

export function AdminCommandPalette({ open, onOpenChange }: AdminCommandPaletteProps) {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState<SearchResult[]>([]);
  const [isSearching, setIsSearching] = useState(false);

  const search = useCallback(async (q: string) => {
    if (q.length < 2) {
      setResults([]);
      return;
    }

    setIsSearching(true);
    try {
      const response = await fetch(`/admin/search?q=${encodeURIComponent(q)}`, {
        headers: {
          Accept: 'application/json',
          'X-Requested-With': 'XMLHttpRequest',
        },
      });
      if (response.ok) {
        const data = (await response.json()) as { results: SearchResult[] };
        setResults(data.results);
      }
    } finally {
      setIsSearching(false);
    }
  }, []);

  useEffect(() => {
    const timer = setTimeout(() => {
      search(query);
    }, 300);
    return () => clearTimeout(timer);
  }, [query, search]);

  useEffect(() => {
    if (!open) {
      setQuery('');
      setResults([]);
    }
  }, [open]);

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

  const groupLabels: Record<string, string> = {
    user: 'Users',
    site: 'Sites',
    audit_log: 'Audit Logs',
  };

  return (
    <CommandDialog open={open} onOpenChange={onOpenChange}>
      <CommandInput
        placeholder="Search users, sites, audit logs..."
        value={query}
        onValueChange={setQuery}
      />
      <CommandList>
        {isSearching && <CommandEmpty>Searching...</CommandEmpty>}
        {!isSearching && query.length >= 2 && results.length === 0 && (
          <CommandEmpty>No results found.</CommandEmpty>
        )}
        {!isSearching && query.length < 2 && (
          <CommandEmpty>
            <div className="flex flex-col items-center gap-2 py-4">
              <Search className="h-8 w-8 text-muted-foreground" />
              <p className="text-sm text-muted-foreground">
                Type at least 2 characters to search
              </p>
            </div>
          </CommandEmpty>
        )}
        {Object.entries(groupedResults).map(([type, items]) => {
          const Icon = typeIcons[type] ?? FileText;
          return (
            <CommandGroup key={type} heading={groupLabels[type] ?? type}>
              {items.map((result) => (
                <CommandItem
                  key={`${result.type}-${result.id}`}
                  onSelect={() => {
                    onOpenChange(false);
                    router.visit(result.url);
                  }}
                >
                  <Icon className="mr-2 h-4 w-4" />
                  <div className="flex flex-col">
                    <span>{result.label}</span>
                    <span className="text-xs text-muted-foreground">{result.description}</span>
                  </div>
                </CommandItem>
              ))}
            </CommandGroup>
          );
        })}
      </CommandList>
    </CommandDialog>
  );
}
