import React, { useState, useRef, useEffect, memo } from "react";
import { useGenerator } from "../../context/GeneratorContext";

const SearchIcon = ({ className = "w-5 h-5" }) => (
  <svg className={className} fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
    <path strokeLinecap="round" strokeLinejoin="round" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
  </svg>
);

function SearchBar({
  value,
  onChange,
  placeholder = "Search images...",
  onSubmit,
  showSubmitButton = true,
  submitLabel = "Search",
  disabled = false,
  providerId,
  isSearching = false,
}) {
  const [inputValue, setInputValue] = useState(value);
  const [showHistory, setShowHistory] = useState(false);
  const [selectedHistoryIndex, setSelectedHistoryIndex] = useState(-1);
  const inputRef = useRef(null);
  const historyListRef = useRef(null);
  const generator = useGenerator();
  const history = providerId ? generator.getSearchHistory(providerId) : [];
  const addToHistory = providerId ? generator.addSearchToHistory : () => {};
  const clearHistory = providerId ? generator.clearSearchHistory : () => {};

  // Sync input value when external value changes
  useEffect(() => {
    setInputValue(value);
  }, [value]);

  // Reset selected index when history visibility changes
  useEffect(() => {
    if (!showHistory) {
      setSelectedHistoryIndex(-1);
    }
  }, [showHistory]);

  useEffect(() => {
    const handleKeyDown = (e) => {
      if ((e.ctrlKey || e.metaKey) && e.key === "k") {
        e.preventDefault();
        inputRef.current?.focus();
      }
      if (e.key === "Escape") {
        setShowHistory(false);
        if (inputValue) {
          setInputValue("");
          onChange("");
        }
        inputRef.current?.blur();
      }
    };
    window.addEventListener("keydown", handleKeyDown);
    return () => window.removeEventListener("keydown", handleKeyDown);
  }, [inputValue, onChange]);

  const handleSubmit = (e) => {
    e.preventDefault();
    const q = (inputValue || "").trim();
    if (q) addToHistory(providerId, q);
    setShowHistory(false);
    onChange(q); // Only update search query on submit
    onSubmit?.();
  };

  const handleHistorySelect = (item) => {
    setInputValue(item);
    onChange(item); // Trigger search when selecting from history
    setShowHistory(false);
    inputRef.current?.focus();
  };

  const handleClear = () => {
    setInputValue("");
    onChange(""); // Trigger search with empty query
  };

  const hasText = (inputValue || "").trim().length > 0;

  return (
    <form
      className="relative w-full mb-6"
      onSubmit={handleSubmit}
      role="search"
      aria-label={placeholder}
    >
      <div className="relative flex items-center rounded-md border border-gray-200 bg-white h-[46px] focus-within:border-gray-400 focus-within:ring-1 focus-within:ring-gray-400">
        <div className="pointer-events-none absolute left-3 text-gray-400">
          <SearchIcon className="w-4 h-4" />
        </div>
        <input
          ref={inputRef}
          type="text"
          value={inputValue}
          onChange={(e) => setInputValue(e.target.value)}
          onFocus={() => history.length > 0 && setShowHistory(true)}
          onBlur={() => setTimeout(() => setShowHistory(false), 200)}
          onKeyDown={(e) => {
            if (!showHistory || history.length === 0) return;
            
            if (e.key === "ArrowDown") {
              e.preventDefault();
              setSelectedHistoryIndex((prev) => 
                prev < history.length - 1 ? prev + 1 : prev
              );
            } else if (e.key === "ArrowUp") {
              e.preventDefault();
              setSelectedHistoryIndex((prev) => (prev > 0 ? prev - 1 : -1));
            } else if (e.key === "Enter" && selectedHistoryIndex >= 0) {
              e.preventDefault();
              handleHistorySelect(history[selectedHistoryIndex]);
            }
          }}
          placeholder={placeholder}
          disabled={disabled}
          className="search-input-field"
          aria-label={placeholder}
          aria-describedby={showHistory ? "search-history-list" : undefined}
          aria-activedescendant={
            showHistory && selectedHistoryIndex >= 0
              ? `history-item-${selectedHistoryIndex}`
              : undefined
          }
          aria-expanded={showHistory}
          aria-controls="search-history-list"
        />
        <div className="absolute right-1 flex items-center gap-1">
          {hasText && !isSearching && (
            <button
              type="button"
              onClick={handleClear}
              className="flex h-7 w-7 items-center justify-center rounded text-gray-400 hover:bg-gray-100 hover:text-gray-600 transition-colors"
              aria-label="Clear search"
            >
              <svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2.5}>
                <path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
              </svg>
            </button>
          )}
          {showSubmitButton && (
            <button
              type="submit"
              disabled={disabled || isSearching}
              className="flex items-center justify-center gap-1.5 rounded-md border border-gray-800 bg-gray-800 h-9 min-w-[80px] px-3 text-sm font-medium text-white hover:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-gray-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
              aria-label={submitLabel}
            >
              {isSearching ? (
                <>
                  <svg className="h-4 w-4 animate-spin" fill="none" viewBox="0 0 24 24">
                    <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
                    <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" />
                  </svg>
                  <span>Searching...</span>
                </>
              ) : (
                <span>{submitLabel}</span>
              )}
            </button>
          )}
        </div>
      </div>
      {showHistory && history.length > 0 && (
        <div
          ref={historyListRef}
          id="search-history-list"
          className="absolute left-0 right-0 top-full z-20 mt-1 max-h-60 overflow-auto rounded-xl border border-gray-200 bg-white py-2 shadow-lg"
          role="listbox"
        >
          <div className="flex items-center justify-between px-4 py-2 text-xs font-medium text-gray-500">
            <span>Recent searches</span>
            <button
              type="button"
              onClick={() => clearHistory(providerId)}
              className="text-gray-800 hover:underline focus:outline-none focus:ring-2 focus:ring-gray-600 rounded"
              tabIndex={-1}
            >
              Clear
            </button>
          </div>
          {history.map((item, i) => (
            <button
              key={`${i}-${item}`}
              id={`history-item-${i}`}
              type="button"
              onClick={() => handleHistorySelect(item)}
              onMouseEnter={() => setSelectedHistoryIndex(i)}
              className={`w-full px-4 py-2.5 text-left text-sm transition-colors ${
                selectedHistoryIndex === i
                  ? "bg-indigo-50 text-indigo-900 font-medium"
                  : "text-gray-700 hover:bg-gray-50"
              }`}
              role="option"
              aria-selected={selectedHistoryIndex === i}
              tabIndex={-1}
            >
              <div className="flex items-center gap-2">
                <svg className="w-4 h-4 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
                </svg>
                <span>{item}</span>
              </div>
            </button>
          ))}
        </div>
      )}
    </form>
  );
}

export default memo(SearchBar);
