import { useState, useCallback, useMemo } from 'react';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { MagnifyingGlass, X, FileText } from '@phosphor-icons/react';
import { FileNode } from './FileTree';

interface SearchResult {
  fileId: string;
  fileName: string;
  line: number;
  content: string;
  matchStart: number;
  matchEnd: number;
}

interface SearchInFilesPanelProps {
  files: FileNode[];
  onFileSelect: (file: FileNode, line?: number) => void;
  isOpen: boolean;
  onClose: () => void;
}

export function SearchInFilesPanel({
  files,
  onFileSelect,
  isOpen,
  onClose,
}: SearchInFilesPanelProps) {
  const [searchQuery, setSearchQuery] = useState('');
  const [results, setResults] = useState<SearchResult[]>([]);
  const [isSearching, setIsSearching] = useState(false);
  const [caseSensitive, setCaseSensitive] = useState(false);

  const searchInFiles = useCallback((query: string) => {
    if (!query.trim()) {
      setResults([]);
      return;
    }

    setIsSearching(true);
    const foundResults: SearchResult[] = [];

    const searchRegex = new RegExp(
      caseSensitive ? query : query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'),
      caseSensitive ? 'g' : 'gi'
    );

    const searchNode = (node: FileNode) => {
      if (node.type === 'file' && node.content) {
        const lines = node.content.split('\n');

        lines.forEach((line, index) => {
          const matches = Array.from(line.matchAll(searchRegex));

          matches.forEach((match) => {
            if (match.index !== undefined) {
              foundResults.push({
                fileId: node.id,
                fileName: node.name,
                line: index + 1,
                content: line.trim(),
                matchStart: match.index,
                matchEnd: match.index + match[0].length,
              });
            }
          });
        });
      }

      if (node.children) {
        node.children.forEach(searchNode);
      }
    };

    files.forEach(searchNode);
    setResults(foundResults);
    setIsSearching(false);
  }, [files, caseSensitive]);

  const handleSearch = useCallback(() => {
    searchInFiles(searchQuery);
  }, [searchInFiles, searchQuery]);

  const handleResultClick = useCallback((result: SearchResult) => {
    const findFile = (nodes: FileNode[]): FileNode | null => {
      for (const node of nodes) {
        if (node.id === result.fileId) return node;
        if (node.children) {
          const found = findFile(node.children);
          if (found) return found;
        }
      }
      return null;
    };

    const file = findFile(files);
    if (file) {
      onFileSelect(file, result.line);
    }
  }, [files, onFileSelect]);

  const highlightMatch = (content: string, start: number, end: number) => {
    return (
      <>
        {content.substring(0, start)}
        <span className="bg-yellow-500/30 text-yellow-200 font-semibold">
          {content.substring(start, end)}
        </span>
        {content.substring(end)}
      </>
    );
  };

  if (!isOpen) return null;

  return (
    <div className="h-[300px] md:h-[400px] bg-card border-t border-border flex flex-col">
      <div className="flex items-center justify-between px-4 py-2 border-b border-border">
        <div className="flex items-center gap-2">
          <MagnifyingGlass size={18} weight="bold" aria-hidden="true" />
          <span className="text-sm font-semibold">Search in Files</span>
          {results.length > 0 && (
            <Badge variant="secondary" className="text-xs" aria-live="polite">
              {results.length} result{results.length !== 1 ? 's' : ''}
            </Badge>
          )}
        </div>
        <Button variant="ghost" size="icon" onClick={onClose} className="h-6 w-6" aria-label="Close search panel">
          <X size={16} aria-hidden="true" />
        </Button>
      </div>

      <div className="px-4 py-3 border-b border-border space-y-2">
        <div className="flex gap-2">
          <Input
            placeholder="Search for text..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === 'Enter') handleSearch();
            }}
            className="flex-1"
            aria-label="Search query"
          />
          <Button onClick={handleSearch} disabled={isSearching || !searchQuery.trim()} aria-label="Search in files">
            <MagnifyingGlass size={16} className="mr-1" aria-hidden="true" />
            Search
          </Button>
        </div>

        <div className="flex items-center gap-2">
          <label className="flex items-center gap-1 text-xs cursor-pointer">
            <input
              type="checkbox"
              checked={caseSensitive}
              onChange={(e) => setCaseSensitive(e.target.checked)}
              className="rounded"
              aria-label="Case sensitive search"
            />
            <span>Case sensitive</span>
          </label>
        </div>
      </div>

      <ScrollArea className="flex-1">
        <div className="px-4 py-2 space-y-1">
          {results.length === 0 && searchQuery && !isSearching && (
            <div className="text-center text-muted-foreground py-8 text-sm">
              No results found for "{searchQuery}"
            </div>
          )}

          {results.length === 0 && !searchQuery && (
            <div className="text-center text-muted-foreground py-8 text-sm">
              Enter a search query to find text across all files
            </div>
          )}

          {results.map((result, index) => (
            <div
              key={`${result.fileId}-${result.line}-${index}`}
              role="button"
              tabIndex={0}
              onClick={() => handleResultClick(result)}
              onKeyDown={(e) => {
                if (e.key === 'Enter' || e.key === ' ') {
                  e.preventDefault();
                  handleResultClick(result);
                }
              }}
              aria-label={`Open ${result.fileName} at line ${result.line}`}
              className="p-2 rounded hover:bg-muted/60 cursor-pointer group transition-colors border border-transparent hover:border-accent/30 focus:outline-none focus:ring-2 focus:ring-accent focus:ring-offset-1"
            >
              <div className="flex items-center gap-2 mb-1">
                <FileText size={14} className="text-muted-foreground flex-shrink-0" />
                <span className="text-xs font-semibold text-accent">
                  {result.fileName}
                </span>
                <span className="text-xs text-muted-foreground">
                  Line {result.line}
                </span>
              </div>
              <div className="text-xs font-mono text-foreground/80 ml-5 truncate">
                {highlightMatch(result.content, result.matchStart, result.matchEnd)}
              </div>
            </div>
          ))}
        </div>
      </ScrollArea>
    </div>
  );
}
