import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { AhoCorasick } from '@/lib/aho';
import { ListSystemsWithRegions, SetDestinationForAll, ListCharacters, StartESILogin } from 'wailsjs/go/main/App';
import { toast } from '@/hooks/use-toast';

interface SearchResult {
  system: string;
  region: string;
}

async function loadAllSystems(): Promise<Array<SearchResult>> {
  const list = await ListSystemsWithRegions();
  const seen = new Set<string>();
  const out: Array<SearchResult> = [];
  for (const item of list) {
    const system = String(item.system);
    if (seen.has(system)) continue;
    seen.add(system);
    out.push({ system, region: String(item.region) });
  }
  return out;
}

export const SearchDialog: React.FC = () => {
  const navigate = useNavigate();
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState('');
  const [all, setAll] = useState<Array<SearchResult>>([]);
  const [results, setResults] = useState<Array<SearchResult>>([]);
  const inputRef = useRef<HTMLInputElement | null>(null);

  const automaton = useMemo(() => {
    const ac = new AhoCorasick();
    if (query.trim().length > 0) ac.add(query.toLowerCase());
    ac.build();
    return ac;
  }, [query]);

  useEffect(() => {
    const onKeyDown = (e: KeyboardEvent) => {
      const isCtrlF = (e.key === 'f' || e.key === 'F') && (e.ctrlKey || e.metaKey);
      if (isCtrlF) {
        e.preventDefault();
        setOpen(true);
        setTimeout(() => inputRef.current?.focus(), 0);
      }
    };
    window.addEventListener('keydown', onKeyDown);
    return () => window.removeEventListener('keydown', onKeyDown);
  }, []);

  useEffect(() => {
    if (!open) return;
    if (all.length === 0) {
      loadAllSystems().then(setAll);
    }
  }, [open, all.length]);

  useEffect(() => {
    const q = query.trim().toLowerCase();
    if (q.length === 0) { setResults([]); return; }
    const scored: Array<{ s: SearchResult; idx: number }> = [];
    for (const r of all) {
      const idx = automaton.searchFirstIndex(r.system.toLowerCase());
      if (idx >= 0) scored.push({ s: r, idx });
    }
    scored.sort((a, b) => {
      if (a.idx !== b.idx) return a.idx - b.idx; // earlier index first
      if (a.s.system.length !== b.s.system.length) return a.s.system.length - b.s.system.length; // shorter name next
      return a.s.system.localeCompare(b.s.system);
    });
    setResults(scored.slice(0, 10).map(x => x.s));
  }, [query, all, automaton]);

  const onSelect = (r: SearchResult) => {
    setOpen(false);
    setQuery('');
    navigate(`/regions/${encodeURIComponent(r.region)}?focus=${encodeURIComponent(r.system)}`);
  };

  const ensureAnyLoggedIn = async (): Promise<boolean> => {
    try {
      const list = await ListCharacters();
      if (Array.isArray(list) && list.length > 0) return true;
      await StartESILogin();
      toast({ title: 'EVE Login', description: 'Complete login in your browser, then retry.' });
      return false;
    } catch (e: any) {
      await StartESILogin();
      toast({ title: 'EVE Login', description: 'Complete login in your browser, then retry.', variant: 'destructive' });
      return false;
    }
  };

  const handleResultClick = async (e: React.MouseEvent, r: SearchResult) => {
    if (e.shiftKey) {
      e.preventDefault();
      e.stopPropagation();
      try {
        if (!(await ensureAnyLoggedIn())) return;
        await SetDestinationForAll(r.system, true, false);
        toast({ title: 'Destination set', description: r.system });
      } catch (err: any) {
        toast({ title: 'Failed to set destination', description: String(err), variant: 'destructive' });
      } finally {
        setOpen(false);
        setQuery('');
      }
      return;
    }
    onSelect(r);
  };

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogContent className="sm:max-w-lg bg-slate-900/95 border border-purple-500/40 text-white">
        <DialogHeader>
          <DialogTitle>Search systems</DialogTitle>
        </DialogHeader>
        <div className="flex flex-col gap-2">
          <Input
            ref={inputRef}
            placeholder="Type system name..."
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            className="bg-slate-800 border-slate-700 text-white placeholder:text-slate-400"
          />
          <div className="max-h-80 overflow-auto divide-y divide-slate-800 rounded-md border border-slate-800">
            {results.length === 0 && query && (
              <div className="p-3 text-sm text-slate-300">No results</div>
            )}
            {results.map((r, idx) => (
              <button
                key={`${r.region}-${r.system}-${idx}`}
                className="w-full text-left p-3 hover:bg-purple-500/20"
                onClick={(e) => handleResultClick(e, r)}
                title="Click to open, Shift+Click to set destination"
              >
                <div className="text-sm font-medium">{r.system}</div>
                <div className="text-xs text-slate-300">{r.region}</div>
              </button>
            ))}
          </div>
        </div>
      </DialogContent>
    </Dialog>
  );
}; 