import React, {
  useState,
  Dispatch,
  SetStateAction,
  useEffect,
  useRef,
  useCallback,
} from "react";
import useDebounce from "../../hooks/useDebounce";
import { useLocationSearch } from "../../utils/hooks/useLocationSearch";

interface LocationBoxProps {
  setSortAndFilterOptions: Dispatch<SetStateAction<SortAndFilterOptionsType>>;
  sortAndFilterOptions: SortAndFilterOptionsType;
  setClearAllStateDisabled: Dispatch<SetStateAction<boolean>>;
}

type DropdownItem = {
  type: "country" | "state" | "city";
  label: string;
  countryId?: number;
  stateId?: number;
  cityId?: number;
};

// In-memory cache to store previous query results
const locationCache = new Map<string, DropdownItem[]>();

const LocationBox: React.FC<LocationBoxProps> = ({
  setSortAndFilterOptions,
  sortAndFilterOptions,
  setClearAllStateDisabled,
}) => {
  const [query, setQuery] = useState("");
  const debouncedQuery = useDebounce(query, 150); // Slightly increased debounce for stability

  const [dropdownItems, setDropdownItems] = useState<DropdownItem[]>([]);
  const [activeIndex, setActiveIndex] = useState<number>(-1);
  const [isFinalSelection, setIsFinalSelection] = useState(false);
  const [isLoading, setIsLoading] = useState(false); // NEW: loading state

  const listRef = useRef<HTMLUListElement | null>(null);

  const handleLocationChange = (value: string) => {
    if (value !== "") setClearAllStateDisabled(false);
    setSortAndFilterOptions({
      ...sortAndFilterOptions,
      locationSearchKeyword: value,
    });
  };

  // 🔁 Fetch logic with memory cache
  const fetchLocations = useCallback(async () => {
    const trimmed = debouncedQuery.trim();
    if (!trimmed) {
      setDropdownItems([]);
      return;
    }

    // Check memory cache
    if (locationCache.has(trimmed)) {
      setDropdownItems(locationCache.get(trimmed)!);
      return;
    }

    setIsLoading(true);
    try {
      const { resp, status } = await useLocationSearch(trimmed);
      const results =
        status === 200 && Array.isArray(resp.results) ? resp.results : [];
      setDropdownItems(results);
      locationCache.set(trimmed, results); // Cache it
    } catch (err) {
      console.error("Search error:", err);
      setDropdownItems([]);
    } finally {
      setIsLoading(false);
    }
  }, [debouncedQuery]);

  useEffect(() => {
    fetchLocations();
    handleLocationChange(debouncedQuery);
  }, [debouncedQuery, fetchLocations]);

  useEffect(() => {
    setIsFinalSelection(false);
  }, [query]);

  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
    const listItems = listRef.current?.querySelectorAll("li") || [];
    if (e.key === "ArrowDown") {
      e.preventDefault();
      setActiveIndex((prev) => Math.min(prev + 1, listItems.length - 1));
    } else if (e.key === "ArrowUp") {
      e.preventDefault();
      setActiveIndex((prev) => Math.max(prev - 1, 0));
    } else if (e.key === "Enter" && activeIndex >= 0) {
      e.preventDefault();
      const selectedItem = listItems[activeIndex];
      selectedItem?.dispatchEvent(new MouseEvent("click", { bubbles: true }));
    }
  };

  useEffect(() => {
    const listItems = listRef.current?.querySelectorAll("li");
    if (listItems && listItems[activeIndex]) {
      (listItems[activeIndex] as HTMLElement).scrollIntoView({
        block: "nearest",
      });
    }
  }, [activeIndex]);

  return (
    <form method="post" style={{ position: "relative" }}>
      <span className="icon flaticon-map-locator"></span>
      <input
        type="text"
        name="listing-search"
        placeholder="Search Country, State or City"
        value={query}
        onChange={(e) => {
          setQuery(e.target.value);
          setActiveIndex(-1);
        }}
        onKeyDown={handleKeyDown}
        style={{
          width: "100%",
          padding: "8px",
          paddingLeft: "50px",
          fontSize: "1rem",
        }}
        autoComplete="off"
      />

      {query && (
        <button
          type="button"
          onClick={() => {
            setQuery("");
            setDropdownItems([]);
            setSortAndFilterOptions({
              ...sortAndFilterOptions,
              locationSearchKeyword: "",
            });
            setIsFinalSelection(false);
          }}
          style={{
            position: "absolute",
            right: "10px",
            top: "50%",
            transform: "translateY(-50%)",
            background: "none",
            border: "none",
            cursor: "pointer",
            fontSize: "1.2rem",
            color: "#888",
          }}
        >
          ×
        </button>
      )}

      {!isFinalSelection && (dropdownItems.length > 0 || isLoading) && (
        <ul
          className="auto-complete-list"
          ref={listRef}
          style={{
            listStyle: "none",
            padding: 0,
            margin: 0,
            maxHeight: "200px",
            overflowY: "auto",
            border: "1px solid #ccc",
            borderRadius: "4px",
            position: "absolute",
            width: "100%",
            backgroundColor: "white",
            zIndex: 9999,
          }}
        >
          {isLoading && (
            <li style={{ padding: "8px", color: "#999" }}>Searching...</li>
          )}
          {dropdownItems.map((item, index) => (
            <li
              key={`${item.type}-${item.countryId ?? ""}-${item.stateId ?? ""}-${item.cityId ?? ""}`}
              onClick={() => {
                setQuery(item.label);
                setIsFinalSelection(true);
                setActiveIndex(-1);
                handleLocationChange(item.label);
              }}
              style={{
                padding: "8px",
                cursor: "pointer",
                backgroundColor: index === activeIndex ? "#eee" : "#fff",
              }}
            >
              {item.label}
            </li>
          ))}
        </ul>
      )}
    </form>
  );
};

export default LocationBox;
