"use client";

import React, { useState, useRef, useEffect } from "react";
import type { ItemRecord } from "@/lib/api";
import { searchItems } from "@/lib/api";

/**
 * ItemAutocomplete Component
 * 
 * Reusable autocomplete component for item search with debounced API calls.
 * 
 * Features:
 * - Debounced search (300ms) after typing 2+ characters
 * - Loading indicator during API call
 * - Suggestions dropdown with item code (bold) and item name (secondary)
 * - Keyboard navigation (Arrow Up/Down, Enter, Escape)
 * - Click outside to close dropdown
 * - "No results found" message when search returns empty
 * - Fixed positioning dropdown (below input)
 * - Limited dropdown height with scroll
 * - Matches existing design patterns (brand colors #4c6fff)
 */

const BRAND = "#4c6fff";

interface ItemAutocompleteProps {
  value: string;
  onSelect: (item: ItemRecord) => void;
  onChange: (value: string) => void;
  getInputValue?: (item: ItemRecord) => string;
  placeholder?: string;
  disabled?: boolean;
  searchOnValueChange?: boolean;
}

export default function ItemAutocomplete({
  value,
  onSelect,
  onChange,
  getInputValue = (item) => item.itemCode,
  placeholder = "Enter item code or name...",
  disabled = false,
  searchOnValueChange = true,
}: ItemAutocompleteProps) {
  const [showSuggestions, setShowSuggestions] = useState(false);
  const [suggestions, setSuggestions] = useState<ItemRecord[]>([]);
  const [selectedIndex, setSelectedIndex] = useState(-1);
  const [isLoading, setIsLoading] = useState(false);
  const [typedSearchPending, setTypedSearchPending] = useState(false);
  const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, width: 0 });
  
  const inputRef = useRef<HTMLInputElement>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);
  const debounceTimerRef = useRef<NodeJS.Timeout | null>(null);
  const selectedValueRef = useRef<string | null>(null);
  const typedValueRef = useRef<string | null>(null);

  // Debounced search effect
  useEffect(() => {
    // Clear existing timer
    if (debounceTimerRef.current) {
      clearTimeout(debounceTimerRef.current);
    }

    // Don't search if value is too short, disabled, or just selected.
    if (
      disabled ||
      value.length < 2 ||
      value === selectedValueRef.current ||
      (!searchOnValueChange && value !== typedValueRef.current) ||
      (!searchOnValueChange && !typedSearchPending)
    ) {
      setSuggestions([]);
      setShowSuggestions(false);
      setIsLoading(false);
      return;
    }

    // Set loading state
    setIsLoading(true);

    // Set up new timer for 300ms
    debounceTimerRef.current = setTimeout(async () => {
      try {
        const results = await searchItems(value);
        setSuggestions(results);
        setShowSuggestions(true);
        setSelectedIndex(-1);
      } catch (error) {
        console.error("Error searching items:", error);
        setSuggestions([]);
        setShowSuggestions(false);
      } finally {
        setIsLoading(false);
      }
    }, 300);

    // Cleanup
    return () => {
      if (debounceTimerRef.current) {
        clearTimeout(debounceTimerRef.current);
      }
    };
  }, [value, disabled, typedSearchPending, searchOnValueChange]);

  // Update dropdown position when it opens
  useEffect(() => {
    if (showSuggestions && inputRef.current) {
      const rect = inputRef.current.getBoundingClientRect();
      setDropdownPosition({
        top: rect.bottom + window.scrollY + 4,
        left: rect.left + window.scrollX,
        width: rect.width,
      });
    }
  }, [showSuggestions]);

  // Click outside to close
  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (
        dropdownRef.current &&
        !dropdownRef.current.contains(event.target as Node) &&
        inputRef.current &&
        !inputRef.current.contains(event.target as Node)
      ) {
        setShowSuggestions(false);
      }
    }

    if (showSuggestions) {
      document.addEventListener("mousedown", handleClickOutside);
      return () => document.removeEventListener("mousedown", handleClickOutside);
    }
  }, [showSuggestions]);

  // Handle keyboard navigation
  function handleKeyDown(e: React.KeyboardEvent) {
    if (!showSuggestions || suggestions.length === 0) {
      return;
    }

    switch (e.key) {
      case "ArrowDown":
        e.preventDefault();
        setSelectedIndex((prev) => 
          prev < suggestions.length - 1 ? prev + 1 : prev
        );
        break;

      case "ArrowUp":
        e.preventDefault();
        setSelectedIndex((prev) => (prev > 0 ? prev - 1 : -1));
        break;

      case "Enter":
        e.preventDefault();
        if (selectedIndex >= 0 && selectedIndex < suggestions.length) {
          handleSelect(suggestions[selectedIndex]);
        }
        break;

      case "Escape":
        e.preventDefault();
        setShowSuggestions(false);
        setSelectedIndex(-1);
        break;
    }
  }

  // Handle suggestion selection
  function handleSelect(item: ItemRecord) {
    selectedValueRef.current = getInputValue(item);
    typedValueRef.current = null;
    setTypedSearchPending(false);
    onSelect(item);
    setShowSuggestions(false);
    setSelectedIndex(-1);
  }

  // Handle input change
  function handleInputChange(e: React.ChangeEvent<HTMLInputElement>) {
    selectedValueRef.current = null;
    typedValueRef.current = e.target.value;
    setTypedSearchPending(true);
    onChange(e.target.value);
  }

  return (
    <>
      <div style={{ position: "relative", zIndex: 1 }}>
        <input
          ref={inputRef}
          type="text"
          value={value}
          onChange={handleInputChange}
          onKeyDown={handleKeyDown}
          placeholder={placeholder}
          disabled={disabled}
          style={{
            padding: "9px 10px",
            borderRadius: 6,
            border: `1.5px solid ${isLoading ? BRAND : "var(--line)"}`,
            background: isLoading ? "#f0f4ff" : "#fff",
            fontSize: "0.88rem",
            fontFamily: "inherit",
            color: "var(--ink)",
            outline: "none",
            width: "100%",
            boxSizing: "border-box",
            opacity: disabled ? 0.6 : 1,
            cursor: disabled ? "not-allowed" : "text",
          }}
        />
        
        {/* Loading indicator */}
        {isLoading && (
          <div
            style={{
              position: "absolute",
              right: 10,
              top: "50%",
              transform: "translateY(-50%)",
              pointerEvents: "none",
            }}
          >
            <div
              style={{
                width: 14,
                height: 14,
                border: `2px solid ${BRAND}`,
                borderTopColor: "transparent",
                borderRadius: "50%",
                animation: "spin 0.8s linear infinite",
              }}
            />
          </div>
        )}
      </div>

      {/* Suggestions Dropdown */}
      {showSuggestions && !isLoading && (
        <div
          ref={dropdownRef}
          style={{
            position: "fixed",
            top: dropdownPosition.top,
            left: dropdownPosition.left,
            width: dropdownPosition.width,
            maxHeight: 320,
            overflowY: "auto",
            background: "#fff",
            border: "1.5px solid var(--line)",
            borderRadius: 8,
            boxShadow: "0 8px 24px rgba(31, 39, 64, 0.12)",
            zIndex: 1000,
          }}
        >
          {suggestions.length === 0 ? (
            // No results message
            <div
              style={{
                padding: "16px 14px",
                textAlign: "center",
                color: "var(--muted)",
                fontSize: "0.86rem",
              }}
            >
              No results found
            </div>
          ) : (
            // Suggestions list
            suggestions.map((item, index) => (
              <div
                key={item._id}
                onClick={() => handleSelect(item)}
                style={{
                  padding: "10px 14px",
                  cursor: "pointer",
                  background: index === selectedIndex ? "#f0f4ff" : "#fff",
                  borderBottom: index < suggestions.length - 1 ? "1px solid var(--line)" : "none",
                  transition: "background 120ms ease",
                }}
                onMouseEnter={() => setSelectedIndex(index)}
              >
                <div
                  style={{
                    fontWeight: 700,
                    fontSize: "0.88rem",
                    color: "var(--ink)",
                    marginBottom: 2,
                  }}
                >
                  {item.itemCode}
                </div>
                <div
                  style={{
                    fontSize: "0.82rem",
                    color: "var(--muted)",
                  }}
                >
                  {item.itemName || "—"}
                </div>
              </div>
            ))
          )}
        </div>
      )}

      {/* CSS for spinner animation */}
      <style jsx>{`
        @keyframes spin {
          to {
            transform: rotate(360deg);
          }
        }
      `}</style>
    </>
  );
}
