/**
 * FlightsMiniListItem — a single row in the flights mini-list sidebar.
 *
 * Renders a Link with flight number, departure/arrival times, dates, and
 * station city/airport labels. Applies a `--selected` modifier when the
 * item matches the currently-viewed flight. Mirrors Angular's
 * `flights-details-list-flight` layout.
 */

import { forwardRef } from "react";
import { Link } from "@modern-js/runtime/router";
import { useTranslation } from "@/i18n/provider.js";
import type { ISimpleFlight, IFlightLeg } from "../../types.js";
import { buildOnlineBoardUrl } from "../../url.js";
import { getFlightSearchDate } from "../../flightSearchDate.js";
import {
  formatLocalTime,
  formatDayMonthYear,
} from "@/shared/utils/datetime/index.js";
import "./FlightsMiniList.scss";

export interface FlightsMiniListItemProps {
  flight: ISimpleFlight;
  isSelected: boolean;
  lang: string;
}

function getEndpoints(flight: ISimpleFlight): { dep: IFlightLeg["departure"]; arr: IFlightLeg["arrival"] } {
  if (flight.routeType === "Direct") {
    return { dep: flight.leg.departure, arr: flight.leg.arrival };
  }
  const firstLeg = flight.legs[0];
  const lastLeg = flight.legs[flight.legs.length - 1];
  if (!firstLeg || !lastLeg) throw new Error("MultiLeg flight has no legs");
  return { dep: firstLeg.departure, arr: lastLeg.arrival };
}

function getDepTimeIso(dep: IFlightLeg["departure"]): string {
  return dep.times.actualBlockOff?.local ?? dep.times.scheduledDeparture.local;
}

function getArrTimeIso(arr: IFlightLeg["arrival"]): string {
  return arr.times.actualBlockOn?.local ?? arr.times.scheduledArrival.local;
}

export const FlightsMiniListItem = forwardRef<HTMLAnchorElement, FlightsMiniListItemProps>(
  ({ flight, isSelected, lang }, ref) => {
    const { t } = useTranslation();
    const { dep, arr } = getEndpoints(flight);
    const href = `/${lang}/${buildOnlineBoardUrl({
      type: "details",
      carrier: flight.flightId.carrier,
      flightNumber: flight.flightId.flightNumber,
      ...(flight.flightId.suffix ? { suffix: flight.flightId.suffix } : {}),
      date: getFlightSearchDate(flight),
    })}`;

    const depIso = getDepTimeIso(dep);
    const arrIso = getArrTimeIso(arr);
    const depTime = formatLocalTime(depIso);
    const arrTime = formatLocalTime(arrIso);
    const depDate = formatDayMonthYear(depIso);
    const arrDate = formatDayMonthYear(arrIso);

    const className = `mini-list__item${isSelected ? " mini-list__item--selected" : ""}`;

    /**
     * TZ §4.1.15.2-R19 + §4.1.15.2-R20 (also §4.1.16.2 Table 57):
     * SVO and VKO airport names are rendered as hyperlinks opening in a new tab.
     */
    const AIRPORT_LINKS: Record<string, string> = {
      SVO: "https://www.svo.aero/ru/main",
      VKO: "http://www.vnukovo.ru",
    };

    /**
     * Cannot use <a> inside the outer <Link> (renders as <a>) — nesting
     * anchors is invalid HTML. Use a <span> that opens the URL imperatively.
     */
    function renderAirportName(airport: string, airportCode: string, terminal: string): JSX.Element {
      const airportLabel = `${airport}${terminal ? ` - ${terminal}` : ""}`;
      const externalUrl = AIRPORT_LINKS[airportCode];
      if (externalUrl) {
        return (
          <span
            role="link"
            tabIndex={0}
            className="mini-list__airport mini-list__airport--link"
            data-testid={`mini-list-airport-link-${airportCode}`}
            onClick={(e) => {
              e.preventDefault();
              e.stopPropagation();
              window.open(externalUrl, "_blank", "noopener,noreferrer");
            }}
            onKeyDown={(e) => {
              if (e.key === "Enter" || e.key === " ") {
                e.preventDefault();
                e.stopPropagation();
                window.open(externalUrl, "_blank", "noopener,noreferrer");
              }
            }}
            aria-label={airportLabel}
          >
            {airportLabel}
          </span>
        );
      }
      return <div className="mini-list__airport">{airportLabel}</div>;
    }

    const isCancelled = flight.status === "Cancelled";
    const isFinished = flight.status === "Arrived" || flight.status === "Landed";
    const isInFlight = flight.status === "InFlight";
    const iconColor = isCancelled
      ? "mini-list__status-icon--cancelled"
      : isFinished || isInFlight
        ? "mini-list__status-icon--green"
        : "mini-list__status-icon--blue";

    return (
      <Link
        ref={ref}
        to={href}
        className={className}
        data-testid={`mini-list-item-${flight.id}`}
      >
        <div className="mini-list__flight-number">
          {(() => {
            const childIds = (flight as typeof flight & {
              _childFlightIds?: { carrier: string; flightNumber: string }[];
            })._childFlightIds;
            if (childIds && childIds.length > 1) {
              return childIds
                .map((c) => `${c.carrier} ${c.flightNumber}`)
                .join(", ");
            }
            return `${flight.flightId.carrier} ${flight.flightId.flightNumber}`;
          })()}
          <span
            className={`mini-list__status-icon ${iconColor}`}
            aria-label={t(`FLIGHT-STATUSES.${flight.status}`)}
          >
            {"\u2708"}
          </span>
        </div>
        <div className="mini-list__times">
          <div className="mini-list__dep">
            <div className="mini-list__time">{depTime}</div>
            <div className="mini-list__date">{depDate}</div>
          </div>
          <div className="mini-list__arr">
            <div className="mini-list__time">{arrTime}</div>
            <div className="mini-list__date">{arrDate}</div>
          </div>
        </div>
        <div className="mini-list__stations">
          <div className="mini-list__station">
            <div className="mini-list__city">{dep.scheduled.city}</div>
            {renderAirportName(dep.scheduled.airport, dep.scheduled.airportCode, dep.terminal ?? "")}
          </div>
          <div className="mini-list__station mini-list__station--arrival">
            <div className="mini-list__city">{arr.scheduled.city}</div>
            {renderAirportName(arr.scheduled.airport, arr.scheduled.airportCode, arr.terminal ?? "")}
          </div>
        </div>
      </Link>
    );
  },
);

FlightsMiniListItem.displayName = "FlightsMiniListItem";
