import type { MyBookingWindow } from "@/services/bookings.service";

/** All booking-window times are communicated in East Africa Time. */
const TZ = "Africa/Addis_Ababa";

/** "Thu, 10 Jul, 08:00 EAT" — a full opening date/time in Addis Ababa time. */
export function formatWindowOpensAt(iso: string): string {
  const day = new Date(iso).toLocaleDateString("en-GB", {
    weekday: "short",
    day: "numeric",
    month: "short",
    timeZone: TZ,
  });
  const time = new Date(iso).toLocaleTimeString("en-GB", {
    hour: "2-digit",
    minute: "2-digit",
    hour12: false,
    timeZone: TZ,
  });
  return `${day}, ${time}`;
}

/** True when at least one of the contract's windows is bookable right now. */
export function hasOpenWindow(windows: MyBookingWindow[]): boolean {
  return windows.some((w) => w.isOpenNow);
}

/**
 * Full ordered corridor for a window — every stop from origin through the
 * intermediate milestones to the destination. Falls back to origin/destination
 * when the backend sends no milestone chain (older schedules, routeless windows).
 */
export function windowRouteStops(w: MyBookingWindow): string[] {
  if (w.routeStations && w.routeStations.length >= 2) return w.routeStations;
  return [w.origin ?? "—", w.destination ?? "—"];
}

/**
 * The next upcoming (not-yet-open) window the customer should come back for —
 * the one that OPENS soonest from now. Two guards matter here:
 *  - only openings strictly in the future qualify. A train mid-cycle
 *    (doc-review/payment) still reports the window that already opened and
 *    closed; showing that past time as "next" told customers to come back for
 *    a window that was over.
 *  - ordered by opening time, not departure date — "next window" is the next
 *    moment booking opens, which may belong to a later-departing train.
 * Returns `null` when nothing upcoming carries a future opening time.
 */
export function soonestUpcomingWindow(
  windows: MyBookingWindow[],
): MyBookingWindow | null {
  const now = Date.now();
  const upcoming = windows
    .filter(
      (w) =>
        !w.isOpenNow &&
        w.windowOpensAt &&
        new Date(w.windowOpensAt).getTime() > now,
    )
    .sort(
      (a, b) =>
        new Date(a.windowOpensAt!).getTime() - new Date(b.windowOpensAt!).getTime(),
    );
  return upcoming[0] ?? null;
}

/**
 * The closed-state message shown when no booking window is open: the soonest
 * upcoming window's opening time + lane, or a generic notice when nothing is
 * scheduled.
 */
export function closedWindowMessage(windows: MyBookingWindow[]): string {
  const next = soonestUpcomingWindow(windows);
  if (!next || !next.windowOpensAt) {
    return "No upcoming booking window scheduled.";
  }
  const lane =
    next.origin && next.destination
      ? ` for ${next.origin}→${next.destination}`
      : "";
  return `Booking is not open right now. Next window: ${formatWindowOpensAt(
    next.windowOpensAt,
  )} EAT${lane}.`;
}
