export type DirectionsProvider = "google" | "apple" | "waze";

export function hasFiniteCoordinates(latitude?: number | null, longitude?: number | null) {
  return Number.isFinite(latitude) && Number.isFinite(longitude);
}

export function buildDirectionsHref(input: {
  latitude?: number | null;
  longitude?: number | null;
  destinationLabel?: string | null;
  provider?: DirectionsProvider;
  travelMode?: "driving" | "walking" | "bicycling" | "transit";
}) {
  const {
    latitude,
    longitude,
    destinationLabel,
    provider = "google",
    travelMode = "driving",
  } = input;

  const destination = hasFiniteCoordinates(latitude, longitude)
    ? `${latitude},${longitude}`
    : String(destinationLabel || "").trim();

  if (!destination) {
    return null;
  }

  if (provider === "apple") {
    const params = new URLSearchParams({
      daddr: destination,
      dirflg: travelMode === "walking" ? "w" : "d",
    });
    return `https://maps.apple.com/?${params.toString()}`;
  }

  if (provider === "waze") {
    const params = new URLSearchParams(
      hasFiniteCoordinates(latitude, longitude)
        ? {
            ll: `${latitude},${longitude}`,
            navigate: "yes",
          }
        : {
            q: destination,
            navigate: "yes",
          }
    );
    return `https://www.waze.com/ul?${params.toString()}`;
  }

  const params = new URLSearchParams({
    api: "1",
    destination,
    travelmode: travelMode,
    dir_action: "navigate",
  });

  return `https://www.google.com/maps/dir/?${params.toString()}`;
}

export function buildDirectionsOptions(input: {
  latitude?: number | null;
  longitude?: number | null;
  destinationLabel?: string | null;
  travelMode?: "driving" | "walking" | "bicycling" | "transit";
}) {
  const providers: Array<{ provider: DirectionsProvider; label: string }> = [
    { provider: "google", label: "Google Maps" },
    { provider: "apple", label: "Apple Plans" },
    { provider: "waze", label: "Waze" },
  ];

  return providers
    .map(({ provider, label }) => ({
      provider,
      label,
      href: buildDirectionsHref({
        ...input,
        provider,
      }),
    }))
    .filter((option): option is { provider: DirectionsProvider; label: string; href: string } => Boolean(option.href));
}
