/**
 * Client-side route filter matching Angular `filterRoutes`.
 *
 * Rules:
 *   - domestic && !international → keep routes where every city is RU.
 *   - international && !domestic → keep routes with at least one non-RU city.
 *   - both domestic && international → no domestic/intl filter (show all).
 *   - connections → keep only routes where isDirect is false.
 *
 * City codes and airport codes both appear in route arrays; we normalize each
 * entry to its city code before set-membership checks.
 */

import type { IDictionaries } from "@/shared/dictionaries/index.js";
import { getCityCodeByAirportCode } from "@/shared/dictionaries/index.js";
import type { IFlightRoute, IFlightsMapFilterState } from "./types.js";

export function filterRoutes(
  routes: IFlightRoute[],
  filter: Pick<IFlightsMapFilterState, "domestic" | "international" | "connections">,
  dictionaries: IDictionaries,
): IFlightRoute[] {
  const { domestic, international, connections } = filter;

  const toCityCode = (code: string): string =>
    getCityCodeByAirportCode(dictionaries, code) ?? code;

  const isDomestic = (r: IFlightRoute): boolean =>
    r.route.every((code) => dictionaries.ruCityCodes.has(toCityCode(code)));

  const isInternational = (r: IFlightRoute): boolean =>
    r.route.some((code) => dictionaries.otherCityCodes.has(toCityCode(code)));

  const hasConnections = (r: IFlightRoute): boolean => !r.isDirect;

  const predicates: Array<(r: IFlightRoute) => boolean> = [];

  if (domestic && !international) predicates.push(isDomestic);
  else if (international && !domestic) predicates.push(isInternational);

  if (connections) predicates.push(hasConnections);

  if (predicates.length === 0) return routes;
  return routes.filter((r) => predicates.every((p) => p(r)));
}
