/**
 * Online Board flight details page component.
 *
 * Receives parsed flight ID, fetches flight details via useFlightDetails,
 * wires live updates via useLiveFlightDetails, renders detailed flight info.
 *
 * @module
 */

import { Fragment, useCallback, type FC } from "react";
import { useNavigate } from "@modern-js/runtime/router";
import { useTranslation } from "@/i18n/provider.js";
import "./OnlineBoardDetailsPage.scss";
import { FlightCard } from "@/ui/flights/FlightCard.js";
import { FlightListSkeleton } from "@/ui/flights/FlightListSkeleton.js";
import { SeoHead } from "@/ui/seo/SeoHead.js";
import { JsonLdRenderer } from "@/shared/seo/json-ld.js";
import { PageLayout } from "@/ui/layout/PageLayout.js";
import { useAppSettings } from "@/shared/hooks/useAppSettings.js";
import { useFlightDetails } from "../hooks/useFlightDetails.js";
import { useLiveFlightDetails } from "../hooks/useLiveFlightDetails.js";
import { buildFlightDetailsSeo } from "../seo.js";
import { buildFlightJsonLd } from "../json-ld.js";
import { buildOnlineBoardUrl } from "../url.js";
import { FlightDetailsAccordion } from "./details-panels/FlightDetailsAccordion.js";
import { FlightsMiniList } from "./FlightsMiniList/index.js";
import { DayTabs } from "./DayTabs/index.js";
import { BoardDetailsHeader } from "./BoardDetailsHeader/index.js";
import { DetailsBackButton } from "./DetailsBackButton/index.js";
import { FlightSchedule } from "./FlightSchedule/index.js";
import { FullRouteTimeline } from "./FullRouteTimeline/index.js";
import { TransferBar } from "./TransferBar/index.js";
import type { IParsedFlightId, IFlightLeg } from "../types.js";

export interface OnlineBoardDetailsPageProps {
  /** Parsed flight identifier from the URL */
  flightId: IParsedFlightId;
  /** Current locale for SEO */
  locale: string;
  /** Canonical origin for SEO URLs */
  canonicalOrigin: string;
}

/**
 * Render all legs of a flight with departure/arrival station details.
 * For multi-leg flights, interleaves a TransferBar between consecutive legs.
 */
function FlightLegs({
  legs,
  viewType,
}: {
  legs: IFlightLeg[];
  viewType: "Onlineboard" | "Schedule";
}): JSX.Element {
  return (
    <div className="flight-details__legs" data-testid="flight-legs">
      {legs.map((leg, i) => (
        <Fragment key={leg.index}>
        <div className="flight-details__leg" data-testid={`flight-leg-${leg.index}`}>
          <div className="flight-details__leg-header">
            <span className="flight-details__leg-index">Leg {leg.index + 1}</span>
            <span className="flight-details__leg-status">{leg.status}</span>
          </div>

          <div className="flight-details__leg-stations">
            <div className="flight-details__leg-departure">
              <span className="flight-details__station-code">
                {leg.departure.scheduled.airportCode}
              </span>
              <span className="flight-details__station-name">
                {leg.departure.scheduled.airport}
              </span>
              <span className="flight-details__station-city">
                {leg.departure.scheduled.city}
              </span>
              {leg.departure.terminal && (
                <span className="flight-details__terminal">
                  Terminal {leg.departure.terminal}
                </span>
              )}
              {leg.departure.gate && (
                <span className="flight-details__gate">Gate {leg.departure.gate}</span>
              )}
              <span className="flight-details__time">
                {leg.departure.times.scheduledDeparture.local}
              </span>
              {leg.departure.times.actualBlockOff && (
                <span className="flight-details__time-actual">
                  Actual: {leg.departure.times.actualBlockOff.local}
                </span>
              )}
            </div>

            <div className="flight-details__leg-duration">
              <span>{leg.flyingTime}</span>
            </div>

            <div className="flight-details__leg-arrival">
              <span className="flight-details__station-code">
                {leg.arrival.scheduled.airportCode}
              </span>
              <span className="flight-details__station-name">
                {leg.arrival.scheduled.airport}
              </span>
              <span className="flight-details__station-city">
                {leg.arrival.scheduled.city}
              </span>
              {leg.arrival.terminal && (
                <span className="flight-details__terminal">
                  Terminal {leg.arrival.terminal}
                </span>
              )}
              {leg.arrival.bagBelt && (
                <span className="flight-details__bag-belt">
                  Baggage belt {leg.arrival.bagBelt}
                </span>
              )}
              <span className="flight-details__time">
                {leg.arrival.times.scheduledArrival.local}
              </span>
              {leg.arrival.times.actualBlockOn && (
                <span className="flight-details__time-actual">
                  Actual: {leg.arrival.times.actualBlockOn.local}
                </span>
              )}
            </div>
          </div>

          {leg.equipment.name && (
            <div className="flight-details__aircraft">
              Aircraft: {leg.equipment.name}
              {leg.equipment.code ? ` (${leg.equipment.code})` : ""}
            </div>
          )}
          <FlightDetailsAccordion leg={leg} viewType="Onlineboard" />
        </div>
        {i < legs.length - 1 && (
          <TransferBar leg={leg} nextLeg={legs[i + 1]!} viewType={viewType} />
        )}
        </Fragment>
      ))}
    </div>
  );
}

/**
 * Extract legs from a flight (handles both Direct and MultiLeg).
 */
function getLegs(flight: { routeType: string; leg?: IFlightLeg; legs?: IFlightLeg[] }): IFlightLeg[] {
  if (flight.routeType === "Direct" && "leg" in flight && flight.leg) {
    return [flight.leg];
  }
  if ("legs" in flight && flight.legs) {
    return flight.legs;
  }
  return [];
}

