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

export interface CpvHit {
  code: string;
  label: string;
  level: number;
  division: string;
  emoji: string | null;
  count: number;
}

interface Props {
  /** Optional initial CPV code (8 digits) — used to label the chip. */
  value?: string | null;
  /** Optional initial label for the current code (avoids a round-trip). */
  valueLabel?: string | null;
  /** Hidden form field name (so an enclosing <form> can submit it). Default 'cpv'. */
  name?: string;
  /** Placeholder for the input. */
  placeholder?: string;
}

const fmt = new Intl.NumberFormat('ro-RO');

export default function CpvAutocomplete({
  value: initialValue,
  valueLabel: initialLabel,
  name = 'cpv',
  placeholder = 'caută CPV: cod (45000000) sau cuvânt cheie (construcții, medical, alimente…)',
}: Props) {
  const reactId = useId();
  const listboxId = `cpv-listbox-${reactId.replace(/:/g, '-')}`;
  const optionId = (i: number) => `cpv-opt-${reactId.replace(/:/g, '-')}-${i}`;

  const [query, setQuery] = useState('');
  const [open, setOpen] = useState(false);
  const [hits, setHits] = useState<CpvHit[]>([]);
  const [loading, setLoading] = useState(false);
  const [activeIdx, setActiveIdx] = useState(-1);
  const [selected, setSelected] = useState<{ code: string; label: string } | null>(
    initialValue ? { code: initialValue, label: initialLabel || initialValue } : null,
  );

  const inputRef = useRef<HTMLInputElement>(null);
  const wrapperRef = useRef<HTMLDivElement>(null);
  const abortRef = useRef<AbortController | null>(null);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  // Debounced fetch
  useEffect(() => {
    if (debounceRef.current) clearTimeout(debounceRef.current);
    const q = query.trim();
    if (q.length < 2) {
      setHits([]);
      setLoading(false);
      setActiveIdx(-1);
      return;
    }
    setLoading(true);
    debounceRef.current = setTimeout(async () => {
      abortRef.current?.abort();
      const ac = new AbortController();
      abortRef.current = ac;
      try {
        const res = await fetch(`/api/cpv/search?q=${encodeURIComponent(q)}`, {
          signal: ac.signal,
        });
        if (!res.ok) {
          setHits([]);
          setLoading(false);
          return;
        }
        const data = (await res.json()) as CpvHit[];
        setHits(data);
        setActiveIdx(data.length > 0 ? 0 : -1);
      } catch (e) {
        if ((e as { name?: string }).name !== 'AbortError') {
          setHits([]);
        }
      } finally {
        setLoading(false);
      }
    }, 250);
    return () => {
      if (debounceRef.current) clearTimeout(debounceRef.current);
    };
  }, [query]);

  // Click-outside to close
  useEffect(() => {
    function onDocClick(e: MouseEvent) {
      if (!wrapperRef.current) return;
      if (!wrapperRef.current.contains(e.target as Node)) setOpen(false);
    }
    document.addEventListener('mousedown', onDocClick);
    return () => document.removeEventListener('mousedown', onDocClick);
  }, []);

  function pick(hit: CpvHit) {
    setSelected({ code: hit.code, label: hit.label });
    setQuery('');
    setHits([]);
    setOpen(false);
    setActiveIdx(-1);
    // Notify the page so it can update the URL / submit a form.
    document.dispatchEvent(
      new CustomEvent('cpv:selected', {
        detail: { code: hit.code, label: hit.label, level: hit.level, count: hit.count },
      }),
    );
  }

  function clearSelection() {
    setSelected(null);
    document.dispatchEvent(
      new CustomEvent('cpv:selected', { detail: { code: null, label: null } }),
    );
    requestAnimationFrame(() => inputRef.current?.focus());
  }

  function onKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {
    if (!open && (e.key === 'ArrowDown' || e.key === 'ArrowUp')) {
      setOpen(true);
      return;
    }
    if (e.key === 'ArrowDown') {
      e.preventDefault();
      setActiveIdx((i) => Math.min(hits.length - 1, i + 1));
    } else if (e.key === 'ArrowUp') {
      e.preventDefault();
      setActiveIdx((i) => Math.max(0, i - 1));
    } else if (e.key === 'Enter') {
      if (activeIdx >= 0 && hits[activeIdx]) {
        e.preventDefault();
        pick(hits[activeIdx]);
      }
    } else if (e.key === 'Escape') {
      setOpen(false);
    }
  }

  const showDropdown = open && (loading || hits.length > 0 || query.trim().length >= 2);

  const dropdownItems = useMemo(() => hits, [hits]);

  return (
    <div
      ref={wrapperRef}
      className="cpv-autocomplete"
      style={{ position: 'relative' }}
    >
      {/* Hidden field so an enclosing <form> can submit the current code. */}
      <input type="hidden" name={name} value={selected?.code ?? ''} />

      {selected ? (
        <div
          className="cpv-selected"
          style={{
            display: 'flex',
            alignItems: 'center',
            gap: 8,
            padding: '8px 10px',
            border: '1px solid var(--rule, #E2E8F0)',
            background: 'var(--rule-soft, #F1F5F9)',
            borderRadius: 10,
            fontSize: 13,
          }}
        >
          <span
            className="font-mono"
            style={{
              fontSize: 11,
              padding: '2px 6px',
              background: 'var(--ink, #0F172A)',
              color: 'var(--paper, #FFFFFF)',
              borderRadius: 4,
              letterSpacing: '0.04em',
            }}
          >
            {selected.code}
          </span>
          <span style={{ flex: 1, minWidth: 0, color: 'var(--ink, #0F172A)' }}>
            {selected.label}
          </span>
          <button
            type="button"
            onClick={clearSelection}
            aria-label="Elimină filtrul CPV"
            style={{
              border: '1px solid var(--rule, #E2E8F0)',
              background: 'var(--paper, #FFFFFF)',
              color: 'var(--meta, #64748B)',
              padding: '2px 7px',
              borderRadius: 4,
              cursor: 'pointer',
              fontSize: 11,
            }}
          >
            × elimină
          </button>
        </div>
      ) : (
        <>
          <div
            role="combobox"
            aria-expanded={showDropdown}
            aria-haspopup="listbox"
            aria-owns={showDropdown ? listboxId : undefined}
            aria-controls={showDropdown ? listboxId : undefined}
            style={{ position: 'relative' }}
          >
            <input
              ref={inputRef}
              type="text"
              value={query}
              placeholder={placeholder}
              autoComplete="off"
              spellCheck={false}
              role="searchbox"
              aria-autocomplete="list"
              aria-activedescendant={
                showDropdown && activeIdx >= 0 ? optionId(activeIdx) : undefined
              }
              onChange={(e) => {
                setQuery(e.target.value);
                setOpen(true);
              }}
              onFocus={() => setOpen(true)}
              onKeyDown={onKeyDown}
              style={{
                width: '100%',
                fontFamily: 'Inter, system-ui, sans-serif',
                fontSize: 13,
                padding: '9px 32px 9px 12px',
                border: '1px solid var(--rule, #E2E8F0)',
                background: 'var(--paper, #FFFFFF)',
                color: 'var(--ink, #0F172A)',
                borderRadius: 10,
                outline: 'none',
              }}
            />
            {loading && (
              <span
                aria-hidden="true"
                style={{
                  position: 'absolute',
                  right: 10,
                  top: '50%',
                  transform: 'translateY(-50%)',
                  fontSize: 10,
                  color: 'var(--meta, #64748B)',
                  fontFamily: 'JetBrains Mono, monospace',
                  letterSpacing: '0.06em',
                }}
              >
                …
              </span>
            )}
          </div>

          {showDropdown && (
            <ul
              id={listboxId}
              role="listbox"
              aria-label="Rezultate CPV"
              style={{
                position: 'absolute',
                top: 'calc(100% + 4px)',
                left: 0,
                right: 0,
                maxHeight: 360,
                overflowY: 'auto',
                margin: 0,
                padding: 0,
                listStyle: 'none',
                background: 'var(--paper, #FFFFFF)',
                border: '1px solid var(--ink, #0F172A)',
                borderRadius: 10,
                boxShadow: '0 8px 24px rgba(15, 23, 42, 0.12)',
                zIndex: 50,
              }}
            >
              {dropdownItems.length === 0 && !loading && (
                <li
                  style={{
                    padding: '12px 14px',
                    fontSize: 13,
                    color: 'var(--meta, #64748B)',
                    fontStyle: 'italic',
                  }}
                >
                  Niciun cod CPV care să se potrivească.
                </li>
              )}
              {dropdownItems.map((h, i) => {
                const active = i === activeIdx;
                return (
                  <li
                    key={h.code}
                    id={optionId(i)}
                    role="option"
                    aria-selected={active}
                    onMouseDown={(e) => {
                      // Prevent input blur before click handler runs.
                      e.preventDefault();
                      pick(h);
                    }}
                    onMouseEnter={() => setActiveIdx(i)}
                    style={{
                      display: 'grid',
                      gridTemplateColumns: 'auto 1fr auto',
                      alignItems: 'center',
                      gap: 10,
                      padding: '9px 12px',
                      borderBottom: '1px solid var(--rule-soft, #F1F5F9)',
                      cursor: 'pointer',
                      background: active ? 'var(--stamp-soft, #DBEAFE)' : 'transparent',
                      color: 'var(--ink, #0F172A)',
                      fontSize: 13,
                      lineHeight: 1.35,
                    }}
                  >
                    <span
                      style={{
                        fontFamily: 'JetBrains Mono, monospace',
                        fontSize: 11,
                        padding: '2px 6px',
                        background: active ? 'var(--stamp, #2563EB)' : 'var(--ink, #0F172A)',
                        color: 'var(--paper, #FFFFFF)',
                        borderRadius: 4,
                        letterSpacing: '0.04em',
                      }}
                    >
                      {h.code}
                    </span>
                    <span style={{ minWidth: 0, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                      {h.emoji && <span style={{ marginRight: 6 }}>{h.emoji}</span>}
                      {h.label}
                    </span>
                    <span
                      style={{
                        fontFamily: 'JetBrains Mono, monospace',
                        fontSize: 11,
                        color: active ? 'var(--ink, #0F172A)' : 'var(--meta, #64748B)',
                        fontVariantNumeric: 'tabular-nums',
                        whiteSpace: 'nowrap',
                      }}
                    >
                      {h.count > 0 ? `${fmt.format(h.count)} ann.` : '—'}
                    </span>
                  </li>
                );
              })}
              {loading && dropdownItems.length === 0 && (
                <li
                  style={{
                    padding: '12px 14px',
                    fontSize: 12,
                    color: 'var(--meta, #64748B)',
                    fontFamily: 'JetBrains Mono, monospace',
                    letterSpacing: '0.04em',
                    textTransform: 'uppercase',
                  }}
                >
                  caut…
                </li>
              )}
            </ul>
          )}
        </>
      )}
    </div>
  );
}
