import { useState, useEffect, useRef, useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import { globalSearch } from '../api';
import { GlobalSearchResponse } from '../types';
import './GlobalSearch.css';

export function GlobalSearch() {
  const navigate = useNavigate();
  const [query, setQuery] = useState('');
  const [results, setResults] = useState<GlobalSearchResponse | null>(null);
  const [loading, setLoading] = useState(false);
  const [isOpen, setIsOpen] = useState(false);
  const [selectedIndex, setSelectedIndex] = useState(-1);
  const inputRef = useRef<HTMLInputElement>(null);
  const containerRef = useRef<HTMLDivElement>(null);

  // Build flat list of results for keyboard navigation
  const flatResults = results
    ? [
        ...results.projects.map((p) => ({ type: 'project' as const, item: p })),
        ...results.packages.map((p) => ({ type: 'package' as const, item: p })),
        ...results.artifacts.map((a) => ({ type: 'artifact' as const, item: a })),
      ]
    : [];

  const handleSearch = useCallback(async (searchQuery: string) => {
    if (!searchQuery.trim()) {
      setResults(null);
      setIsOpen(false);
      return;
    }

    setLoading(true);
    try {
      const data = await globalSearch(searchQuery);
      setResults(data);
      setIsOpen(true);
      setSelectedIndex(-1);
    } catch (err) {
      console.error('Search failed:', err);
      setResults(null);
    } finally {
      setLoading(false);
    }
  }, []);

  // Debounced search
  useEffect(() => {
    const timer = setTimeout(() => {
      handleSearch(query);
    }, 300);

    return () => clearTimeout(timer);
  }, [query, handleSearch]);

  // Close on click outside
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (containerRef.current && !containerRef.current.contains(event.target as Node)) {
        setIsOpen(false);
      }
    }

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

  // Keyboard navigation
  useEffect(() => {
    function handleKeyDown(event: KeyboardEvent) {
      if (event.key === '/' && !['INPUT', 'TEXTAREA'].includes((event.target as HTMLElement).tagName)) {
        event.preventDefault();
        inputRef.current?.focus();
      }

      if (!isOpen) return;

      switch (event.key) {
        case 'ArrowDown':
          event.preventDefault();
          setSelectedIndex((prev) => Math.min(prev + 1, flatResults.length - 1));
          break;
        case 'ArrowUp':
          event.preventDefault();
          setSelectedIndex((prev) => Math.max(prev - 1, -1));
          break;
        case 'Enter':
          if (selectedIndex >= 0 && flatResults[selectedIndex]) {
            event.preventDefault();
            navigateToResult(flatResults[selectedIndex]);
          }
          break;
        case 'Escape':
          setIsOpen(false);
          inputRef.current?.blur();
          break;
      }
    }

    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [isOpen, selectedIndex, flatResults]);

  function navigateToResult(result: (typeof flatResults)[0]) {
    setIsOpen(false);
    setQuery('');

    switch (result.type) {
      case 'project':
        navigate(`/project/${result.item.name}`);
        break;
      case 'package':
        navigate(`/project/${result.item.project_name}/${result.item.name}`);
        break;
      case 'artifact':
        navigate(`/project/${result.item.project_name}/${result.item.package_name}`);
        break;
    }
  }

  const hasResults = results && results.counts.total > 0;

  return (
    <div className="global-search" ref={containerRef}>
      <div className="global-search__input-wrapper">
        <svg
          className="global-search__icon"
          width="16"
          height="16"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          strokeWidth="2"
        >
          <circle cx="11" cy="11" r="8" />
          <line x1="21" y1="21" x2="16.65" y2="16.65" />
        </svg>
        <input
          ref={inputRef}
          type="text"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          onFocus={() => query && results && setIsOpen(true)}
          placeholder="Search projects, packages, artifacts..."
          className="global-search__input"
        />
        <kbd className="global-search__shortcut">/</kbd>
        {loading && <span className="global-search__spinner" />}
      </div>

      {isOpen && (
        <div className="global-search__dropdown">
          {!hasResults && query && (
            <div className="global-search__empty">No results found for "{query}"</div>
          )}

          {hasResults && (
            <>
              {results.projects.length > 0 && (
                <div className="global-search__section">
                  <div className="global-search__section-header">
                    Projects
                    <span className="global-search__count">{results.counts.projects}</span>
                  </div>
                  {results.projects.map((project, index) => {
                    const flatIndex = index;
                    return (
                      <button
                        key={project.id}
                        className={`global-search__result ${selectedIndex === flatIndex ? 'selected' : ''}`}
                        onClick={() => navigateToResult({ type: 'project', item: project })}
                        onMouseEnter={() => setSelectedIndex(flatIndex)}
                      >
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                          <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z" />
                        </svg>
                        <div className="global-search__result-content">
                          <span className="global-search__result-name">{project.name}</span>
                          {project.description && (
                            <span className="global-search__result-desc">{project.description}</span>
                          )}
                        </div>
                        <span className={`global-search__badge ${project.is_public ? 'public' : 'private'}`}>
                          {project.is_public ? 'Public' : 'Private'}
                        </span>
                      </button>
                    );
                  })}
                </div>
              )}

              {results.packages.length > 0 && (
                <div className="global-search__section">
                  <div className="global-search__section-header">
                    Packages
                    <span className="global-search__count">{results.counts.packages}</span>
                  </div>
                  {results.packages.map((pkg, index) => {
                    const flatIndex = results.projects.length + index;
                    return (
                      <button
                        key={pkg.id}
                        className={`global-search__result ${selectedIndex === flatIndex ? 'selected' : ''}`}
                        onClick={() => navigateToResult({ type: 'package', item: pkg })}
                        onMouseEnter={() => setSelectedIndex(flatIndex)}
                      >
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                          <path d="M16.5 9.4l-9-5.19M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
                          <polyline points="3.27 6.96 12 12.01 20.73 6.96" />
                          <line x1="12" y1="22.08" x2="12" y2="12" />
                        </svg>
                        <div className="global-search__result-content">
                          <span className="global-search__result-name">{pkg.name}</span>
                          <span className="global-search__result-path">{pkg.project_name}</span>
                          {pkg.description && (
                            <span className="global-search__result-desc">{pkg.description}</span>
                          )}
                        </div>
                        <span className="global-search__badge format">{pkg.format}</span>
                      </button>
                    );
                  })}
                </div>
              )}

              {results.artifacts.length > 0 && (
                <div className="global-search__section">
                  <div className="global-search__section-header">
                    Artifacts / Tags
                    <span className="global-search__count">{results.counts.artifacts}</span>
                  </div>
                  {results.artifacts.map((artifact, index) => {
                    const flatIndex = results.projects.length + results.packages.length + index;
                    return (
                      <button
                        key={artifact.tag_id}
                        className={`global-search__result ${selectedIndex === flatIndex ? 'selected' : ''}`}
                        onClick={() => navigateToResult({ type: 'artifact', item: artifact })}
                        onMouseEnter={() => setSelectedIndex(flatIndex)}
                      >
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                          <path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z" />
                          <line x1="7" y1="7" x2="7.01" y2="7" />
                        </svg>
                        <div className="global-search__result-content">
                          <span className="global-search__result-name">{artifact.tag_name}</span>
                          <span className="global-search__result-path">
                            {artifact.project_name} / {artifact.package_name}
                          </span>
                          {artifact.original_name && (
                            <span className="global-search__result-desc">{artifact.original_name}</span>
                          )}
                        </div>
                      </button>
                    );
                  })}
                </div>
              )}
            </>
          )}
        </div>
      )}
    </div>
  );
}
