import { geoConfig } from "./config";
import type { Coordinates, OsrmTableResult } from "./types";

/**
 * Ruft die OSRM-`/table`-Matrix von genau EINER Quelle zu mehreren Zielen ab.
 * Koordinaten in OSRM-Reihenfolge `lng,lat`. `sources=0` + Annotationen
 * `duration,distance`. Wirft bei Netz-/HTTP-Fehler oder `code != "Ok"`, damit
 * der Aufrufer (orderByEintreffzeit) auf Haversine zurückfallen kann.
 */
export async function etaTable(
  origin: Coordinates,
  destinations: Coordinates[],
): Promise<OsrmTableResult> {
  const all: Coordinates[] = [origin, ...destinations];
  const coordParam = all.map((c) => `${c.lng},${c.lat}`).join(";");
  const url =
    `${geoConfig.osrmUrl}/table/v1/driving/${coordParam}` +
    `?sources=0&annotations=duration,distance`;

  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), geoConfig.httpTimeoutMs);
  try {
    const res = await fetch(url, { signal: controller.signal });
    if (!res.ok) {
      throw new Error(`OSRM HTTP ${res.status}`);
    }
    const json = (await res.json()) as {
      code?: string;
      durations?: (number | null)[][];
      distances?: (number | null)[][];
    };
    if (json.code !== "Ok" || !json.durations) {
      throw new Error(`OSRM code ${json.code ?? "unbekannt"}`);
    }
    return {
      durations: json.durations,
      distances: json.distances ?? [],
    };
  } finally {
    clearTimeout(timer);
  }
}

/** Health-Probe für OSRM: liefert true bei erreichbarem `/table`-Endpunkt. */
export async function osrmHealthy(): Promise<boolean> {
  try {
    await etaTable({ lat: 48.2, lng: 15.6 }, [{ lat: 48.21, lng: 15.61 }]);
    return true;
  } catch {
    return false;
  }
}
