import { useState, useEffect, useCallback, useRef } from 'react';
import { useJsApiLoader, GoogleMap, Marker, InfoWindow } from '@react-google-maps/api';
import { Loader2, MapPin } from 'lucide-react';
import { PIPELINE } from '../../api/config';
import { dailyReportsClient } from '../../api/clients';

interface StoreLocation {
  latitude: number;
  longitude: number;
}

interface Store {
  area: string;
  business_name: string;
  distance_km: number;
  location: StoreLocation;
  route_name: string;
  store_code: string;
}

interface NearestStoresResponse {
  message: string;
  response: {
    count: number;
    stores: Store[];
    success: boolean;
  };
}

const mapContainerStyle = {
  width: '100%',
  height: '100%',
  borderRadius: '0px'
};

const defaultCenter = { lat: 12.9716, lng: 77.5946 };

export function DailyLogMap({ 
  latitude, 
  longitude,
  showStoreList = false
}: { 
  latitude?: number | string | null; 
  longitude?: number | string | null;
  showStoreList?: boolean;
}) {
  const [userLocation, setUserLocation] = useState<{ lat: number, lng: number } | null>(null);
  const [stores, setStores] = useState<Store[]>([]);
  const [selectedStore, setSelectedStore] = useState<Store | null>(null);
  const [error, setError] = useState<string | null>(null);
  const mapRef = useRef<google.maps.Map | null>(null);

  const { isLoaded } = useJsApiLoader({
    id: 'google-map-script',
    googleMapsApiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY || ''
  });

  const fetchNearestStores = async (lat: number, lng: number) => {
    try {
      const data = await dailyReportsClient.request<NearestStoresResponse>(
        'POST',
        PIPELINE.endpoints.nearestStores,
        {
          latitude: lat,
          longitude: lng
        },
        {
          'accept': 'application/json, text/plain, */*',
          'groupid': '25',
          'orgid': '57',
          'templateid': '189',
          'x-pipeline-version': 'draft'
        }
      );

      if (data.response && data.response.stores) {
        setStores(data.response.stores);
      }
    } catch (err: any) {
      console.error('An error occurred while fetching stores.', err);
    }
  };

  useEffect(() => {
    // If coords provided in props, use them
    if (latitude && longitude && String(latitude).trim() !== '—' && String(longitude).trim() !== '—') {
        const lat = Number(latitude);
        const lng = Number(longitude);
        if (!isNaN(lat) && !isNaN(lng)) {
          setUserLocation({ lat, lng });
          fetchNearestStores(lat, lng);
          return;
        }
    }

    // Otherwise fallback to whatever tactic used for mobile
    if (!navigator.geolocation) {
      setError('Geolocation is not supported by your browser.');
      return;
    }

    navigator.geolocation.getCurrentPosition(
      (position) => {
        const lat = position.coords.latitude;
        const lng = position.coords.longitude;
        setUserLocation({ lat, lng });
        fetchNearestStores(lat, lng);
      },
      (err) => {
        setError(err.message || 'Failed to get location');
      },
      { enableHighAccuracy: true }
    );
  }, [latitude, longitude]);

  const onLoad = useCallback(function callback(map: google.maps.Map) {
    mapRef.current = map;
    if (userLocation) {
      const bounds = new window.google.maps.LatLngBounds();
      bounds.extend(userLocation);
      map.fitBounds(bounds);
      
      const listener = window.google.maps.event.addListener(map, 'idle', () => {
          if (map.getZoom()! > 15) {
              map.setZoom(15);
          }
          window.google.maps.event.removeListener(listener);
      });
    }
  }, [userLocation]);

  useEffect(() => {
    if (mapRef.current && userLocation && stores.length > 0) {
      const bounds = new window.google.maps.LatLngBounds();
      bounds.extend(userLocation);
      stores.forEach(store => {
        if (store.location) {
          const lat = Number(store.location.latitude);
          const lng = Number(store.location.longitude);
          if (!isNaN(lat) && !isNaN(lng)) {
            bounds.extend({ lat, lng });
          }
        }
      });
      mapRef.current.fitBounds(bounds);
    }
  }, [stores, userLocation]);

  if (!isLoaded) {
    return (
      <div className="w-full h-[320px] flex items-center justify-center bg-slate-50 rounded-xl border border-slate-200">
        <Loader2 className="w-8 h-8 text-slate-400 animate-spin" />
      </div>
    );
  }

  return (
    <div className="w-full h-full flex flex-col bg-transparent min-h-[320px]">
      {error && (
        <div className="bg-red-50 text-red-600 p-3 mb-4 rounded-lg text-sm border border-red-100">
          {error}
        </div>
      )}

      <div className="w-full min-h-[320px] flex-1 relative rounded-none border border-slate-200 rounded-xl overflow-hidden">
        <GoogleMap
          mapContainerStyle={mapContainerStyle}
          center={userLocation || defaultCenter}
          zoom={userLocation ? 13 : 5}
          onLoad={onLoad}
          options={{
            streetViewControl: false,
            mapTypeControl: false,
            fullscreenControl: false
          }}
        >
          {/* User's Current Location Marker */}
          {userLocation && (
            <Marker
              position={userLocation}
              icon={{
                url: 'http://maps.google.com/mapfiles/ms/icons/blue-dot.png'
              }}
              title="Location"
            />
          )}

          {/* Stores Markers */}
          {stores.map((store) => {
            if (!store.location) return null;
            const lat = Number(store.location.latitude);
            const lng = Number(store.location.longitude);
            if (isNaN(lat) || isNaN(lng)) return null;

            return (
              <Marker
                key={store.store_code}
                position={{ lat, lng }}
                onClick={() => setSelectedStore(store)}
                title={store.business_name}
              />
            );
          })}

          {/* Info Window for Selected Store */}
          {selectedStore && selectedStore.location && !isNaN(Number(selectedStore.location.latitude)) && (
            <InfoWindow
              position={{ lat: Number(selectedStore.location.latitude), lng: Number(selectedStore.location.longitude) }}
              onCloseClick={() => setSelectedStore(null)}
            >
              <div className="p-1 max-w-[200px]">
                <h3 className="font-semibold text-sm text-slate-800">{selectedStore.business_name}</h3>
                <p className="text-xs text-slate-500 mt-1">{selectedStore.area}</p>
                <div className="flex justify-between items-center mt-2 pt-2 border-t border-slate-100">
                  <span className="text-[10px] bg-blue-50 text-blue-600 px-1.5 py-0.5 rounded border border-blue-100">
                    {selectedStore.route_name}
                  </span>
                  <span className="text-[10px] text-slate-400 font-medium">
                    {selectedStore.distance_km} km
                  </span>
                </div>
              </div>
            </InfoWindow>
          )}
        </GoogleMap>
      </div>

      {showStoreList && (
        <div className="mt-4 p-5 flex flex-col gap-4 bg-[var(--tiles-card-bg)] rounded-xl border border-slate-200">
           <h3 className="font-bold text-slate-800 text-sm m-0 flex items-center gap-2 uppercase tracking-wider">
             <MapPin size={16} className="text-slate-500" /> Nearby Stores
           </h3>
           <div className="flex flex-col gap-3">
             {stores.length > 0 ? (
               stores.map((store) => (
                 <div key={store.store_code} className="flex flex-col p-3 rounded-lg border border-slate-100 bg-slate-50 hover:bg-slate-100 transition-colors cursor-pointer" onClick={() => setSelectedStore(store)}>
                   <span className="font-bold text-slate-800 text-sm">{store.business_name}</span>
                   <span className="text-xs text-slate-500">{store.store_code}</span>
                   {store.distance_km != null && (
                      <span className="text-xs text-[#1b37a5] font-semibold mt-1">{store.distance_km.toFixed(2)} km away</span>
                   )}
                 </div>
               ))
             ) : (
               <span className="text-sm text-slate-400 italic">No nearby stores found.</span>
             )}
           </div>
        </div>
      )}
    </div>
  );
}
