import { useState, useEffect, useCallback } from 'react';
import { useMap, useMapEvents, CircleMarker, Polyline, Polygon, Tooltip } from 'react-leaflet';
import type { LatLng, LeafletMouseEvent } from 'leaflet';

interface Props {
  active: boolean;
  color: string;
  opacity: number;
  onFinish: (geojson: string, bounds: string) => void;
  onCancel: () => void;
}

function DrawHandler({ onClickMap }: { onClickMap: (latlng: LatLng) => void }) {
  useMapEvents({
    click(e: LeafletMouseEvent) {
      onClickMap(e.latlng);
    },
  });
  return null;
}

export default function CutDrawingMode({ active, color, opacity, onFinish, onCancel }: Props) {
  const map = useMap();
  const [vertices, setVertices] = useState<LatLng[]>([]);

  useEffect(() => {
    if (active) {
      map.getContainer().style.cursor = 'crosshair';
      map.doubleClickZoom.disable();
      setVertices([]);
    } else {
      map.getContainer().style.cursor = '';
      map.doubleClickZoom.enable();
      setVertices([]);
    }
    return () => {
      map.getContainer().style.cursor = '';
      map.doubleClickZoom.enable();
    };
  }, [active, map]);

  // Keyboard shortcuts
  useEffect(() => {
    if (!active) return;
    const handler = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        onCancel();
      } else if (e.ctrlKey && e.key === 'z') {
        setVertices((prev) => prev.slice(0, -1));
      }
    };
    document.addEventListener('keydown', handler);
    return () => document.removeEventListener('keydown', handler);
  }, [active, onCancel]);

  const handleClick = useCallback(
    (latlng: LatLng) => {
      if (vertices.length >= 3) {
        // Check if close to first vertex
        const firstPx = map.latLngToContainerPoint(vertices[0]!);
        const clickPx = map.latLngToContainerPoint(latlng);
        const dist = Math.sqrt(
          Math.pow(firstPx.x - clickPx.x, 2) + Math.pow(firstPx.y - clickPx.y, 2)
        );
        if (dist < 15) {
          // Close the polygon
          const coords = vertices.map((v) => [v.lng, v.lat]);
          // Close ring
          coords.push(coords[0]!);
          const geojson = JSON.stringify({
            type: 'Polygon',
            coordinates: [coords],
          });

          const lats = vertices.map((v) => v.lat);
          const lngs = vertices.map((v) => v.lng);
          const bounds = JSON.stringify({
            minLat: Math.min(...lats),
            maxLat: Math.max(...lats),
            minLng: Math.min(...lngs),
            maxLng: Math.max(...lngs),
          });

          onFinish(geojson, bounds);
          return;
        }
      }
      setVertices((prev) => [...prev, latlng]);
    },
    [vertices, map, onFinish]
  );

  if (!active) return null;

  const positions = vertices.map((v) => [v.lat, v.lng] as [number, number]);

  return (
    <>
      <DrawHandler onClickMap={handleClick} />

      {/* Polygon preview (3+ vertices) */}
      {vertices.length >= 3 && (
        <Polygon
          positions={positions}
          pathOptions={{
            color,
            fillColor: color,
            fillOpacity: opacity,
            weight: 2,
            dashArray: '6 4',
          }}
        />
      )}

      {/* Line between vertices (2+ vertices) */}
      {vertices.length >= 2 && vertices.length < 3 && (
        <Polyline
          positions={positions}
          pathOptions={{ color, weight: 2, dashArray: '6 4' }}
        />
      )}

      {/* Vertex markers */}
      {vertices.map((v, i) => (
        <CircleMarker
          key={i}
          center={[v.lat, v.lng]}
          radius={i === 0 ? 8 : 5}
          pathOptions={{
            fillColor: i === 0 ? '#fff' : color,
            fillOpacity: 1,
            color: i === 0 ? color : '#fff',
            weight: 2,
          }}
        >
          {i === 0 && vertices.length >= 3 && (
            <Tooltip permanent direction="top" offset={[0, -10]}>
              Click to close
            </Tooltip>
          )}
        </CircleMarker>
      ))}
    </>
  );
}
