/**
 * Schedule search results page for one-way and round-trip searches.
 *
 * Receives parsed route params, fetches flights via useScheduleSearch,
 * renders results with calendar navigation.
 * No SignalR -- schedule data is static.
 *
 * @module
 */

import type { FC } from "react";
import { useCallback } from "react";
import { useNavigate, useParams } from "@modern-js/runtime/router";
import { FlightList } from "@/ui/flights/FlightList.js";
import "./ScheduleSearchPage.scss";
import { JsonLdRenderer } from "@/shared/seo/json-ld.js";
import { useScheduleSearch } from "../hooks/useScheduleSearch.js";
import { useScheduleCalendar } from "../hooks/useScheduleCalendar.js";
import { buildScheduleUrl } from "../url.js";
import { buildScheduleFlightListJsonLd } from "../json-ld.js";
import type { ScheduleParams } from "../url.js";
import type { IScheduleSearchRequest, ISimpleFlight } from "../types.js";
import type { IScheduleRouteDirectionParams } from "../types.js";

export interface ScheduleSearchPageProps {
  params: ScheduleParams & { type: "route" | "roundtrip" };
}

/**
 * Convert parsed schedule params to API search params.
 */
function toSearchRequest(
  direction: IScheduleRouteDirectionParams,
  attribute?: 1 | 2,
): IScheduleSearchRequest {
  const request: IScheduleSearchRequest = {
    departure: direction.departure,
    arrival: direction.arrival,
    dateFrom: formatApiDate(direction.dateFrom),
    dateTo: formatApiDate(direction.dateTo),
  };

  if (direction.timeFrom) request.timeFrom = direction.timeFrom;
  if (direction.timeTo) request.timeTo = direction.timeTo;
  if (direction.connections !== undefined) request.connections = direction.connections;
  if (attribute) request.attribute = attribute;

  return request;
}

/**
 * Convert yyyyMMdd to yyyy-MM-dd for the API.
 */
function formatApiDate(yyyymmdd: string): string {
  if (yyyymmdd.length !== 8) return yyyymmdd;
  return `${yyyymmdd.slice(0, 4)}-${yyyymmdd.slice(4, 6)}-${yyyymmdd.slice(6, 8)}`;
}

/**
 * Extract simple flights from the mixed IFlight[] response for rendering.
 */
function extractSimpleFlights(flights: Array<{ routeType: string }>): ISimpleFlight[] {
  return flights.filter(
    (f): f is ISimpleFlight => f.routeType === "Direct" || f.routeType === "MultiLeg",
  );
}

export const ScheduleSearchPage: FC<ScheduleSearchPageProps> = ({ params }) => {
  const navigate = useNavigate();
  const routeParams = useParams<{ lang: string }>();
  const lang = routeParams.lang ?? "ru";

  const outbound = params.outbound;
  const inbound = params.type === "roundtrip" ? params.inbound : undefined;

  // Fetch outbound flights
  const outboundRequest = toSearchRequest(outbound);
  const { flights: outboundFlights, loading: outboundLoading, error: outboundError, refresh } =
    useScheduleSearch(outboundRequest);

  // Fetch inbound flights (if round-trip)
  const inboundRequest = inbound ? toSearchRequest(inbound, 2) : outboundRequest;
  const {
    flights: inboundFlights,
    loading: inboundLoading,
  } = useScheduleSearch(inboundRequest);

  // Calendar
  const calendarParams = {
    date: formatApiDate(outbound.dateFrom),
    departure: outbound.departure,
    arrival: outbound.arrival,
    connections: outbound.connections !== undefined && outbound.connections > 0,
  };
  const { days: calendarDays } = useScheduleCalendar(calendarParams);

  const _loading = outboundLoading || (inbound ? inboundLoading : false);

  // Navigation: change date via calendar
  const handleDateChange = useCallback(
    (newDate: string) => {
      // newDate is yyyy-MM-dd from calendar, convert to yyyyMMdd
      const yyyymmdd = newDate.replace(/-/g, "");
      const newOutbound = { ...outbound, dateFrom: yyyymmdd };
      const newParams: ScheduleParams = inbound
        ? { type: "roundtrip", outbound: newOutbound, inbound }
        : { type: "route", outbound: newOutbound };
      const url = buildScheduleUrl(newParams);
      void navigate(`/${lang}/${url}`);
    },
    [navigate, lang, outbound, inbound],
  );

  const outboundSimple = extractSimpleFlights(outboundFlights);
  const inboundSimple = inbound ? extractSimpleFlights(inboundFlights) : [];

  // JSON-LD
  const searchDescription = `Schedule ${outbound.departure} to ${outbound.arrival}`;
  const jsonLd = outboundSimple.length > 0
    ? buildScheduleFlightListJsonLd(outboundSimple, searchDescription)
    : undefined;

  return (
    <div className="schedule-search" data-testid="schedule-search">
      {jsonLd && <JsonLdRenderer data={jsonLd} />}

      {/* Calendar strip */}
      {calendarDays.length > 0 && (
        <div className="schedule-search__calendar" data-testid="calendar-strip">
          {calendarDays.map((day) => (
            <button
              key={day}
              type="button"
              className="calendar-day"
              onClick={() => handleDateChange(day)}
            >
              {day}
            </button>
          ))}
        </div>
      )}

      {/* Error state */}
      {outboundError && (
        <div className="schedule-search__error" data-testid="search-error">
          <p>Failed to load schedule. Please try again.</p>
          <button type="button" onClick={refresh}>Retry</button>
        </div>
      )}

      {/* Outbound flights */}
      <div className="schedule-search__outbound" data-testid="outbound-results">
        <h2>Outbound: {outbound.departure} &rarr; {outbound.arrival}</h2>
        <FlightList flights={outboundSimple} loading={outboundLoading} />
      </div>

      {/* Inbound flights (round-trip) */}
      {inbound && (
        <div className="schedule-search__inbound" data-testid="inbound-results">
          <h2>Return: {inbound.departure} &rarr; {inbound.arrival}</h2>
          <FlightList flights={inboundSimple} loading={inboundLoading} />
        </div>
      )}
    </div>
  );
};
