import { useLeafletStore } from 'stores/leaflet';
import { storeToRefs } from 'pinia';
import type { routeCoordinates as StoreRouteCoordinates } from 'components/models';

const leafletStore = useLeafletStore();
const { routeSegments, routeDirections, routeCoordinates } = storeToRefs(leafletStore);

type RouteSummary = {
  totalDistance: number;
  totalTime: number;
};

type RouteWaypoint = {
  latLng: {
    lat: number;
    lng: number;
  };
};

type RouteCoordinates = {
  lat: number;
  lng: number;
};

type RouteInstructions = {
  text: string;
  distance: number;
  time: number;
  index: number;
};

type RouteResult = {
  summary?: RouteSummary;
  segments?: RouteSummary[];
  inputWaypoints?: RouteWaypoint[];
  instructions?: RouteInstructions[];
  waypoints?: RouteWaypoint[];
  coordinates?: RouteCoordinates[];
};

function getDistance(a: RouteCoordinates, b: RouteCoordinates) {
  const R = 6371000; // meters
  const toRad = (x: number) => (x * Math.PI) / 180;

  const dLat = toRad(b.lat - a.lat);
  const dLng = toRad(b.lng - a.lng);

  const lat1 = toRad(a.lat);
  const lat2 = toRad(b.lat);

  const aVal = Math.sin(dLat / 2) ** 2 + Math.sin(dLng / 2) ** 2 * Math.cos(lat1) * Math.cos(lat2);

  const c = 2 * Math.atan2(Math.sqrt(aVal), Math.sqrt(1 - aVal));

  return R * c;
}

export function useRoutingEvents() {
  const handleRoutesFound = (event: { routes?: RouteResult[] }) => {
    const route = event.routes?.[0];
    console.log('routesfound event:', event);
    if (!route) {
      return;
    }

    if (route.summary) {
      console.log('Route summary:', route.summary);
    }

    if (route.segments?.length) {
      const segmentSummary = route.segments.map((segment, index) => ({
        fromWaypoint: index,
        toWaypoint: index + 1,
        distanceMeters: segment.totalDistance,
        timeSeconds: segment.totalTime,
        toCoordinates: route.inputWaypoints?.[index + 1]?.latLng ??
          route.waypoints?.[index + 1]?.latLng ?? { lat: 0, lng: 0 },
      }));
      if (routeSegments) {
        routeSegments.value = segmentSummary;
      }
      console.log('Waypoint segment summary:', segmentSummary);
    }

    if (route.instructions?.length) {
      const directionsSummary = route.instructions.map((direction, inx) => ({
        dirIndex: inx,
        coordinateIndex: direction.index,
        text: direction.text,
        distance: direction.distance,
        time: direction.time,
        coordinates: {
          lat: route.coordinates?.[direction.index]?.lat,
          lng: route.coordinates?.[direction.index]?.lng,
        },
      }));
      console.log('Direction waypoint segment summary:', directionsSummary);
      if (routeDirections) {
        routeDirections.value = directionsSummary;
      }
    }

    if (route.coordinates?.length) {
      const coordinatesAll: StoreRouteCoordinates[] = [];

      const instructions = route.instructions || [];
      const coords = route.coordinates;

      for (let i = 0; i < instructions.length; i++) {
        const current = instructions[i];
        if (!current) {
          continue;
        }

        const next = instructions[i + 1];

        const startIndex = current.index;
        const endIndex = Math.min(next ? next.index : coords.length - 1, coords.length - 1);
        if (startIndex < 0 || startIndex > endIndex) {
          continue;
        }

        // slice this segment
        const segmentCoords = coords.slice(startIndex, endIndex + 1);

        // calculate distances between each pair
        let totalSegmentDistance = 0;

        for (let j = 0; j < segmentCoords.length - 1; j++) {
          const from = segmentCoords[j];
          const to = segmentCoords[j + 1];
          if (from && to) {
            totalSegmentDistance += getDistance(from, to);
          }
        }

        // distribute time proportionally
        for (let j = 0; j < segmentCoords.length; j++) {
          const coord = segmentCoords[j];
          if (!coord) {
            continue;
          }

          const coordIndex = startIndex + j;
          const previousCoord = j === 0 ? undefined : segmentCoords[j - 1];
          const segmentDistance = previousCoord ? getDistance(previousCoord, coord) : 0;

          const timePortion =
            totalSegmentDistance > 0 ? (segmentDistance / totalSegmentDistance) * current.time : 0;

          coordinatesAll[coordIndex] = {
            coordinateIndex: coordIndex,
            lat: coord.lat,
            lng: coord.lng,
            distanceFromPrev: segmentDistance,
            timeFromPrev: timePortion,
            instruction: j === 0 ? current.text : '',
          };
        }
      }
      console.log('Coordinates:', coordinatesAll);
      if (routeCoordinates) {
        routeCoordinates.value = coordinatesAll;
      }
      }
  };



  return {
    handleRoutesFound,
  };
}
