/**
 * Live SignalR hook for the Online Board flight details page.
 *
 * Composes the generic `useLiveFlights` (1E) with TrackerHub's
 * `Subscribe` channel for a single flight. When the server pushes a
 * `Refresh` message, `useLiveFlights` replaces the flight data.
 *
 * Client-only — SSR is handled by `useLiveFlights` internally.
 *
 * @module
 */

import { useMemo } from "react";
import {
  useLiveFlights,
  type UseLiveFlightsConfig,
} from "@/shared/hooks/useLiveFlights.js";
import type { ConnectionStatus } from "@/shared/signalr/connection.js";
import type { ISimpleFlight, IFlightId, IParsedFlightId } from "../types.js";
import { getEnv } from "@/env/index.js";

// ---------------------------------------------------------------------------
// Result type
// ---------------------------------------------------------------------------

export interface UseLiveFlightDetailsResult {
  flight: ISimpleFlight | null;
  connectionStatus: ConnectionStatus;
}

// ---------------------------------------------------------------------------
// Channel key builder (exported for testing)
// ---------------------------------------------------------------------------

type LiveFlightId = IParsedFlightId | IFlightId;

export function buildFlightChannelKey(id: LiveFlightId): string {
  return `flight:${id.carrier}${id.flightNumber}${id.suffix ?? ""}@${id.date}`;
}

export function buildTrackerFlightSubscriptionKey(id: LiveFlightId): string {
  const date = "dateLT" in id && id.dateLT ? id.dateLT : id.date.replace(/-/g, "");
  return `${id.carrier}${id.flightNumber}${id.suffix ?? ""}@${date}`;
}

// ---------------------------------------------------------------------------
// Hook
// ---------------------------------------------------------------------------

export function useLiveFlightDetails(
  id: LiveFlightId,
  initialFlight: ISimpleFlight | null,
  onRefresh?: () => void,
): UseLiveFlightDetailsResult {
  const config = useMemo<UseLiveFlightsConfig<LiveFlightId>>(
    () => ({
      hubUrl: getEnv().SIGNALR_HUB_URL,
      channelKey: buildFlightChannelKey,
      subscription: {
        eventName: "Refresh",
        invokeMethodName: "Subscribe",
        args: (flightId) => [buildTrackerFlightSubscriptionKey(flightId)],
      },
      onMessage: (message) => {
        if (Array.isArray(message)) return message;
        onRefresh?.();
        return undefined;
      },
    }),
    [onRefresh],
  );

  // useLiveFlights expects an array — wrap/unwrap the single flight
  const initialData = useMemo(
    () => (initialFlight ? [initialFlight] : []),
    [initialFlight],
  );

  const { data, connectionStatus } = useLiveFlights<
    LiveFlightId,
    ISimpleFlight
  >(id, initialData, config);

  const flight = data[0] ?? null;

  return { flight, connectionStatus };
}