/**
 * Flight details page. Displays comprehensive flight information
 * with live updates via SignalR.
 */
export const OnlineBoardDetailsPage: FC<OnlineBoardDetailsPageProps> = ({
  flightId,
  locale,
  canonicalOrigin,
}) => {
  const { t } = useTranslation();

  // Fetch flight details
  const detailsParams = {
    flights: `${flightId.carrier}${flightId.flightNumber}${flightId.suffix ?? ""}`,
    dates: `${flightId.date.slice(0, 4)}-${flightId.date.slice(4, 6)}-${flightId.date.slice(6, 8)}`,
  };
  const { flight: firstFlight, allFlights, daysOfFlight, loading, error } = useFlightDetails(detailsParams);

  // Pick the flight matching the URL's flightId (date-based match). The API
  // response may contain multiple flights with the same flight number on
  // different dates; we need the one the user actually navigated to.
  const flight =
    allFlights.find((f) => f.flightId.date === flightId.date) ?? firstFlight;

  // Live updates via SignalR
  const { flight: liveFlight, connectionStatus } = useLiveFlightDetails(
    flightId,
    flight,
  );

  const displayFlight = connectionStatus === "live" && liveFlight ? liveFlight : flight;

  const { onlineboardSearchFrom, onlineboardSearchTo } = useAppSettings();
  const navigate = useNavigate();

  const handleNavigateDate = useCallback(
    (newDate: string) => {
      const url = buildOnlineBoardUrl({
        type: "details",
        carrier: flightId.carrier,
        flightNumber: flightId.flightNumber,
        ...(flightId.suffix ? { suffix: flightId.suffix } : {}),
        date: newDate,
      });
      void navigate(`/${locale}/${url}`);
    },
    [flightId.carrier, flightId.flightNumber, flightId.suffix, locale, navigate],
  );

  const onlineboardHref = `/${locale}/onlineboard`;
  const commonLayoutProps = {
    headerLeft: <DetailsBackButton locale={locale} />,
    breadcrumbs: [
      { label: t("BREADCRUMBS.ONLINEBOARD"), url: onlineboardHref },
    ],
  };

  if (loading) {
    return (
      <PageLayout {...commonLayoutProps}>
        <FlightListSkeleton count={1} />
      </PageLayout>
    );
  }

  if (error) {
    return (
      <PageLayout {...commonLayoutProps}>
        <div className="flight-details flight-details--error" data-testid="flight-details-error">
          <p>Failed to load flight details. Please try again.</p>
        </div>
      </PageLayout>
    );
  }

  if (!displayFlight) {
    return (
      <PageLayout {...commonLayoutProps}>
        <div className="flight-details flight-details--not-found" data-testid="flight-details-not-found">
          <p>Flight not found.</p>
        </div>
      </PageLayout>
    );
  }

  const legs = getLegs(displayFlight);
  const flightNumber = `${displayFlight.flightId.carrier} ${displayFlight.flightId.flightNumber}`;

  const seoProps = buildFlightDetailsSeo(t, displayFlight, locale, canonicalOrigin);
  const jsonLd = buildFlightJsonLd(displayFlight);

  return (
    <>
      <SeoHead {...seoProps} />
      <JsonLdRenderer data={jsonLd} />
      <PageLayout
        headerLeft={<DetailsBackButton locale={locale} />}
        title={<h1 className="flight-details__flight-number">{flightNumber}</h1>}
        breadcrumbs={[
          { label: t("BREADCRUMBS.ONLINEBOARD"), url: onlineboardHref },
          { label: flightNumber },
        ]}
        contentLeft={
          <FlightsMiniList
            flights={allFlights}
            currentFlight={displayFlight}
            lang={locale}
          />
        }
        stickyContent={
          <DayTabs
            selectedDate={flightId.date}
            availableDates={daysOfFlight}
            daysBefore={onlineboardSearchFrom}
            daysAfter={onlineboardSearchTo}
            locale={locale}
            onNavigate={handleNavigateDate}
          />
        }
      >
        <div className="flight-details" data-testid="flight-details">
          {/* Connection status */}
          <div className="flight-details__status" data-testid="connection-status">
            {connectionStatus === "live" && (
              <span className="connection-badge connection-badge--live">Live</span>
            )}
            {connectionStatus === "reconnecting" && (
              <span className="connection-badge connection-badge--reconnecting">Reconnecting...</span>
            )}
            {connectionStatus === "offline" && (
              <span className="connection-badge connection-badge--offline">Offline</span>
            )}
          </div>

          <BoardDetailsHeader flight={displayFlight} locale={locale} />

          {displayFlight.routeType === "MultiLeg" && (
            <FullRouteTimeline legs={displayFlight.legs} viewType="Onlineboard" />
          )}

          {/* Summary card */}
          <FlightCard flight={displayFlight} />

          {/* Operating carrier */}
          {displayFlight.operatingBy.carrier && (
            <div className="flight-details__operating" data-testid="operating-carrier">
              Operated by: {displayFlight.operatingBy.carrier}
              {displayFlight.operatingBy.flightNumber
                ? ` ${displayFlight.operatingBy.flightNumber}`
                : ""}
            </div>
          )}

          {/* Detailed leg information */}
          <FlightLegs legs={legs} viewType="Onlineboard" />

          {/* Flying time */}
          <div className="flight-details__flying-time" data-testid="flying-time">
            Total flying time: {displayFlight.flyingTime}
          </div>

          <FlightSchedule flight={displayFlight} />
        </div>
      </PageLayout>
    </>
  );
};
