'use client';

import React, { useEffect, useState, useCallback } from 'react';
import { APIProvider, Map, ColorScheme, useMap } from '@vis.gl/react-google-maps';
import { ChargePoint } from '@/types/chargepoint/chargepoint';
import { ResponsiveChargePointInfo } from '@/modules/chargepointModule/map/components/ResponsiveStationInfo';
import { ResponsiveClusterInfo } from '@/modules/chargepointModule/map/components/ResponsiveClusterInfo';
import { MobileFilterModal, FilterState } from '@/modules/chargepointModule/map/components/MobileFilterModal';
import { DesktopFilterPanel } from '@/modules/chargepointModule/map/components/DesktopFilterPanel';
import { MobileFilterButton } from '@/modules/chargepointModule/map/components/MobileFilterButton';
import { MapPin } from 'lucide-react';
import { useNavigation } from '@/hooks/useNavigation';
import { useTheme } from '@/context/ThemeContext';
import { MapContent } from './MapContent';
import { FindNearestButton } from '../components/FindNearestButton';

interface MapClientWithFiltersProps {
  readonly initialStations: ChargePoint[];
  readonly apiKey: string;
  readonly mapId: string;
}

/**
 * Enhanced map component with filters, refresh, location detection, and improved clustering
 */
export function MapClientWithFilters({ initialStations, apiKey, mapId }: MapClientWithFiltersProps) {
  const { theme } = useTheme();
  const [colorScheme, setColorScheme] = useState<ColorScheme>('FOLLOW_SYSTEM');  
  const { isMobile } = useNavigation();
  const [chargePoints, setChargePoints] = useState<ChargePoint[]>(initialStations);
  const [filteredChargePoints, setFilteredChargePoints] = useState<ChargePoint[]>(initialStations);
  const [selectedChargePoint, setSelectedChargePoint] = useState<ChargePoint | null>(null);
  
  const [showWelcomeBanner, setShowWelcomeBanner] = useState(true);
  const [clusterChargePoints, setClusterChargePoints] = useState<ChargePoint[] | null>(null);
  const [isMapLoaded, setIsMapLoaded] = useState(false);
  const [userLocation, setUserLocation] = useState<{ lat: number; lng: number } | null>(null);
  const [locationPermissionAsked, setLocationPermissionAsked] = useState(false);
  
  const [showDesktopFilters, setShowDesktopFilters] = useState(false);
  const [mapInstance, setMapInstance] = useState<google.maps.Map | null>(null);
  const [showMobileFilterModal, setShowMobileFilterModal] = useState(false);
  
  const [isRefreshing, setIsRefreshing] = useState(false);
  const [mapCenter, setMapCenter] = useState<{ lat: number; lng: number } | null>(null);
  const [isDesktopDrawerOpen, setIsDesktopDrawerOpen] = useState(false);
  const [hasCenteredOnce, setHasCenteredOnce] = useState(false);
  
  const [filters, setFilters] = useState<FilterState>({
    searchQuery: '',
    statusFilter: 'all',
    connectorType: 'all',
    showOnlyFastChargers: false,
  });

  useEffect(() => {
    if (theme === 'dark') {
      setColorScheme('DARK');
    } else {
      setColorScheme('LIGHT');
    }
  }, [theme]);

  // Request user location on first load
  useEffect(() => {
    if (!locationPermissionAsked) {
      setLocationPermissionAsked(true);
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
          (position) => {
            const location = {
              lat: position.coords.latitude,
              lng: position.coords.longitude,
            };
            setUserLocation(location);
            // Only set initial map center if not already set
            if (!mapCenter) {
              setMapCenter(location);
            }
          },
          (error) => {
            console.info('Location permission denied or unavailable:', error);
            // Fallback to default location (San Francisco)
            const defaultLocation = { lat: -6.2042007, lng: 106.8175586 };
            // Only set initial map center if not already set
            if (!mapCenter) { 
              setMapCenter(defaultLocation);
            }
          }
        );
      } else {
        const defaultLocation = { lat: -6.2042007, lng: 106.8175586 };
        setUserLocation(defaultLocation);
        // Only set initial map center if not already set
        if (!mapCenter) {
          setMapCenter(defaultLocation);
        }
      }
    }
  }, [locationPermissionAsked, mapCenter]);

  // When we obtain a user location and the map instance is ready, ensure the map
  // is centered on the user's marker and zoomed in closer for desktop experience.
  useEffect(() => {
    if (!hasCenteredOnce && mapInstance && userLocation) {
      try {
        // center on user's location and zoom in
        mapInstance.setCenter(userLocation as google.maps.LatLngLiteral);
        // prefer a relatively close zoom so the user marker is dead-center
        const preferredZoom = 17;
        mapInstance.setZoom(preferredZoom);
        setHasCenteredOnce(true);
      } catch (e) {
        // ignore errors from map API
      }
    }
  }, [mapInstance, userLocation, hasCenteredOnce]);

  // Filter charge points based on current filters
  const applyFilters = useCallback(() => {
    let filtered = [...chargePoints];

    // Search filter
    if (filters.searchQuery.trim()) {
      const query = filters.searchQuery.toLowerCase();
      filtered = filtered.filter(chargePoint =>
        chargePoint.name.toLowerCase().includes(query) ||
        chargePoint.description?.toLowerCase().includes(query)
      );
    }

    // Status filter
    if (filters.statusFilter !== 'all') {
      filtered = filtered.filter(chargePoint => {
        const connectors = chargePoint.connectors || [];
        const hasStatus = connectors.some(connector => {
          switch (filters.statusFilter) {
            case 'available':
              return connector.status === 'Available';
            case 'charging':
              return connector.status === 'Charging';
            case 'unavailable':
              return connector.status === 'Faulted' || connector.status === 'SuspendedEV' || connector.status === 'SuspendedEVSE';
            default:
              return true;
          }
        });
        return hasStatus;
      });
    }

    // Connector type filter
    if (filters.connectorType !== 'all') {
      filtered = filtered.filter(chargePoint => {
        const connectors = chargePoint.connectors || [];
        return connectors.some(connector => {
          // Normalize to uppercase for case-insensitive comparison
          const connectorTypeUpper = connector.type?.toUpperCase() || '';
          const filterTypeUpper = filters.connectorType.toUpperCase();
          return connectorTypeUpper.includes(filterTypeUpper);
        });
      });
    }

    // Fast charger filter (>50kW)
    if (filters.showOnlyFastChargers) {
      filtered = filtered.filter(chargePoint => {
        const connectors = chargePoint.connectors || [];
        return connectors.some(connector => (connector.power || 0) > 50);
      });
    }

    setFilteredChargePoints(filtered);
  }, [chargePoints, filters]);

  useEffect(() => {
    applyFilters();
  }, [applyFilters]);

  const handleMarkerClick = (chargePoint: ChargePoint) => {
    // Check if there are other charge points with the same coordinates
    if (chargePoint.coordinates && chargePoint.coordinates.length === 2) {
      const [lat, lng] = chargePoint.coordinates;
      const sameLocationChargePoints = filteredChargePoints.filter(cp => {
        if (!cp.coordinates || cp.coordinates.length !== 2) return false;
        const [cpLat, cpLng] = cp.coordinates;
        // Compare coordinates with small tolerance for floating point precision
        return Math.abs(cpLat - lat) < 0.000001 && Math.abs(cpLng - lng) < 0.000001;
      });

      // If there are multiple charge points at the same location, show cluster list
      if (sameLocationChargePoints.length > 1) {
        setClusterChargePoints(sameLocationChargePoints);
        setSelectedChargePoint(null); // Close single charge point info if open
        return;
      }
    }

    // Single charge point at this location, show normal info
    setSelectedChargePoint(chargePoint);
    setClusterChargePoints(null); // Close cluster list if open
  };

  const handleClusterClick = (chargePoints: ChargePoint[]) => {
    setClusterChargePoints(chargePoints);
    setSelectedChargePoint(null); // Close charge point info if open
  };

  const handleInfoWindowClose = () => {
    setSelectedChargePoint(null);
    setIsDesktopDrawerOpen(false); // Reset the drawer state here
  };

  const handleClusterListClose = () => {
    setClusterChargePoints(null);
  };

  const handleChargePointSelectFromCluster = (chargePoint: ChargePoint) => {
    setSelectedChargePoint(chargePoint);
    setClusterChargePoints(null); // Close cluster list
  };

  const handleMapLoad = () => {
    setIsMapLoaded(true);
    // Auto-hide welcome banner after 5 seconds
    setTimeout(() => setShowWelcomeBanner(false), 5000);
  };

  const handleRefresh = async () => {
    setIsRefreshing(true);
    try {
      await new Promise(resolve => setTimeout(resolve, 1000));
      setChargePoints([...initialStations]);
      applyFilters();
    } finally {
      setIsRefreshing(false);
    }
  };

  const clearFilters = () => {
    setFilters({
      searchQuery: '',
      statusFilter: 'all',
      connectorType: 'all',
      showOnlyFastChargers: false,
    });
  };

  const gestureHandlingMode = isMobile ? 'greedy' : 'auto';
  // Helper component to capture map instance after mount
  const MapInstanceCatcher = () => {
    const map = useMap();
    useEffect(() => {
      if (map && !mapInstance) setMapInstance(map as unknown as google.maps.Map);
    }, [map]);
    return null;
  };
  return (
    <div className="relative w-full h-full">
      {/* Loading overlay */}
      {!isMapLoaded && (
        <div className="absolute inset-0 bg-white z-50 flex items-center justify-center dark:bg-gray-900">
          <div className="text-center">
            <div className="w-12 h-12 border-4 border-blue-200 border-t-blue-600 rounded-full animate-spin mx-auto mb-4 dark:border-blue-200 dark:border-t-blue-600"></div>
            <p className="text-gray-600 font-medium dark:text-gray-400">Loading map...</p>
            {userLocation && <p className="text-sm text-gray-500 mt-2">📍 Using your location</p>}
          </div>
        </div>
      )}

      {/* Desktop Filter Panel */}
      <DesktopFilterPanel
        isOpen={showDesktopFilters}
        filters={filters}
        filteredCount={filteredChargePoints.length}
        totalCount={chargePoints.length}
        isRefreshing={isRefreshing}
        onToggle={() => setShowDesktopFilters(!showDesktopFilters)}
        onFiltersChange={setFilters}
        onClearFilters={clearFilters}
        onRefresh={handleRefresh}
        extraButtons={
          <FindNearestButton
            chargePoints={filteredChargePoints}
            userLocation={userLocation}
            onUserLocationChange={setUserLocation}
            onSelectStation={(cp: ChargePoint) => setSelectedChargePoint(cp)}
            mapRef={mapInstance}
            variant="desktop"
          />
        }
      />

      {/* Mobile Filter Button */}
      <MobileFilterButton
        filteredCount={filteredChargePoints.length}
        totalCount={chargePoints.length}
        isRefreshing={isRefreshing}
        onFilterClick={() => setShowMobileFilterModal(true)}
        onRefresh={handleRefresh}
        extraButton={
          <FindNearestButton
            chargePoints={filteredChargePoints}
            userLocation={userLocation}
            onUserLocationChange={setUserLocation}
            onSelectStation={(cp: ChargePoint) => setSelectedChargePoint(cp)}
            mapRef={mapInstance}
            variant="mobile"
          />
        }
      />

      {/* Mobile Filter Modal */}
      <MobileFilterModal
        isOpen={showMobileFilterModal}
        filters={filters}
        filteredCount={filteredChargePoints.length}
        totalCount={chargePoints.length}
        onClose={() => setShowMobileFilterModal(false)}
        onFiltersChange={setFilters}
        onClearFilters={clearFilters}
      />

      {/* Welcome Banner */}
      {showWelcomeBanner && isMapLoaded && (
        <div className="absolute bottom-4 left-4 right-4 md:bottom-6 md:left-1/2 md:right-auto md:transform md:-translate-x-1/2 z-20 md:max-w-md md:mx-auto">
          <div className="bg-white/95 backdrop-blur-sm rounded-2xl shadow-xl border border-gray-200/50 p-3 md:p-4 dark:bg-gray-900/95 dark:border-gray-700/50">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-2 md:gap-3">
                <div className="w-8 h-8 md:w-10 md:h-10 rounded-xl flex items-center justify-center">
                  <MapPin className="w-4 h-4 md:w-5 md:h-5 text-blue-600 dark:text-blue-400" />
                </div>
                <div>
                  <p className="font-medium text-gray-900 text-sm md:text-base dark:text-gray-100">Welcome to EV Station Finder</p>
                  <p className="text-xs md:text-sm text-gray-600 dark:text-gray-400">Use filters to find the perfect charging station</p>
                </div>
              </div>
              <button
                onClick={() => setShowWelcomeBanner(false)}
                className="text-gray-400 hover:text-gray-600 transition-colors dark:text-gray-400 dark:hover:text-gray-600"
              >
                <svg className="w-4 h-4 md:w-5 md:h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </div>
          </div>
        </div>
      )}

      {/* Map Container with Rounded Corners */}
      <div className={`absolute inset-0 overflow-hidden transition-all duration-300 ${isDesktopDrawerOpen ? 'blur-[2px] brightness-75' : ''} dark:bg-gray-900`}>
        <APIProvider apiKey={apiKey}>
          <Map 
            mapId={mapId}
            colorScheme={colorScheme}
            gestureHandling={gestureHandlingMode} 
            style={{ width: '100%', height: '100%' }}
            defaultZoom={12}
            minZoom={4}
            defaultCenter={mapCenter || userLocation || { lat: -6.2042007, lng: 106.8175586 }}
            cameraControl={false}
            disableDefaultUI={false}
            zoomControl={false}
            keyboardShortcuts={true}
            mapTypeControl={false}
            
            scaleControl={false}
            streetViewControl={false}
            rotateControl={false}
            fullscreenControl={true}
            onTilesLoaded={handleMapLoad}
          >
            <MapInstanceCatcher />
            <MapContent 
              chargePoints={filteredChargePoints}
              selectedChargePoint={selectedChargePoint}
              onMarkerClick={handleMarkerClick}
              onInfoWindowClose={handleInfoWindowClose}
              onClusterClick={handleClusterClick}
              userLocation={userLocation}
              isMobile={isMobile}
              onUserLocationChange={setUserLocation}
              hasCenteredToUser={hasCenteredOnce}
            />
            {/* Nearest buttons now embedded via panel / mobile button props */}
          </Map>
        </APIProvider>
      </div>

      {/* Charge Point Info - Outside map container to avoid blur */}
      {selectedChargePoint && (
        <ResponsiveChargePointInfo
          chargePoint={selectedChargePoint}
          onClose={handleInfoWindowClose}
          isMobile={isMobile}
          onDrawerStateChange={setIsDesktopDrawerOpen}
        />
      )}

      {/* Cluster List - Outside map container to avoid blur */}
      {clusterChargePoints && (
        <ResponsiveClusterInfo
          stations={clusterChargePoints.map(cp => ({
            id: cp.id || '',
            name: cp.name,
            address: cp.description || 'No description',
            online: cp.online || false,
            city: 'Location',
            imageUrl: '',
            rating: 0,
            connectors: cp.connectors || [],
            location: {
              latitude: cp.coordinates?.[0] || 0,  // lat is at index 0
              longitude: cp.coordinates?.[1] || 0, // lng is at index 1
            }
          }))}
          onClose={handleClusterListClose}
          onStationSelect={(station) => {
            const originalChargePoint = clusterChargePoints.find(cp => cp.id === station.id);
            if (originalChargePoint) {
              handleChargePointSelectFromCluster(originalChargePoint);
            }
          }}
          isMobile={isMobile}
        />
      )}
    </div>
  );
}
