"use client";

import React, { useEffect, useRef, useState } from "react";
import { mapIrSearch, MapIrSearchItem, isValidMapIrKey } from "@/lib/map-ir";
import { useSettings } from "@/hook/use-settings";

type PlaceLike = {
  formatted_address?: string;
  geometry?: {
    location?: {
      lat: () => number;
      lng: () => number;
    };
  };
};

type AutocompleteHandle = {
  getPlace: () => PlaceLike;
};

/**
 * جایگزین Autocomplete گوگل — جستجو با Map.ir
 */
export function Autocomplete({
  children,
  onLoad,
  onPlaceChanged,
  className,
}: {
  children: React.ReactElement;
  onLoad?: (ac: AutocompleteHandle) => void;
  onPlaceChanged?: () => void;
  className?: string;
}) {
  const { settings } = useSettings();
  const apiKey = [
    settings?.map_ir_key,
    settings?.mapir_key,
    settings?.google_map_key,
    process.env.NEXT_PUBLIC_MAP_IR_KEY,
    process.env.NEXT_PUBLIC_GOOGLE_MAPS_KEY,
  ]
    .map((k) => String(k || "").trim())
    .find((k) => isValidMapIrKey(k)) || "";

  const [query, setQuery] = useState("");
  const [items, setItems] = useState<MapIrSearchItem[]>([]);
  const [open, setOpen] = useState(false);
  const selectedRef = useRef<MapIrSearchItem | null>(null);
  const skipSearchRef = useRef(false);
  const searchIdRef = useRef(0);
  const handleRef = useRef<AutocompleteHandle>({
    getPlace: () => {
      const s = selectedRef.current;
      if (!s) return {};
      return {
        formatted_address: s.address || s.title,
        geometry: {
          location: {
            lat: () => s.lat,
            lng: () => s.lng,
          },
        },
      };
    },
  });

  useEffect(() => {
    onLoad?.(handleRef.current);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  useEffect(() => {
    if (skipSearchRef.current) {
      skipSearchRef.current = false;
      return;
    }
    if (!query || query.length < 2 || !isValidMapIrKey(apiKey)) {
      setItems([]);
      return;
    }
    const id = ++searchIdRef.current;
    const t = setTimeout(() => {
      void mapIrSearch(query, apiKey).then((res) => {
        if (id !== searchIdRef.current) return;
        setItems(res);
        setOpen(res.length > 0);
      });
    }, 300);
    return () => clearTimeout(t);
  }, [query, apiKey]);

  const child = React.Children.only(children) as React.ReactElement<any>;

  const selectItem = (item: MapIrSearchItem) => {
    selectedRef.current = item;
    skipSearchRef.current = true;
    searchIdRef.current += 1;
    const label = item.address || item.title;
    setQuery(label);
    setItems([]);
    setOpen(false);

    child.props.onChange?.({
      target: { value: label },
    } as React.ChangeEvent<HTMLInputElement>);

    onPlaceChanged?.();
  };

  return (
    <div className={className} style={{ position: "relative" }}>
      {React.cloneElement(child, {
        onChange: (e: React.ChangeEvent<HTMLInputElement>) => {
          selectedRef.current = null;
          setQuery(e.target.value);
          child.props.onChange?.(e);
        },
        onFocus: (e: React.FocusEvent<HTMLInputElement>) => {
          if (items.length > 0) setOpen(true);
          child.props.onFocus?.(e);
        },
        onBlur: (e: React.FocusEvent<HTMLInputElement>) => {
          setTimeout(() => setOpen(false), 150);
          child.props.onBlur?.(e);
        },
      })}
      {open && items.length > 0 && (
        <ul className="absolute z-50 left-0 right-0 mt-1 max-h-56 overflow-auto rounded-lg border bg-white shadow-lg text-start">
          {items.map((item) => (
            <li key={item.id}>
              <button
                type="button"
                className="w-full px-3 py-2 text-sm hover:bg-gray-50 text-start"
                onMouseDown={(e) => e.preventDefault()}
                onClick={() => selectItem(item)}
              >
                <div className="font-medium">{item.title}</div>
                {item.address && item.address !== item.title && (
                  <div className="text-xs text-gray-500">{item.address}</div>
                )}
              </button>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}
