import React, { useEffect, useRef } from 'react';
import { Box } from '@chakra-ui/react';

// Dynamically load Leaflet
let L: any = null;

interface ContactMapProps {
  latitude: number;
  longitude: number;
  zoom?: number;
  address?: string;
  clubName?: string;
  mapStyle?: string;
  height?: number;
  clubPrimaryColor?: string;
  clubSecondaryColor?: string;
}

// Available map styles
export const MAP_STYLES = {
  // Clean & Minimal
  'positron': {
    name: 'Positron (Light)',
    url: 'https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png',
    attribution: '© OpenStreetMap © CartoDB',
    description: 'Clean light map, perfect for overlays'
  },
  'positron-no-labels': {
    name: 'Positron No Labels',
    url: 'https://{s}.basemaps.cartocdn.com/light_nolabels/{z}/{x}/{y}{r}.png',
    attribution: '© OpenStreetMap © CartoDB',
    description: 'Minimal light map without labels'
  },
  
  // Dark Themes
  'dark': {
    name: 'Dark Matter',
    url: 'https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png',
    attribution: '© OpenStreetMap © CartoDB',
    description: 'Dark theme, great for night mode'
  },
  'dark-no-labels': {
    name: 'Dark No Labels',
    url: 'https://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png',
    attribution: '© OpenStreetMap © CartoDB',
    description: 'Dark map without labels'
  },
  
  // Black & White
  'toner': {
    name: 'Toner (B&W)',
    url: 'https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}{r}.png',
    attribution: '© Stamen Design © OpenStreetMap',
    description: 'High contrast black and white'
  },
  'toner-lite': {
    name: 'Toner Lite (B&W)',
    url: 'https://tiles.stadiamaps.com/tiles/stamen_toner_lite/{z}/{x}/{y}{r}.png',
    attribution: '© Stamen Design © OpenStreetMap',
    description: 'Subtle black and white'
  },
  
  // Colorful Options
  'voyager': {
    name: 'Voyager',
    url: 'https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png',
    attribution: '© OpenStreetMap © CartoDB',
    description: 'Balanced colors, good readability'
  },
  'terrain': {
    name: 'Terrain',
    url: 'https://tiles.stadiamaps.com/tiles/stamen_terrain/{z}/{x}/{y}{r}.jpg',
    attribution: '© Stamen Design © OpenStreetMap',
    description: 'Natural terrain visualization'
  },
  'watercolor': {
    name: 'Watercolor',
    url: 'https://tiles.stadiamaps.com/tiles/stamen_watercolor/{z}/{x}/{y}.jpg',
    attribution: '© Stamen Design © OpenStreetMap',
    description: 'Artistic watercolor style'
  },
  
  // Default
  'default': {
    name: 'OpenStreetMap',
    url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
    attribution: '© OpenStreetMap contributors',
    description: 'Standard OpenStreetMap'
  },
  
  // Satellite
  'satellite': {
    name: 'Satellite',
    url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
    attribution: '© Esri',
    description: 'Satellite imagery'
  },
};

