import { useEffect, useMemo, useRef, useState } from 'react';
import { cn } from '@/lib/utils';

interface Props {
  query: string;
  files: string[];
  anchorRect: { top: number; left: number };
  onSelect: (path: string) => void;
  onClose: () => void;
}

function filterAndRank(files: string[], query: string): string[] {
  const q = query.toLowerCase();
  if (!q) {
    return files.slice(0, 20);
  }

  const filenameMatches: string[] = [];
  const pathOnlyMatches: string[] = [];

  for (const file of files) {
    const lower = file.toLowerCase();
    if (!lower.includes(q)) continue;
    const basename = file.split('/').pop() ?? file;
    if (basename.toLowerCase().includes(q)) {
      filenameMatches.push(file);
    } else {
      pathOnlyMatches.push(file);
    }
  }

  filenameMatches.sort((a, b) => a.localeCompare(b));
  pathOnlyMatches.sort((a, b) => a.localeCompare(b));

  return [...filenameMatches, ...pathOnlyMatches].slice(0, 20);
}

export function FileMentionPopover({
  query,
  files,
  anchorRect,
  onSelect,
  onClose,
}: Props) {
  const [highlightIndex, setHighlightIndex] = useState(0);
  const popoverRef = useRef<HTMLDivElement>(null);
  const filtered = useMemo(() => filterAndRank(files, query), [files, query]);

  // Reset highlight when query changes
  useEffect(() => {
    setHighlightIndex(0);
  }, [query]);

  // Keyboard navigation
  useEffect(() => {
    function handleKeyDown(e: KeyboardEvent) {
      if (e.key === 'ArrowDown') {
        e.preventDefault();
        setHighlightIndex(prev =>
          prev < filtered.length - 1 ? prev + 1 : 0
        );
      } else if (e.key === 'ArrowUp') {
        e.preventDefault();
        setHighlightIndex(prev =>
          prev > 0 ? prev - 1 : filtered.length - 1
        );
      } else if (e.key === 'Enter') {
        e.preventDefault();
        if (filtered.length > 0) {
          onSelect(filtered[highlightIndex] ?? filtered[0]!);
        }
      } else if (e.key === 'Escape') {
        e.preventDefault();
        onClose();
      }
    }

    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [filtered, highlightIndex, onSelect, onClose]);

  // Click outside to close
  useEffect(() => {
    function handleMouseDown(e: MouseEvent) {
      if (
        popoverRef.current &&
        !popoverRef.current.contains(e.target as Node)
      ) {
        onClose();
      }
    }

    document.addEventListener('mousedown', handleMouseDown);
    return () => document.removeEventListener('mousedown', handleMouseDown);
  }, [onClose]);

  // Scroll highlighted item into view
  useEffect(() => {
    const el = popoverRef.current?.querySelector('[data-highlighted="true"]');
    if (el) {
      el.scrollIntoView({ block: 'nearest' });
    }
  }, [highlightIndex]);

  if (filtered.length === 0) {
    return (
      <div
        ref={popoverRef}
        className="fixed z-50 bg-popover border border-border rounded-md shadow min-w-[260px] p-2"
        style={{ top: anchorRect.top, left: anchorRect.left }}
      >
        <div className="text-xs text-muted-foreground px-2 py-1">
          No matching files
        </div>
      </div>
    );
  }

  return (
    <div
      ref={popoverRef}
      className="fixed z-50 bg-popover border border-border rounded-md shadow min-w-[260px] max-h-[240px] overflow-y-auto"
      style={{ top: anchorRect.top, left: anchorRect.left }}
    >
      {filtered.map((file, i) => (
        <button
          key={file}
          type="button"
          data-highlighted={i === highlightIndex}
          className={cn(
            'w-full text-left text-xs font-mono px-2 py-1.5 cursor-pointer',
            i === highlightIndex && 'bg-muted'
          )}
          onMouseEnter={() => setHighlightIndex(i)}
          onMouseDown={(e) => {
            e.preventDefault();
            onSelect(file);
          }}
        >
          {file}
        </button>
      ))}
    </div>
  );
}
