/**
 * useSimulatedGuidance — the explicit "Simulate drive" / demo mode. Advances a
 * puck along the route by arc-length at the route's OWN average speed (from its
 * real duration), emitting the same GuidanceEvent shape as live GPS.
 *
 * Because it shares `progressAlongRoute` with the live engine, the ETA and
 * remaining-time are correct (derived from the route's real duration, not a
 * fixed cruise speed — which is why the old mock loop showed 8h for a 400km
 * motorway route). Emits a few times a second; ChaseLayer interpolates those
 * fixes to 60fps natively.
 */
import { useEffect } from "react";
import type { GuidanceEvent, Route } from "../../../modules/mapmap-react-native/src/MapmapNav.types";
import { guidanceEventFromProgress, prepareRoute } from "./routeProgress";

// Denser fixes → shorter straight-line hops between on-route points, so the
// camera (and the puck pinned to its centre) cuts corners less.
const TICK_MS = 170;
const FALLBACK_SPEED_MPS = 13.4; // ~30mph, only if the route has no duration

export function useSimulatedGuidance(
  route: Route | undefined,
  active: boolean,
  onEvent: (event: GuidanceEvent) => void
): void {
  useEffect(() => {
    if (!active || !route) return;

    // Precompute the route's constants ONCE (see PreparedRoute) — recomputing
    // these per tick froze the JS thread on long routes.
    const prepared = prepareRoute(route);
    const total = prepared.totalMetres;
    const averageSpeed =
      route.durationSeconds > 0 ? total / route.durationSeconds : FALLBACK_SPEED_MPS;

    let distance = 0;
    let stopped = false;

    const timer = setInterval(() => {
      if (stopped) return;
      distance = Math.min(total, distance + averageSpeed * (TICK_MS / 1000));
      const event = guidanceEventFromProgress(
        route,
        prepared,
        distance,
        averageSpeed,
        undefined,
        false,
        false,
        Date.now()
      );
      onEvent(event);
      if (event.state === "arrived") {
        stopped = true;
        clearInterval(timer);
      }
    }, TICK_MS);

    return () => {
      stopped = true;
      clearInterval(timer);
    };
  }, [route, active, onEvent]);
}
