import { useTheme } from "@/context/ThemeContext";
import { ChargePoint } from "@/types/chargepoint/chargepoint";
import { MarkerClusterer } from "@googlemaps/markerclusterer";
import { AdvancedMarker, useMap } from "@vis.gl/react-google-maps";
import { useEffect, useState, useRef } from "react";
import { colord } from "colord";
import { LocateFixed } from "lucide-react";
import { StationMarker } from "@/modules/chargepointModule/map/components/StationMarker";

/**
 * Map content component with improved clustering
 */
export function MapContent({ 
    chargePoints, 
    selectedChargePoint, 
    onMarkerClick, 
    onInfoWindowClose,
    onClusterClick,
    userLocation,
    isMobile,
    onUserLocationChange,
    hasCenteredToUser,
  }: { 
    readonly chargePoints: ChargePoint[];
    readonly selectedChargePoint: ChargePoint | null;
    readonly onMarkerClick: (chargePoint: ChargePoint) => void;
    readonly onInfoWindowClose: () => void;
    readonly onClusterClick: (chargePoints: ChargePoint[]) => void;
    readonly userLocation: { lat: number; lng: number } | null;
    readonly isMobile: boolean;
    readonly onUserLocationChange: (loc: { lat: number; lng: number }) => void;
    readonly hasCenteredToUser?: boolean;
  }) {
    const map = useMap();
  const [clusterer, setClusterer] = useState<MarkerClusterer | null>(null);
  const hasInitialUserCenter = useRef(false);
  const hasManualCentered = useRef(false);
    const { theme } = useTheme();
    const [baseBrandColor, setBaseBrandColor] = useState('#3B82F6');
    useEffect(() => {
      const frame = requestAnimationFrame(() => {
        const cssColor = getComputedStyle(document.documentElement)
          .getPropertyValue('--color-brand-500')
          .trim();
        if (cssColor) setBaseBrandColor(cssColor);
      });
      return () => cancelAnimationFrame(frame);
    }, []);

    // Derive brand colors
    const base = colord(baseBrandColor);
    const adjustedBase = theme === 'dark'
      ? base.lighten(0.15).saturate(0.1)
      : base;
    const userOuterBg = adjustedBase.alpha(theme === 'dark' ? 0.28 : 0.2).toRgbString();
    const userBorder = adjustedBase.alpha(theme === 'dark' ? 0.6 : 0.4).toRgbString();
    const userInnerDot = theme === 'dark'
      ? adjustedBase.lighten(0.05).toHex()
      : base.darken(0.08).toHex();
  
    // Initialize the MarkerClusterer with improved settings for zoom levels
    useEffect(() => {
      if (!map) return;
      
      const newClusterer = new MarkerClusterer({ 
        map,
        renderer: {
          render: ({ count, position, markers }) => {
            // Get current zoom level for dynamic sizing
            const currentZoom = map.getZoom() || 10;
            
            // Dynamic sizing based on zoom level and count
            let baseSize: number;
            if (currentZoom < 8) {
              baseSize = 30;      // Smaller for far zoom
            } else if (currentZoom < 12) {
              baseSize = 40;      // Medium for medium zoom
            } else {
              baseSize = 50;      // Larger for close zoom
            }
            
            const size = Math.min(baseSize + (count * 1.5), baseSize + 25);
            
            // Color based on count
            let color: string;
            if (count < 5) {
              color = '#10B981';
            } else if (count < 15) {
              color = '#F59E0B';
            } else {
              color = '#EF4444';
            }
  
            // Extract charge points from markers
            const clusterChargePoints = markers
              .map(marker => (marker as any).chargePoint)
              .filter(Boolean) as ChargePoint[];
            
            return new google.maps.marker.AdvancedMarkerElement({
              position,
              content: createImprovedClusterIcon(count, color, size, currentZoom, () => {
                onClusterClick(clusterChargePoints);
              }),
              zIndex: 1000 + count,
            });
          },
        },
      });
      
      setClusterer(newClusterer);
      
      return () => {
        newClusterer?.clearMarkers();
      };
    }, [map]);
  
    // Set map bounds when charge points load (desktop-focused logic with padding for side panels)
    useEffect(() => {
      if (!map) return;
      const isMobileView = typeof window !== 'undefined' ? window.innerWidth < 1024 : false;

      // Mobile behavior: already handled by centering on user if available
      if (isMobileView && userLocation) {
        if (!hasInitialUserCenter.current) {
          map.setCenter(userLocation);
          map.setZoom(15);
          hasInitialUserCenter.current = true;
          hasManualCentered.current = true; // Mark as manually centered to prevent fitBounds override
        }
        return;
      }

      // Desktop logic
      // Skip fitBounds if we've already centered to user location to prevent override
      // This prevents the map from jumping to a random location when window size is normal
      if ((hasCenteredToUser || hasManualCentered.current) && userLocation) {
        return;
      }

      const timer = setTimeout(() => {
        // If no stations but we have user, center there
        if (chargePoints.length === 0 && userLocation) {
          map.setCenter(userLocation);
          map.setZoom(14);
          return;
        } else if (chargePoints.length === 0) {
          return; // nothing to fit
        }

        const bounds = new google.maps.LatLngBounds();
        let anyExtended = false;

        // Extend by charge points
        chargePoints.forEach(cp => {
          if (cp.coordinates) {
            bounds.extend({ lat: cp.coordinates[0], lng: cp.coordinates[1] });
            anyExtended = true;
          }
        });

        // Also extend by user location (helps center cluster around user if they are near edge)
        if (userLocation) {
          bounds.extend(userLocation);
          anyExtended = true;
        }

        if (anyExtended && !bounds.isEmpty()) {
          map.fitBounds(bounds, {
            top: 100,
            right: 80,
            bottom: 100,
            left: 420,
          });

          const listener = google.maps.event.addListenerOnce(map, 'bounds_changed', () => {
            const currentZoom = map.getZoom();
            if (currentZoom && currentZoom > 16) map.setZoom(16);

            // Post-fit adjustments: if span is too large, gently zoom in; if too small, zoom out a bit
            const ne = bounds.getNorthEast();
            const sw = bounds.getSouthWest();
            const latSpan = Math.abs(ne.lat() - sw.lat());
            const lngSpan = Math.abs(ne.lng() - sw.lng());
            const maxSpan = Math.max(latSpan, lngSpan);
            if (maxSpan > 1.5 && currentZoom && currentZoom < 10) { // world-ish view, tighten
              map.setZoom(11);
            } else if (maxSpan < 0.01 && currentZoom && currentZoom > 15) { // extremely tight cluster
              map.setZoom(15);
            }
          });
          return () => google.maps.event.removeListener(listener);
        }
      }, 120);
      return () => clearTimeout(timer);
    }, [map, chargePoints, userLocation, hasCenteredToUser]);

    // If user location appears after stations loaded on mobile but we already did a broad fit, recenter anyway
    useEffect(() => {
      if (!map || !userLocation) return;
      const isMobileView = typeof window !== 'undefined' ? window.innerWidth < 1024 : false;
      if (!isMobileView) return;
      if (!hasInitialUserCenter.current) {
        const t = setTimeout(() => {
          map.setCenter(userLocation);
          map.setZoom(15);
          hasInitialUserCenter.current = true;
        }, 50);
        return () => clearTimeout(t);
      }
    }, [map, userLocation]);
  
    return (
      <>
        {/* User location marker */}
        {userLocation && (
          <AdvancedMarker
            position={{ lat: userLocation.lat, lng: userLocation.lng }}
            zIndex={1}
            title="Your location"
          >
            <div className="relative" style={{ pointerEvents: 'none' }}>
              {/* Outer translucent circle */}
              <div className="w-9 h-9 rounded-full border" style={{ backgroundColor: userOuterBg, borderColor: userBorder }} />
              {/* Pulsing effect ring */}
              <div className="absolute inset-0 rounded-full animate-ping" style={{ border: `2px solid ${userBorder}` }} />
              {/* Inner solid dot */}
              <div className="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-2.5 h-2.5 rounded-full shadow-sm" style={{ backgroundColor: userInnerDot }} />
            </div>
          </AdvancedMarker>
        )}
  
        {/* Locate me control */}
        <div className="absolute right-4 mb-12 bottom-12 md:mb-4 md:bottom-8 z-20">
          <button
            aria-label="Center to my location"
            className="h-12 w-12 rounded-full bg-white/90 backdrop-blur-md shadow-xl border border-gray-200 flex items-center justify-center hover:bg-white dark:bg-gray-900/80 dark:border-gray-700 active:scale-95 transition"
            onClick={() => {
              hasManualCentered.current = true;
              if (!navigator.geolocation) {
                if (userLocation && map) {
                  map.panTo(userLocation);
                  const currentZoom = map.getZoom() || 12;
                  if (currentZoom < 14) map.setZoom(14);
                }
                return;
              }
              navigator.geolocation.getCurrentPosition(
                (pos) => {
                  const loc = { lat: pos.coords.latitude, lng: pos.coords.longitude };
                  onUserLocationChange(loc);
                  if (map) {
                    map.panTo(loc);
                    const currentZoom = map.getZoom() || 12;
                    if (currentZoom < 15) map.setZoom(15);
                  }
                },
                () => {
                  if (userLocation && map) {
                    map.panTo(userLocation);
                    const currentZoom = map.getZoom() || 12;
                    if (currentZoom < 14) map.setZoom(14);
                  }
                },
                { enableHighAccuracy: true, timeout: 8000, maximumAge: 10000 }
              );
            }}
          >
            <LocateFixed className="h-5 w-5 text-gray-700 dark:text-gray-200" />
          </button>
        </div>
  
        {/* Charge point markers - temporarily convert to Station for compatibility */}
        {chargePoints.map(chargePoint => {
          // Quick conversion for marker compatibility
          const stationForMarker = {
            id: chargePoint.id || '',
            name: chargePoint.name,
            address: chargePoint.description || 'No description',
            online: chargePoint.online || false,
            city: 'Location',
            imageUrl: '',
            rating: 0,
            connectors: chargePoint.connectors || [],
            location: {
              latitude: chargePoint.coordinates?.[0] || 0,  // lat is at index 0
              longitude: chargePoint.coordinates?.[1] || 0, // lng is at index 1
            }
          };
          
          return (
            <StationMarker
              key={chargePoint.id}
              station={stationForMarker}
              onClick={() => onMarkerClick(chargePoint)}
              isSelected={selectedChargePoint?.id === chargePoint.id}
              clusterer={clusterer}
            />
          );
        })}
      </>
    );
  }

  /**
   * Creates an improved cluster icon with better zoom-based styling
   */
  function createImprovedClusterIcon(count: number, color: string, size: number, zoomLevel: number, onClick?: () => void): HTMLElement {
    const div = document.createElement('div');
    
    // Adjust font size based on zoom level
    let fontSize: number;
    if (zoomLevel < 8) {
      fontSize = 12;
    } else if (zoomLevel < 12) {
      fontSize = 14;
    } else {
      fontSize = 16;
    }
    
    div.style.cssText = `
      width: ${size}px;
      height: ${size}px;
      background: ${color};
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      color: white;
      font-weight: bold;
      font-size: ${fontSize}px;
      border: 3px solid white;
      box-shadow: 0 4px 12px rgba(0,0,0,0.25);
      cursor: pointer;
      transition: all 0.2s ease;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    `;
    
    div.textContent = count > 99 ? '99+' : count.toString();
    
    // Add click/touch handlers if provided for immediate mobile tap
    if (onClick) {
      div.addEventListener('click', onClick);
      div.addEventListener('touchend', (e) => {
        e.preventDefault();
        onClick();
      }, { passive: false });
      div.addEventListener('pointerup', (e) => {
        // quick pointer fallback
        onClick();
      });
    }
    
    // Enhanced hover effects
    div.addEventListener('mouseenter', () => {
      div.style.transform = 'scale(1.15)';
      div.style.boxShadow = '0 6px 20px rgba(0,0,0,0.35)';
      div.style.zIndex = '9999';
    });
    
    div.addEventListener('mouseleave', () => {
      div.style.transform = 'scale(1)';
      div.style.boxShadow = '0 4px 12px rgba(0,0,0,0.25)';
    });
    
    return div;
  }
