import React, { useEffect, useRef } from 'react';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
import { lv95ToWGS84, wgs84ToLV95 } from './LV95Converter';
import type { MapViewProps } from './MapView';
import styles from './MapView.module.css';

// Fix for default marker icons in Leaflet
import icon from 'leaflet/dist/images/marker-icon.png';
import iconShadow from 'leaflet/dist/images/marker-shadow.png';

const DefaultIcon = L.icon({
  iconUrl: icon,
  shadowUrl: iconShadow,
  iconSize: [25, 41],
  iconAnchor: [12, 41],
  popupAnchor: [1, -34],
  shadowSize: [41, 41]
});

L.Marker.prototype.options.icon = DefaultIcon;

const MapViewLeaflet: React.FC<MapViewProps> = ({
  parcels = [],
  center,
  zoomBounds,
  onMapClick,
  onParcelClick,
  height = '600px',
  className = '',
  emptyMessage = 'Klicken Sie auf die Karte, um einen Standort auszuwählen'
}) => {
  const mapRef = useRef<L.Map | null>(null);
  const mapContainerRef = useRef<HTMLDivElement>(null);
  const layersRef = useRef<L.Layer[]>([]);
  const centerMarkerRef = useRef<L.Marker | null>(null);

  // Initialize map
  useEffect(() => {
    if (!mapContainerRef.current || mapRef.current) return;

    // Default center: Switzerland (converted from LV95)
    const defaultCenterLV95 = center || { x: 2600000, y: 1200000 };
    const defaultCenter = lv95ToWGS84(defaultCenterLV95.x, defaultCenterLV95.y);

    // Create map
    const map = L.map(mapContainerRef.current, {
      center: [defaultCenter.lat, defaultCenter.lon],
      zoom: zoomBounds ? 15 : 8, // Zoom level based on whether we have bounds
      zoomControl: true,
      attributionControl: true
    });

    // Add OpenStreetMap tiles
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      attribution: '© OpenStreetMap contributors',
      maxZoom: 19
    }).addTo(map);

    mapRef.current = map;

    // Cleanup
    return () => {
      map.remove();
      mapRef.current = null;
    };
  }, []); // Only run once on mount

  // Update map center and zoom when center or zoomBounds change
  useEffect(() => {
    if (!mapRef.current) return;

    const map = mapRef.current;

    // Remove existing center marker
    if (centerMarkerRef.current) {
      map.removeLayer(centerMarkerRef.current);
      centerMarkerRef.current = null;
    }

    if (zoomBounds && parcels.length > 0) {
      // Convert zoom bounds to WGS84
      const sw = lv95ToWGS84(zoomBounds.min_x, zoomBounds.min_y);
      const ne = lv95ToWGS84(zoomBounds.max_x, zoomBounds.max_y);
      
      // Fit map to bounds
      map.fitBounds([[sw.lat, sw.lon], [ne.lat, ne.lon]], {
        padding: [20, 20],
        maxZoom: 18
      });
    } else if (center) {
      // Center on point and add marker
      const centerWGS84 = lv95ToWGS84(center.x, center.y);
      map.setView([centerWGS84.lat, centerWGS84.lon], map.getZoom() || 15);
      
      // Add center marker
      const marker = L.marker([centerWGS84.lat, centerWGS84.lon], {
        icon: L.icon({
          iconUrl: 'data:image/svg+xml;base64,' + btoa(`
            <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
              <circle cx="12" cy="12" r="8" fill="#ef4444" stroke="#fff" stroke-width="2"/>
            </svg>
          `),
          iconSize: [24, 24],
          iconAnchor: [12, 12]
        })
      }).addTo(map);
      centerMarkerRef.current = marker;
    } else {
      // Default center: Switzerland
      const defaultCenter = lv95ToWGS84(2600000, 1200000);
      map.setView([defaultCenter.lat, defaultCenter.lon], 8);
    }
  }, [center, zoomBounds, parcels.length]);

  // Draw parcels
  useEffect(() => {
    if (!mapRef.current) return;

    const map = mapRef.current;

    // Debug logging
    if (import.meta.env.DEV) {
      console.log('🗺️ MapView: Drawing parcels', {
        parcelCount: parcels.length,
        parcels: parcels.map(p => ({
          id: p.id,
          coordCount: p.coordinates.length,
          isSelected: p.isSelected,
          isAdjacent: p.isAdjacent
        }))
      });
    }

    // Remove existing parcel layers
    layersRef.current.forEach((layer) => {
      map.removeLayer(layer);
    });
    layersRef.current = [];

    // Add parcels
    parcels.forEach((parcel) => {
      if (parcel.coordinates.length < 3) {
        if (import.meta.env.DEV) {
          console.warn(`⚠️ Parcel ${parcel.id} has insufficient coordinates: ${parcel.coordinates.length}`);
        }
        return; // Need at least 3 points for a polygon
      }

      // Convert LV95 coordinates to WGS84
      const latLngs = parcel.coordinates.map((coord) => {
        const wgs84 = lv95ToWGS84(coord.x, coord.y);
        return [wgs84.lat, wgs84.lon] as [number, number];
      });

      // Create polygon
      const polygon = L.polygon(latLngs, {
        color: parcel.isSelected ? '#3b82f6' : parcel.isAdjacent ? '#9ca3af' : '#22c55e',
        weight: parcel.isSelected ? 3 : parcel.isAdjacent ? 2 : 1,
        fillColor: parcel.isSelected ? '#3b82f6' : parcel.isAdjacent ? '#9ca3af' : '#22c55e',
        fillOpacity: parcel.isSelected ? 0.3 : parcel.isAdjacent ? 0.2 : 0.2
      });

      // Add popup with parcel info
      const popupContent = `
        <div>
          <strong>Parzelle ${parcel.number || parcel.id}</strong><br/>
          ${parcel.egrid ? `EGRID: ${parcel.egrid}<br/>` : ''}
          ${parcel.isSelected ? '<em>Ausgewählt</em>' : parcel.isAdjacent ? '<em>Angrenzend</em>' : ''}
        </div>
      `;
      polygon.bindPopup(popupContent);

      // Add click handler
      if (onParcelClick) {
        polygon.on('click', () => {
          onParcelClick(parcel.id);
        });
      }

      polygon.addTo(map);
      layersRef.current.push(polygon);
    });
  }, [parcels, onParcelClick]);

  // Handle map clicks
  useEffect(() => {
    if (!mapRef.current || !onMapClick) return;

    const map = mapRef.current;

    const handleMapClick = (e: L.LeafletMouseEvent) => {
      // Convert WGS84 to LV95
      const lv95 = wgs84ToLV95(e.latlng.lat, e.latlng.lng);
      onMapClick({ x: lv95.x, y: lv95.y });
    };

    map.on('click', handleMapClick);

    return () => {
      map.off('click', handleMapClick);
    };
  }, [onMapClick]);

  return (
    <div className={`${styles.mapViewContainer} ${className}`} style={{ height, position: 'relative' }}>
      <div ref={mapContainerRef} style={{ width: '100%', height: '100%' }} />
      {parcels.length === 0 && !center && (
        <div className={styles.emptyStateOverlay}>
          <p>{emptyMessage}</p>
        </div>
      )}
    </div>
  );
};

export default MapViewLeaflet;

