'use client';

import { useEffect, useId, useMemo, useRef, useState } from 'react';

export type PlayerResult = {
  id: string;
  full_name: string;
  team?: string;
  position?: string;
  headshot_url?: string;
};

export type Sport = 'NBA' | 'MLB' | 'WNBA';

type Props = {
  sport: Sport;
  gameId?: string;
  placeholder?: string;
  initialValue?: string;
  onSelect: (player: PlayerResult) => void;
  autoFocus?: boolean;
};

const SPORT_TINT: Record<Sport, string> = {
  NBA: 'var(--nba)',
  MLB: 'var(--mlb)',
  WNBA: 'var(--wnba)',
};

export default function PlayerSearch({
  sport,
  gameId,
  placeholder = 'Search players…',
  initialValue = '',
  onSelect,
  autoFocus = false,
}: Props) {
  const [query, setQuery] = useState(initialValue);
  const [results, setResults] = useState<PlayerResult[] | null>(null);
  const [loading, setLoading] = useState(false);
  const [highlight, setHighlight] = useState(0);
  const [open, setOpen] = useState(false);
  const inputId = useId();
  const listboxId = `${inputId}-listbox`;
  const containerRef = useRef<HTMLDivElement>(null);
  const abortRef = useRef<AbortController | null>(null);

  // Debounced fetch
  useEffect(() => {
    const q = query.trim();
    if (q.length < 2) {
      setResults(null);
      setLoading(false);
      return;
    }
    setLoading(true);
    abortRef.current?.abort();
    const ctrl = new AbortController();
    abortRef.current = ctrl;
    const t = setTimeout(async () => {
      try {
        const params = new URLSearchParams({ sport, q });
        if (gameId) params.set('game_id', gameId);
        const res = await fetch(`/api/players/search?${params.toString()}`, { signal: ctrl.signal });
        const data = await res.json().catch(() => ({}));
        if (!ctrl.signal.aborted) {
          setResults(Array.isArray(data?.players) ? data.players.slice(0, 5) : []);
          setHighlight(0);
        }
      } catch {
        if (!ctrl.signal.aborted) setResults([]);
      } finally {
        if (!ctrl.signal.aborted) setLoading(false);
      }
    }, 220);
    return () => {
      clearTimeout(t);
      ctrl.abort();
    };
  }, [query, sport, gameId]);

  // Close on outside click
  useEffect(() => {
    const onClick = (e: MouseEvent) => {
      if (!containerRef.current?.contains(e.target as Node)) setOpen(false);
    };
    document.addEventListener('mousedown', onClick);
    return () => document.removeEventListener('mousedown', onClick);
  }, []);

  const noResults = useMemo(
    () => !loading && results !== null && results.length === 0 && query.trim().length >= 2,
    [loading, results, query],
  );

  const choose = (p: PlayerResult) => {
    onSelect(p);
    setQuery(p.full_name);
    setOpen(false);
  };

  const onKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (!results || results.length === 0) return;
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      setOpen(true);
      setHighlight((h) => Math.min(results.length - 1, h + 1));
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      setHighlight((h) => Math.max(0, h - 1));
    } else if (e.key === 'Enter') {
      e.preventDefault();
      const sel = results[highlight];
      if (sel) choose(sel);
    } else if (e.key === 'Escape') {
      setOpen(false);
    }
  };

  return (
    <div ref={containerRef} style={{ position: 'relative' }}>
      <input
        id={inputId}
        role="combobox"
        aria-controls={listboxId}
        aria-expanded={open && (loading || !!results?.length || noResults)}
        aria-autocomplete="list"
        aria-activedescendant={results && results[highlight] ? `${inputId}-opt-${highlight}` : undefined}
        autoComplete="off"
        autoFocus={autoFocus}
        placeholder={placeholder}
        className="input-field"
        value={query}
        onFocus={() => setOpen(true)}
        onChange={(e) => { setQuery(e.target.value); setOpen(true); }}
        onKeyDown={onKeyDown}
        style={{ width: '100%' }}
      />

      {open && (loading || results !== null) && (
        <ul
          id={listboxId}
          role="listbox"
          className="surface-elevated"
          style={{
            position: 'absolute',
            top: 'calc(100% + 6px)',
            left: 0,
            right: 0,
            zIndex: 30,
            margin: 0,
            padding: 4,
            listStyle: 'none',
            maxHeight: 280,
            overflowY: 'auto',
          }}
        >
          {loading && (
            <li style={{ padding: 12 }}>
              <span className="lbl" style={{ color: 'var(--text-1)' }}>SEARCHING…</span>
            </li>
          )}

          {!loading && noResults && (
            <li style={{ padding: 12 }}>
              <p style={{ fontSize: 14, color: 'var(--text-0)', margin: 0 }}>
                No players found for &quot;{query}&quot;.
              </p>
              <p style={{ fontSize: 12, color: 'var(--text-1)', margin: '4px 0 0' }}>Check spelling.</p>
            </li>
          )}

          {!loading && results && results.map((p, i) => {
            const active = i === highlight;
            return (
              <li
                key={p.id}
                id={`${inputId}-opt-${i}`}
                role="option"
                aria-selected={active}
                onMouseDown={(e) => { e.preventDefault(); choose(p); }}
                onMouseEnter={() => setHighlight(i)}
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: 12,
                  padding: '10px 12px',
                  borderRadius: 8,
                  background: active ? 'var(--bg-2)' : 'transparent',
                  cursor: 'pointer',
                }}
              >
                <span
                  aria-hidden
                  style={{
                    width: 24, height: 24, borderRadius: 999,
                    background: 'var(--bg-3)',
                    border: `1px solid ${SPORT_TINT[sport]}`,
                    display: 'inline-flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    fontSize: 10,
                    fontFamily: 'var(--font-mono, "IBM Plex Mono")',
                    fontWeight: 700,
                    color: 'var(--text-1)',
                  }}
                >
                  {p.full_name.split(' ').map((n) => n[0]).slice(0, 2).join('')}
                </span>
                <span style={{ flex: 1, color: 'var(--text-0)', fontSize: 14, fontWeight: 600 }}>
                  {p.full_name}
                </span>
                {p.team ? (
                  <span className="mono" style={{ fontSize: 11, color: 'var(--text-1)' }}>{p.team}</span>
                ) : null}
                <span
                  className="pill"
                  style={{
                    color: SPORT_TINT[sport],
                    background: 'transparent',
                    border: `1px solid ${SPORT_TINT[sport]}`,
                  }}
                >
                  {sport}
                </span>
              </li>
            );
          })}
        </ul>
      )}
    </div>
  );
}
