"use client";

import { useEffect, useRef, useState, useCallback } from "react";
import maplibregl from "maplibre-gl";
import "maplibre-gl/dist/maplibre-gl.css";
import { MagnifyingGlass, CircleNotch, MapPin, X } from '@/lib/icons';
import { Input } from "@/components/ui/input";

const STYLE_URL = "https://tiles.openfreemap.org/styles/bright";
const TURKEY_CENTER: [number, number] = [35.0, 39.0];
const MARKER_COLOR = "#2563eb";

interface NominatimResult {
  place_id: number;
  display_name: string;
  lat: string;
  lon: string;
}

interface Props {
  initialLat?: number | null;
  initialLng?: number | null;
  initialSearchQuery?: string;
  onLocationChange: (lat: number, lng: number) => void;
  onClear: () => void;
}

export function PropertyMapPickerInner({
  initialLat,
  initialLng,
  initialSearchQuery = "",
  onLocationChange,
  onClear,
}: Props) {
  const containerRef = useRef<HTMLDivElement>(null);
  const mapRef = useRef<maplibregl.Map | null>(null);
  const markerRef = useRef<maplibregl.Marker | null>(null);
  const placeRef = useRef<(lat: number, lng: number) => void>(() => {});
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
  const dropdownRef = useRef<HTMLDivElement>(null);

  const [search, setSearch] = useState(initialSearchQuery);
  const [suggestions, setSuggestions] = useState<NominatimResult[]>([]);
  const [loading, setLoading] = useState(false);
  const [showDropdown, setShowDropdown] = useState(false);
  const [coords, setCoords] = useState<{ lat: number; lng: number } | null>(
    initialLat != null && initialLng != null
      ? { lat: initialLat, lng: initialLng }
      : null,
  );

  // Keep placeRef current so closures in map event handlers see latest callbacks
  placeRef.current = (lat: number, lng: number) => {
    setCoords({ lat, lng });
    onLocationChange(lat, lng);

    if (markerRef.current) {
      markerRef.current.setLngLat([lng, lat]);
    } else if (mapRef.current) {
      const marker = new maplibregl.Marker({ draggable: true, color: MARKER_COLOR })
        .setLngLat([lng, lat])
        .addTo(mapRef.current);

      marker.on("dragend", () => {
        const pos = marker.getLngLat();
        placeRef.current(pos.lat, pos.lng);
      });

      markerRef.current = marker;
    }
  };

  // Initialize map
  useEffect(() => {
    if (!containerRef.current) return;

    const hasInitial = initialLat != null && initialLng != null;

    const map = new maplibregl.Map({
      container: containerRef.current,
      style: STYLE_URL,
      center: hasInitial ? [initialLng!, initialLat!] : TURKEY_CENTER,
      zoom: hasInitial ? 14 : 5.5,
    });

    map.addControl(new maplibregl.NavigationControl(), "top-right");
    map.addControl(
      new maplibregl.GeolocateControl({ positionOptions: { enableHighAccuracy: true } }),
      "top-right",
    );

    mapRef.current = map;

    if (hasInitial) {
      const marker = new maplibregl.Marker({ draggable: true, color: MARKER_COLOR })
        .setLngLat([initialLng!, initialLat!])
        .addTo(map);

      marker.on("dragend", () => {
        const pos = marker.getLngLat();
        placeRef.current(pos.lat, pos.lng);
      });

      markerRef.current = marker;
    }

    map.on("click", (e) => {
      placeRef.current(e.lngLat.lat, e.lngLat.lng);
    });

    return () => {
      map.remove();
      mapRef.current = null;
      markerRef.current = null;
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Close dropdown when clicking outside
  useEffect(() => {
    function handleClickOutside(e: MouseEvent) {
      if (dropdownRef.current && !dropdownRef.current.contains(e.target as Node)) {
        setShowDropdown(false);
      }
    }
    document.addEventListener("mousedown", handleClickOutside);
    return () => document.removeEventListener("mousedown", handleClickOutside);
  }, []);

  // Debounced Nominatim fetch
  const fetchSuggestions = useCallback(async (query: string) => {
    if (!query.trim() || query.trim().length < 3) {
      setSuggestions([]);
      setShowDropdown(false);
      return;
    }

    setLoading(true);
    try {
      const q = query.includes("Türkiye") ? query : `${query}, Türkiye`;
      const res = await fetch(
        `https://nominatim.openstreetmap.org/search?q=${encodeURIComponent(q)}&format=json&limit=6&addressdetails=0`,
        { headers: { "Accept-Language": "tr,en" } },
      );
      const data = (await res.json()) as NominatimResult[];
      setSuggestions(data);
      setShowDropdown(data.length > 0);
    } catch {
      setSuggestions([]);
      setShowDropdown(false);
    } finally {
      setLoading(false);
    }
  }, []);

  function handleInputChange(value: string) {
    setSearch(value);

    if (debounceRef.current) clearTimeout(debounceRef.current);

    if (value.trim().length < 3) {
      setSuggestions([]);
      setShowDropdown(false);
      setLoading(false);
      return;
    }

    setLoading(true);
    debounceRef.current = setTimeout(() => {
      void fetchSuggestions(value);
    }, 400);
  }

  function handleSelect(result: NominatimResult) {
    const lat = parseFloat(result.lat);
    const lng = parseFloat(result.lon);

    // Shorten display_name for the search box (first two parts)
    const short = result.display_name.split(",").slice(0, 2).join(",").trim();
    setSearch(short);
    setSuggestions([]);
    setShowDropdown(false);

    placeRef.current(lat, lng);
    mapRef.current?.flyTo({ center: [lng, lat], zoom: 15, duration: 900 });
  }

  function handleClear() {
    markerRef.current?.remove();
    markerRef.current = null;
    setCoords(null);
    setSearch("");
    setSuggestions([]);
    setShowDropdown(false);
    onClear();
    mapRef.current?.flyTo({ center: TURKEY_CENTER, zoom: 5.5 });
  }

  return (
    <div className="space-y-2">
      {/* MagnifyingGlass input with autocomplete dropdown */}
      <div className="relative" ref={dropdownRef}>
        <div className="relative">
          <MagnifyingGlass className="text-muted-foreground absolute left-2.5 top-2.5 size-4" />
          <Input
            className="pl-8 pr-8"
            placeholder="Adres, mahalle veya şehir ara..."
            value={search}
            autoComplete="off"
            onChange={(e) => handleInputChange(e.target.value)}
            onFocus={() => suggestions.length > 0 && setShowDropdown(true)}
          />
          {loading && (
            <CircleNotch className="text-muted-foreground absolute right-2.5 top-2.5 size-4 animate-spin" />
          )}
        </div>

        {showDropdown && suggestions.length > 0 && (
          <div className="absolute z-50 mt-1 w-full rounded-md border bg-popover shadow-md">
            <ul className="py-1 text-sm">
              {suggestions.map((s) => (
                <li key={s.place_id}>
                  <button
                    type="button"
                    className="flex w-full items-start gap-2 px-3 py-2 text-left hover:bg-accent hover:text-accent-foreground"
                    onMouseDown={(e) => {
                      e.preventDefault(); // prevent input blur before click registers
                      handleSelect(s);
                    }}
                  >
                    <MapPin className="mt-0.5 size-3.5 shrink-0 text-muted-foreground" />
                    <span className="line-clamp-2 leading-snug">{s.display_name}</span>
                  </button>
                </li>
              ))}
            </ul>
          </div>
        )}
      </div>

      {/* MapTrifold */}
      <div
        ref={containerRef}
        className="h-64 w-full overflow-hidden rounded-lg border"
      />

      {/* Coordinate display / clear */}
      <div className="flex items-center justify-between">
        <div className="text-muted-foreground flex items-center gap-1.5 text-xs">
          <MapPin className="size-3 shrink-0" />
          {coords ? (
            <span className="font-mono">
              {coords.lat.toFixed(5)}, {coords.lng.toFixed(5)}
            </span>
          ) : (
            <span>Haritaya tıklayın veya adres arayın</span>
          )}
        </div>
        {coords && (
          <button
            type="button"
            onClick={handleClear}
            className="text-muted-foreground hover:text-foreground flex items-center gap-1 text-xs"
          >
            <X className="size-3" />
            Konumu kaldır
          </button>
        )}
      </div>
    </div>
  );
}
