'use client';

import { useEffect, useRef } from 'react';
import L from 'leaflet';

const DEFAULT_CENTER = { lat: 55.7558, lng: 37.6173 };

let iconsFixed = false;

function fixLeafletIcons() {
  if (iconsFixed || typeof window === 'undefined') return;
  iconsFixed = true;
  L.Icon.Default.mergeOptions({
    iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png',
    iconRetinaUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon-2x.png',
    shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
    iconSize: [25, 41],
    iconAnchor: [12, 41],
    popupAnchor: [1, -34],
    shadowSize: [41, 41]
  });
}

export function AddressMapPicker({
  latitude,
  longitude,
  onPick
}: {
  latitude?: number;
  longitude?: number;
  onPick: (lat: number, lng: number) => void;
}) {
  const mapRef = useRef<HTMLDivElement>(null);
  const mapInstance = useRef<L.Map | null>(null);
  const markerRef = useRef<L.Marker | null>(null);
  const onPickRef = useRef(onPick);

  useEffect(() => {
    onPickRef.current = onPick;
  }, [onPick]);

  useEffect(() => {
    fixLeafletIcons();
    if (!mapRef.current || mapInstance.current) return;

    const lat = latitude ?? DEFAULT_CENTER.lat;
    const lng = longitude ?? DEFAULT_CENTER.lng;
    const map = L.map(mapRef.current, { zoomControl: true }).setView([lat, lng], latitude != null ? 16 : 11);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
    }).addTo(map);

    const marker = L.marker([lat, lng], { draggable: true }).addTo(map);

    const emitPick = (nextLat: number, nextLng: number) => {
      onPickRef.current(nextLat, nextLng);
    };

    marker.on('dragend', () => {
      const position = marker.getLatLng();
      emitPick(position.lat, position.lng);
    });

    map.on('click', (event) => {
      marker.setLatLng(event.latlng);
      emitPick(event.latlng.lat, event.latlng.lng);
    });

    mapInstance.current = map;
    markerRef.current = marker;

    const resizeObserver = new ResizeObserver(() => {
      map.invalidateSize();
    });
    resizeObserver.observe(mapRef.current);

    return () => {
      resizeObserver.disconnect();
      map.remove();
      mapInstance.current = null;
      markerRef.current = null;
    };
  }, []);

  useEffect(() => {
    if (!markerRef.current || !mapInstance.current) return;
    if (latitude == null || longitude == null) return;
    const latLng = L.latLng(latitude, longitude);
    markerRef.current.setLatLng(latLng);
    mapInstance.current.setView(latLng, Math.max(mapInstance.current.getZoom(), 15));
  }, [latitude, longitude]);

  return (
    <div className="overflow-hidden rounded-2xl border border-[#eceef4]">
      <div ref={mapRef} className="h-[280px] w-full" />
      <p className="border-t border-[#eceef4] bg-[#fafbfd] px-4 py-2 text-xs text-[#667085]">
        Нажмите на карту или перетащите маркер, чтобы указать адрес
      </p>
    </div>
  );
}
