import { useEffect, useRef, useState } from 'react';
import type { SearchAddon } from '@xterm/addon-search';
import { ChevronDown, ChevronUp, X } from 'lucide-react';
import { type TermTheme } from './theme';

interface SearchBarProps {
  searchRef: React.MutableRefObject<SearchAddon | null>;
  theme: TermTheme;
  onClose: () => void;
}
export function SearchBar({ searchRef, theme, onClose }: SearchBarProps) {
  const [q, setQ] = useState('');
  const [counts, setCounts] = useState<{ idx: number; total: number }>({ idx: -1, total: 0 });
  const inputRef = useRef<HTMLInputElement | null>(null);
  useEffect(() => {
    inputRef.current?.focus();
  }, []);
  useEffect(() => {
    const addon = searchRef.current;
    if (!addon) return;
    const sub = addon.onDidChangeResults(({ resultIndex, resultCount }) => {
      setCounts({ idx: resultIndex, total: resultCount });
    });
    return () => sub.dispose();
  }, [searchRef]);
  useEffect(() => {
    const addon = searchRef.current;
    if (!addon) return;
    if (q.length === 0) {
      addon.clearDecorations?.();
      setCounts({ idx: -1, total: 0 });
      return;
    }
    addon.findNext(q, {
      incremental: true,
      decorations: {
        matchBackground: theme.selectionBackground,
        matchOverviewRuler: theme.cursor,
        activeMatchBackground: theme.cursor,
        activeMatchColorOverviewRuler: theme.cursor,
      },
    });
  }, [q, searchRef, theme]);

  function findNext(): void {
    if (!q) return;
    searchRef.current?.findNext(q);
  }
  function findPrev(): void {
    if (!q) return;
    searchRef.current?.findPrevious(q);
  }
  function onKey(ev: React.KeyboardEvent<HTMLInputElement>): void {
    if (ev.key === 'Escape') {
      ev.preventDefault();
      onClose();
      return;
    }
    if (ev.key === 'Enter') {
      ev.preventDefault();
      if (ev.shiftKey) findPrev();
      else findNext();
    }
  }

  return (
    <div
      style={{
        position: 'absolute',
        top: 8,
        right: 8,
        background: '#1a1d24',
        border: '1px solid #2a2d34',
        borderRadius: 8,
        padding: 4,
        display: 'flex',
        alignItems: 'center',
        gap: 4,
        boxShadow: '0 4px 12px rgba(0,0,0,0.4)',
        zIndex: 40,
      }}
    >
      <input
        ref={inputRef}
        value={q}
        onChange={(ev) => setQ(ev.target.value)}
        onKeyDown={onKey}
        placeholder="Search…"
        style={{
          background: 'transparent',
          border: 0,
          outline: 'none',
          color: '#d6deeb',
          padding: '8px 8px',
          fontSize: 13,
          width: 160,
          minHeight: 36,
        }}
      />
      {q.length > 0 && (
        <span
          style={{
            fontSize: 11,
            color: counts.total === 0 ? '#ef5350' : '#575656',
            minWidth: 56,
            textAlign: 'right',
            padding: '0 4px',
            whiteSpace: 'nowrap',
          }}
        >
          {counts.total === 0
            ? 'No match'
            : counts.idx === -1
              ? `${counts.total}+`
              : `${counts.idx + 1} of ${counts.total}`}
        </span>
      )}
      <button
        type="button"
        onClick={findPrev}
        aria-label="Previous match"
        title="Previous (Shift+Enter)"
        style={iconBtnStyle}
      >
        <ChevronUp size={16} />
      </button>
      <button
        type="button"
        onClick={findNext}
        aria-label="Next match"
        title="Next (Enter)"
        style={iconBtnStyle}
      >
        <ChevronDown size={16} />
      </button>
      <button
        type="button"
        onClick={onClose}
        aria-label="Close search"
        title="Close (Esc)"
        style={iconBtnStyle}
      >
        <X size={16} />
      </button>
    </div>
  );
}

const iconBtnStyle: React.CSSProperties = {
  display: 'inline-flex',
  alignItems: 'center',
  justifyContent: 'center',
  width: 44,
  height: 44,
  background: 'transparent',
  border: 0,
  color: '#d6deeb',
  cursor: 'pointer',
  borderRadius: 6,
};
