"use client";

import { useCallback, useEffect, useRef, useState } from "react";
import {
  MapContainer,
  TileLayer,
  CircleMarker,
  Tooltip,
  useMapEvents,
} from "react-leaflet";
import type { LeafletMouseEvent, Map as LeafletMap } from "leaflet";
import "leaflet/dist/leaflet.css";

import type {
  ParcelBboxItem,
  BboxCoords,
  ParcelBboxFilters,
} from "@/lib/site-finder-api";
import { useParcelsBboxQuery } from "@/lib/site-finder-api";
import { STATUS_COLORS } from "./ParcelLegend";

// ── Bbox change listener ───────────────────────────────────────────────────────

interface BboxListenerProps {
  onBboxChange: (bbox: BboxCoords) => void;
}

function BboxListener({ onBboxChange }: BboxListenerProps) {
  const map = useMapEvents({
    moveend() {
      const bounds = map.getBounds();
      onBboxChange({
        minLat: bounds.getSouth(),
        minLon: bounds.getWest(),
        maxLat: bounds.getNorth(),
        maxLon: bounds.getEast(),
      });
    },
    zoomend() {
      const bounds = map.getBounds();
      onBboxChange({
        minLat: bounds.getSouth(),
        minLon: bounds.getWest(),
        maxLat: bounds.getNorth(),
        maxLon: bounds.getEast(),
      });
    },
  });

  // Emit initial bbox on mount
  useEffect(() => {
    const bounds = map.getBounds();
    onBboxChange({
      minLat: bounds.getSouth(),
      minLon: bounds.getWest(),
      maxLat: bounds.getNorth(),
      maxLon: bounds.getEast(),
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return null;
}

// ── Parcel markers ─────────────────────────────────────────────────────────────

interface ParcelMarkersProps {
  parcels: ParcelBboxItem[];
  selectedCad: string | null;
  onSelect: (parcel: ParcelBboxItem) => void;
}

function ParcelMarkers({ parcels, selectedCad, onSelect }: ParcelMarkersProps) {
  return (
    <>
      {parcels.map((parcel) => {
        const color = STATUS_COLORS[parcel.status] ?? "#73767E";
        const isSelected = parcel.cad_num === selectedCad;
        return (
          <CircleMarker
            key={parcel.cad_num}
            center={[parcel.lat, parcel.lon]}
            radius={isSelected ? 10 : 7}
            pathOptions={{
              color: isSelected ? "#0F172A" : color,
              fillColor: color,
              fillOpacity: 0.85,
              weight: isSelected ? 2.5 : 1.5,
            }}
            eventHandlers={{
              click: (e: LeafletMouseEvent) => {
                e.originalEvent.stopPropagation();
                onSelect(parcel);
              },
            }}
          >
            <Tooltip direction="top" offset={[0, -8]} opacity={0.95}>
              <div style={{ fontSize: 12 }}>
                <div style={{ fontWeight: 600 }}>{parcel.cad_num}</div>
                <div style={{ color: "#5B6066" }}>
                  {parcel.area_ha.toFixed(2)} га · {parcel.district}
                </div>
              </div>
            </Tooltip>
          </CircleMarker>
        );
      })}
    </>
  );
}

// ── EntryMap ───────────────────────────────────────────────────────────────────

// Yekaterinburg center
const EKB_CENTER: [number, number] = [56.8389, 60.6057];
const DEFAULT_ZOOM = 12;

interface EntryMapProps {
  filters: ParcelBboxFilters;
  selectedCad: string | null;
  onParcelSelect: (parcel: ParcelBboxItem) => void;
  onParcelDeselect: () => void;
  /** Called whenever the map viewport changes — allows parent to read bbox for filter counters */
  onBboxChange?: (bbox: BboxCoords) => void;
}

export function EntryMap({
  filters,
  selectedCad,
  onParcelSelect,
  onParcelDeselect,
  onBboxChange,
}: EntryMapProps) {
  const [bbox, setBbox] = useState<BboxCoords | null>(null);
  const mapRef = useRef<LeafletMap | null>(null);

  const { data: parcels, isFetching } = useParcelsBboxQuery(bbox, filters);

  const handleBboxChange = useCallback(
    (newBbox: BboxCoords) => {
      setBbox(newBbox);
      onBboxChange?.(newBbox);
    },
    [onBboxChange],
  );

  return (
    <div style={{ position: "relative", width: "100%", height: "100%" }}>
      <MapContainer
        center={EKB_CENTER}
        zoom={DEFAULT_ZOOM}
        style={{ width: "100%", height: "100%", borderRadius: 12 }}
        ref={mapRef}
        // Click on map backdrop deselects parcel
        // handled via eventHandlers on markers + backdrop div
      >
        <TileLayer
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
        />
        <BboxListener onBboxChange={handleBboxChange} />
        {parcels && parcels.length > 0 && (
          <ParcelMarkers
            parcels={parcels}
            selectedCad={selectedCad}
            onSelect={onParcelSelect}
          />
        )}
      </MapContainer>

      {/* Deselect on map click — overlay to capture clicks outside markers */}
      {selectedCad && (
        <div
          style={{ position: "absolute", inset: 0, zIndex: 399 }}
          onClick={onParcelDeselect}
          aria-hidden="true"
        />
      )}

      {/* Fetching indicator */}
      {isFetching && (
        <div
          style={{
            position: "absolute",
            top: 12,
            left: "50%",
            transform: "translateX(-50%)",
            zIndex: 1000,
            background: "var(--bg-card)",
            border: "1px solid var(--border-card)",
            borderRadius: 20,
            padding: "4px 14px",
            fontSize: 12,
            color: "var(--fg-secondary)",
          }}
        >
          Загрузка участков...
        </div>
      )}

      {/* Empty state */}
      {!isFetching && parcels && parcels.length === 0 && (
        <div
          style={{
            position: "absolute",
            top: "50%",
            left: "50%",
            transform: "translate(-50%, -50%)",
            zIndex: 1000,
            background: "var(--bg-card)",
            border: "1px solid var(--border-card)",
            borderRadius: 12,
            padding: "16px 24px",
            fontSize: 13,
            color: "var(--fg-secondary)",
            textAlign: "center",
          }}
        >
          Нет участков в текущем виде. Измените фильтры или область карты.
        </div>
      )}
    </div>
  );
}
