import React, { useEffect, useMemo, useRef, useState } from 'react';
import {
  GoogleMap,
  Marker,
  InfoWindow,
  DirectionsRenderer,
  useJsApiLoader,
} from '@react-google-maps/api';
import { ITrip } from '@/shared/types/geoloc';
import { primary } from '@/shared/theme/palette';
import { MapType, MarkerType, RouteMarker } from '@/shared/types/Maps';
import MapMarker from './map-marker';
import { StatusColor } from '@/shared/sections/chauffeur/planingChauffeur/utils/schedule-utils';

type Props = {
  trip: ITrip;
  height?: string;
  width?: string;
};

const containerStyleDefault = {
  width: '100%',
  height: '400px',
};
const GOOGLE_MAPS_LIBRARIES: ('places' | 'geometry')[] = ['places', 'geometry'];
const MAX_WAYPOINTS_PER_REQUEST = 25;

export default function GeolocMap({ trip, height = '400px', width = '100%' }: Props) {
  const containerStyle = { ...containerStyleDefault, height, width };
  const mapRef = useRef<google.maps.Map | null>(null);
  const [selectedMarker, setSelectedMarker] = useState<MarkerType | null>(null);

  const [activeInfoIndex, setActiveInfoIndex] = useState<number | null>(null);
  const [directions, setDirections] = useState<google.maps.DirectionsResult | null>(null);
  const animationRef = useRef<number>();
  const [vehiclePos, setVehiclePos] = useState<google.maps.LatLngLiteral | null>(null);

  const { isLoaded } = useJsApiLoader({
    id: 'google-map-script',
    googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY!,
    libraries: GOOGLE_MAPS_LIBRARIES,
  });

  const points = trip.points;
const showMap = isLoaded && points.length >= 2;

  const origin = points[0];
  const destination = points[points.length - 1];
  const waypoints = points.slice(1, -1).map((p) => ({
    location: { lat: p.latitude, lng: p.longitude },
    stopover: false,
  }));

  useEffect(() => {
  if (!isLoaded || !origin || !destination || points.length < 2) return;

    const directionsService = new google.maps.DirectionsService();

    async function fetchDirections() {
      let allLegs: google.maps.DirectionsLeg[] = [];
      let allRoutes: google.maps.DirectionsRoute[] = [];
      let lastOrigin = { lat: origin.latitude, lng: origin.longitude };
      let remainingWaypoints = [...waypoints];

      const fetchRoutePart = (
        start: google.maps.LatLngLiteral,
        end: google.maps.LatLngLiteral,
        partWaypoints: google.maps.DirectionsWaypoint[]
      ) =>
        new Promise<google.maps.DirectionsResult>((resolve, reject) => {
          directionsService.route(
            {
              origin: start,
              destination: end,
              waypoints: partWaypoints,
              travelMode: google.maps.TravelMode.DRIVING,
            },
            (result, status) => {
              if (status === 'OK' && result) resolve(result);
              else reject(`Erreur Directions API : ${status}`);
            }
          );
        });

      try {
        while (remainingWaypoints.length > 0) {
          const part = remainingWaypoints.splice(0, MAX_WAYPOINTS_PER_REQUEST);
          const partDestination =
            part.length > 0
              ? part[part.length - 1].location
              : { lat: destination.latitude, lng: destination.longitude };
          const waypointsForPart = part.length > 1 ? part.slice(0, -1) : [];
          const result = await fetchRoutePart(lastOrigin, partDestination, waypointsForPart);
          allLegs = [...allLegs, ...result.routes[0].legs];
          allRoutes.push(result.routes[0]);
          lastOrigin = partDestination;
        }
        if (lastOrigin.lat !== destination.latitude || lastOrigin.lng !== destination.longitude) {
          const result = await fetchRoutePart(
            lastOrigin,
            { lat: destination.latitude, lng: destination.longitude },
            []
          );
          allLegs = [...allLegs, ...result.routes[0].legs];
          allRoutes.push(result.routes[0]);
        }

        const mergedDirections = {
          ...allRoutes[0],
          legs: allLegs,
        };

        setDirections({
          geocoded_waypoints: [],
          routes: [mergedDirections],
          request: {
            origin: { lat: origin.latitude, lng: origin.longitude },
            destination: { lat: destination.latitude, lng: destination.longitude },
            travelMode: google.maps.TravelMode.DRIVING,
          } as google.maps.DirectionsRequest,
        });
      } catch (error) {
        console.error(error);
      }
    }
    fetchDirections();
  }, [isLoaded, trip]);

  // Animation du marker véhicule le long de la route
 const markers = useMemo<RouteMarker[]>(() => {
  const list: RouteMarker[] = [];

  if (directions) {
    const legs = directions.routes[0].legs;
    const preciseStart = legs[0].start_location;
    const preciseEnd = legs[legs.length - 1].end_location;

    list.push({
      id: 'start-',
      position: { lat: preciseStart.lat(), lng: preciseStart.lng() },
      title: 'Départ',
      icon: '/assets/icons/maps/dynamic/circuit-start.svg',
      color: StatusColor.PRIMARY,
    });

    list.push({
      id: 'end-',
      position: { lat: preciseEnd.lat(), lng: preciseEnd.lng() },
      title: 'Arrivée',
      icon: '/assets/icons/maps/dynamic/circuit-end.svg',
      color: StatusColor.PRIMARY,
    });
  }

  return list;
}, [directions]);

  if (!isLoaded || !origin) return null;

  return (
    <GoogleMap
      mapContainerStyle={containerStyle}
      center={{ lat: origin.latitude, lng: origin.longitude }}
      zoom={13}
      onLoad={(map) => {
        mapRef.current = map;
      }}
    >
      {markers.map((marker) => (
        <MapMarker
          key={marker.id}
          marker={marker}
          selectedMarker={selectedMarker}
          setSelectedMarker={setSelectedMarker}
          Submodule={MapType.CIRCUIT}
        />
      ))}

      {directions && (
        <DirectionsRenderer
          directions={directions}
          options={{
            suppressMarkers: true,
            polylineOptions: {
              strokeColor: primary.main,
              strokeOpacity: 1.0,
              strokeWeight: 4,
            },
          }}
        />
      )}
    </GoogleMap>
  );
}