const ContactMap: React.FC<ContactMapProps> = ({
  latitude,
  longitude,
  zoom = 15,
  address,
  clubName,
  mapStyle = 'default',
  height = 400,
  clubPrimaryColor,
  clubSecondaryColor,
}) => {
  const mapRef = useRef<HTMLDivElement>(null);
  const mapInstanceRef = useRef<any>(null);
  const [isLoaded, setIsLoaded] = React.useState(false);
  const [loadError, setLoadError] = React.useState<string | null>(null);

  useEffect(() => {
    // Load Leaflet CSS and JS dynamically
    const loadLeaflet = async () => {
      try {
        // Check if already loaded
        if ((window as any).L) {
          L = (window as any).L;
          setIsLoaded(true);
          return;
        }

        // Load CSS
        if (!document.getElementById('leaflet-css')) {
          const link = document.createElement('link');
          link.id = 'leaflet-css';
          link.rel = 'stylesheet';
          link.href = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.css';
          link.integrity = 'sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=';
          link.crossOrigin = '';
          document.head.appendChild(link);
        }

        // Load JS
        if (!document.getElementById('leaflet-js')) {
          const script = document.createElement('script');
          script.id = 'leaflet-js';
          script.src = 'https://unpkg.com/leaflet@1.9.4/dist/leaflet.js';
          script.integrity = 'sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=';
          script.crossOrigin = '';
          
          script.onload = () => {
            L = (window as any).L;
            setIsLoaded(true);
          };

          script.onerror = () => {
            setLoadError('Failed to load map library');
          };

          document.head.appendChild(script);
        }
      } catch (error) {
        setLoadError('Error loading map');
      }
    };

    loadLeaflet();
  }, []);

  useEffect(() => {
    if (!isLoaded || !L || !mapRef.current || mapInstanceRef.current) return;

    try {
      // Initialize map
      const map = L.map(mapRef.current, {
        center: [latitude, longitude],
        zoom: zoom,
        scrollWheelZoom: false, // Disable scroll zoom for better UX
      });

      mapInstanceRef.current = map;

      // Get tile layer URL based on style
      let tileUrl = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
      let attribution = '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors';

      // Use predefined styles or custom URL
      if (mapStyle && MAP_STYLES[mapStyle as keyof typeof MAP_STYLES]) {
        const style = MAP_STYLES[mapStyle as keyof typeof MAP_STYLES];
        tileUrl = style.url;
        attribution = style.attribution;
      } else if (mapStyle && mapStyle.startsWith('http')) {
        // Custom tile URL
        tileUrl = mapStyle;
      }

      // Add tile layer
      const tileLayer = L.tileLayer(tileUrl, {
        attribution: attribution,
        maxZoom: 19,
      }).addTo(map);

      // Apply club color overlay if provided
      if (clubPrimaryColor && clubPrimaryColor !== '') {
        const colorFilter = createColorFilter(clubPrimaryColor);
        if (colorFilter) {
          const pane = map.createPane('colorOverlay');
          pane.style.zIndex = '400';
          pane.style.pointerEvents = 'none';
          pane.style.mixBlendMode = 'multiply';
          pane.style.backgroundColor = colorFilter;
          pane.style.opacity = '0.15';
        }
      }

      // Create custom marker icon with club colors
      const markerColor = clubPrimaryColor || '#3388ff';
      const customIcon = createCustomMarkerIcon(markerColor, L);

      // Add marker
      const marker = L.marker([latitude, longitude], { icon: customIcon }).addTo(map);

      // Add popup if address is provided
      if (clubName || address) {
        let popupContent = '';
        if (clubName) popupContent += `<b>${clubName}</b><br>`;
        if (address) popupContent += address;
        marker.bindPopup(popupContent);
      }

      // Enable scroll zoom on click
      map.on('click', () => {
        map.scrollWheelZoom.enable();
      });

      // Disable scroll zoom on mouseout
      map.on('mouseout', () => {
        map.scrollWheelZoom.disable();
      });

    } catch (error) {
      console.error('Error initializing map:', error);
      setLoadError('Failed to initialize map');
    }

    // Cleanup
    return () => {
      if (mapInstanceRef.current) {
        mapInstanceRef.current.remove();
        mapInstanceRef.current = null;
      }
    };
  }, [isLoaded, latitude, longitude, zoom, address, clubName, mapStyle, clubPrimaryColor, clubSecondaryColor]);

  // Helper function to create color filter
  function createColorFilter(color: string): string | null {
    try {
      // Validate and normalize color
      const tempDiv = document.createElement('div');
      tempDiv.style.color = color;
      document.body.appendChild(tempDiv);
      const computedColor = window.getComputedStyle(tempDiv).color;
      document.body.removeChild(tempDiv);
      return computedColor;
    } catch {
      return null;
    }
  }

  // Helper function to create custom marker with club colors
  function createCustomMarkerIcon(color: string, leaflet: any) {
    // Create SVG marker with custom color
    const svgIcon = `
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 36" width="36" height="54">
        <defs>
          <filter id="shadow" x="-50%" y="-50%" width="200%" height="200%">
            <feGaussianBlur in="SourceAlpha" stdDeviation="2"/>
            <feOffset dx="0" dy="2" result="offsetblur"/>
            <feComponentTransfer>
              <feFuncA type="linear" slope="0.3"/>
            </feComponentTransfer>
            <feMerge>
              <feMergeNode/>
              <feMergeNode in="SourceGraphic"/>
            </feMerge>
          </filter>
        </defs>
        <path fill="${color}" stroke="#fff" stroke-width="1.5" filter="url(#shadow)"
              d="M12 0C7.03 0 3 4.03 3 9c0 7.5 9 18 9 18s9-10.5 9-18c0-4.97-4.03-9-9-9z"/>
        <circle cx="12" cy="9" r="3" fill="#fff"/>
      </svg>
    `;
    
    const iconUrl = 'data:image/svg+xml;base64,' + btoa(svgIcon);
    
    return leaflet.icon({
      iconUrl: iconUrl,
      iconSize: [36, 54],
      iconAnchor: [18, 54],
      popupAnchor: [0, -54],
    });
  }

  if (loadError) {
    return (
      <Box
        ref={mapRef}
        w="100%"
        h={`${height}px`}
        bg="gray.100"
        display="flex"
        alignItems="center"
        justifyContent="center"
        borderRadius="md"
      >
        {loadError}
      </Box>
    );
  }

  return (
    <Box
      ref={mapRef}
      w="100%"
      h={`${height}px`}
      borderRadius="md"
      overflow="hidden"
      boxShadow="md"
    />
  );
};

export default ContactMap;
