/**
 * TZ §4.1.15.10 — probe the ws2 meal endpoint for special-meal
 * availability. The caller supplies the flight's origin/destination,
 * airline, flight number, scheduled UTC datetime, and the class table
 * present on the flight. The hook picks the cabin per TZ rule:
 * Economy present → cabin=economy; only Business → cabin=business;
 * neither → skip the probe entirely.
 *
 * Returns true only when the API confirms availability; null while
 * loading; false when the flight has no eligible cabin class or the API
 * reported nothing; null again on transient errors (caller shows no
 * banner — matches Angular's silent fallback).
 */

import { useEffect, useRef, useState } from "react";
import { fetchSpecialMealAvailability } from "../specialMealApi.js";
import type { MealType } from "../types.js";

export interface UseSpecialMealArgs {
  origin: string | undefined;
  destination: string | undefined;
  airline: string | undefined;
  number: string | undefined;
  /** Scheduled departure UTC ISO; converted to "YYYY-MM-DD HH:mm:ss" here. */
  scheduledDepartureUtc: string | undefined;
  /** Set of meal classes present on the flight (Economy/Comfort/Business/Special). */
  cabins: readonly MealType[];
}

function isoToWsFormat(iso: string): string {
  // Accepts "YYYY-MM-DDTHH:mm:ssZ" (or with ms/offset) → "YYYY-MM-DD HH:mm:ss"
  const d = new Date(iso);
  if (Number.isNaN(d.getTime())) return iso;
  const pad = (n: number) => String(n).padStart(2, "0");
  return (
    `${d.getUTCFullYear()}-${pad(d.getUTCMonth() + 1)}-${pad(d.getUTCDate())} ` +
    `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}`
  );
}

export function useSpecialMeal(args: UseSpecialMealArgs): {
  available: boolean | null;
  loading: boolean;
} {
  const [available, setAvailable] = useState<boolean | null>(null);
  const [loading, setLoading] = useState(false);
  const lastKeyRef = useRef<string | null>(null);

  useEffect(() => {
    const { origin, destination, airline, number, scheduledDepartureUtc, cabins } = args;
    if (!origin || !destination || !airline || !number || !scheduledDepartureUtc) {
      setAvailable(null);
      return;
    }
    // Cabin choice per TZ §4.1.15.10.
    let cabin: "economy" | "business" | null = null;
    if (cabins.includes("Economy")) cabin = "economy";
    else if (cabins.includes("Business") && !cabins.includes("Comfort")) cabin = "business";
    if (!cabin) {
      setAvailable(null);
      return;
    }

    const key = `${airline}|${number}|${origin}|${destination}|${scheduledDepartureUtc}|${cabin}`;
    if (lastKeyRef.current === key) return;
    lastKeyRef.current = key;

    const controller = new AbortController();
    let cancelled = false;
    setLoading(true);
    fetchSpecialMealAvailability(
      {
        origin,
        destination,
        airline,
        number,
        flightDatetimeUtc: isoToWsFormat(scheduledDepartureUtc),
        cabin,
      },
      controller.signal,
    )
      .then((v) => {
        if (!cancelled) setAvailable(v);
      })
      .finally(() => {
        if (!cancelled) setLoading(false);
      });
    return () => {
      cancelled = true;
      controller.abort();
    };
  }, [
    args.origin,
    args.destination,
    args.airline,
    args.number,
    args.scheduledDepartureUtc,
    // cabins is a new array each render; stringify for stable dep
    JSON.stringify(args.cabins),
  ]);

  return { available, loading };
}
