/**
 * Find the index of the flight whose scheduled time is closest to `now`.
 * Per TZ §4.1.13 opening ¶1 — the nearest flight gets auto-expanded
 * and the list scrolls to it on today's tab.
 */

import type { ISimpleFlight } from "./types.js";

type TimeMode = "departure" | "arrival";

/**
 * Resolve the scheduled ISO timestamp for a flight in the given mode.
 * Handles both Direct (`.leg`) and MultiLeg (`.legs[0]` / `.legs[last]`)
 * shapes, falling back to the raw `departure.scheduled` / `arrival.scheduled`
 * paths used in tests via `as never` casts.
 */
function resolveIso(flight: ISimpleFlight, mode: TimeMode): string | undefined {
  if (mode === "arrival") {
    // Real shape: MultiLeg last leg, or Direct leg
    const leg =
      flight.routeType === "MultiLeg"
        ? flight.legs[flight.legs.length - 1]
        : flight.leg;
    const arrTime = leg?.arrival?.times?.scheduledArrival?.local;
    if (arrTime) return arrTime;
    // Test-cast shape: { arrival: { scheduled: string } }
    const cast = flight as unknown as { arrival?: { scheduled?: string } };
    return cast.arrival?.scheduled;
  }

  // departure mode
  const leg =
    flight.routeType === "MultiLeg" ? flight.legs[0] : flight.leg;
  const depTime = leg?.departure?.times?.scheduledDeparture?.local;
  if (depTime) return depTime;
  // Test-cast shape: { departure: { scheduled: string } }
  const cast = flight as unknown as { departure?: { scheduled?: string } };
  return cast.departure?.scheduled;
}

/**
 * Returns the index of the flight whose scheduled time is closest to `now`.
 *
 * - Returns `0` when the list is empty.
 * - When all flights are in the past, returns the last index.
 * - When all flights are in the future, returns the first index (`0`).
 */
export function findNearestFlightIndex(
  flights: ISimpleFlight[],
  now: Date,
  mode: TimeMode = "departure",
): number {
  if (flights.length === 0) return 0;
  let bestIndex = 0;
  let bestDiff = Number.POSITIVE_INFINITY;
  for (let i = 0; i < flights.length; i++) {
    const f = flights[i];
    if (!f) continue;
    const iso = resolveIso(f, mode);
    if (!iso) continue;
    const ms = Date.parse(iso);
    if (Number.isNaN(ms)) continue;
    const diff = Math.abs(ms - now.getTime());
    if (diff < bestDiff) {
      bestDiff = diff;
      bestIndex = i;
    }
  }
  return bestIndex;
}
