import { describe, expect, it } from "vitest";
import {
  buildScheduleStartSeo,
  buildScheduleSearchSeo,
  buildScheduleDetailsSeo,
} from "./seo.js";
import type { ISimpleFlight, IScheduleFlightId } from "./types.js";

/** Stub t() that returns the key + interpolation vars for assertion. */
function stubT(key: string, opts?: Record<string, unknown>): string {
  if (opts && Object.keys(opts).length > 0) {
    const vars = Object.entries(opts)
      .map(([k, v]) => `${k}=${v}`)
      .join(",");
    return `${key}|${vars}`;
  }
  return key;
}

const CANONICAL = "https://www.aeroflot.ru";

describe("buildScheduleStartSeo", () => {
  it("uses MAIN translation keys", () => {
    const result = buildScheduleStartSeo(stubT, "ru", CANONICAL);

    expect(result.title).toBe("SEO.SCHEDULE.MAIN.TITLE");
    expect(result.description).toBe("SEO.SCHEDULE.MAIN.DESCRIPTION");
  });

  it("sets canonical to /{locale}/schedule", () => {
    const result = buildScheduleStartSeo(stubT, "en", CANONICAL);

    expect(result.canonical).toBe("https://www.aeroflot.ru/en/schedule");
  });

  it("includes hreflang with 10 entries", () => {
    const result = buildScheduleStartSeo(stubT, "ru", CANONICAL);

    expect(result.hreflang).toHaveLength(10);
  });

  it("sets og tags", () => {
    const result = buildScheduleStartSeo(stubT, "ru", CANONICAL);

    expect(result.og.title).toBe(result.title);
    expect(result.og.type).toBe("website");
    expect(result.og.locale).toBe("ru");
    expect(result.og.siteName).toBe("Aeroflot");
  });

  it("sets twitter card", () => {
    const result = buildScheduleStartSeo(stubT, "ru", CANONICAL);

    expect(result.twitter).toBeDefined();
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- test assertion guards above
    expect(result.twitter!.card).toBe("summary");
  });
});

describe("buildScheduleSearchSeo", () => {
  const params = {
    type: "route" as const,
    outbound: {
      departure: "MOW",
      arrival: "KUF",
      dateFrom: "20220425",
      dateTo: "20220501",
    },
  };

  it("uses SEARCH translation keys with interpolation", () => {
    const result = buildScheduleSearchSeo(stubT, params, "ru", CANONICAL);

    expect(result.title).toContain("SEO.SCHEDULE.SEARCH.TITLE");
    expect(result.title).toContain("departureCity=MOW");
    expect(result.title).toContain("arrivalCity=KUF");
    expect(result.title).toContain("dateFrom=25.04.2022");
    expect(result.title).toContain("dateTo=01.05.2022");
  });

  it("uses city names when provided", () => {
    const result = buildScheduleSearchSeo(
      stubT,
      params,
      "ru",
      CANONICAL,
      { departure: "Moscow", arrival: "Samara" },
    );

    expect(result.title).toContain("departureCity=Moscow");
    expect(result.title).toContain("arrivalCity=Samara");
  });

  it("sets canonical to the route search URL", () => {
    const result = buildScheduleSearchSeo(stubT, params, "ru", CANONICAL);

    expect(result.canonical).toBe(
      "https://www.aeroflot.ru/ru/schedule/route/MOW-KUF-20220425-20220501",
    );
  });

  it("includes hreflang entries", () => {
    const result = buildScheduleSearchSeo(stubT, params, "ru", CANONICAL);

    expect(result.hreflang).toHaveLength(10);
  });

  it("handles round-trip params", () => {
    const rtParams = {
      type: "roundtrip" as const,
      outbound: {
        departure: "MOW",
        arrival: "KUF",
        dateFrom: "20220425",
        dateTo: "20220501",
      },
      inbound: {
        departure: "KUF",
        arrival: "MOW",
        dateFrom: "20220502",
        dateTo: "20220508",
      },
    };

    const result = buildScheduleSearchSeo(stubT, rtParams, "ru", CANONICAL);

    expect(result.canonical).toContain(
      "schedule/route/MOW-KUF-20220425-20220501/KUF-MOW-20220502-20220508",
    );
  });
});

describe("buildScheduleDetailsSeo", () => {
  const flightIds: IScheduleFlightId[] = [
    { carrier: "SU", flightNumber: "0012", date: "20220527" },
  ];

  const flight: ISimpleFlight = {
    id: "SU0012-20220527",
    routeType: "Direct",
    flightId: {
      carrier: "SU",
      flightNumber: "0012",
      suffix: "",
      date: "20220527",
    },
    flyingTime: "1h 30m",
    operatingBy: {},
    status: "Scheduled",
    leg: {
      index: 0,
      status: "Scheduled",
      flyingTime: "1h 30m",
      updated: "2022-05-27T10:00:00Z",
      dayChange: 0,
      equipment: { name: "Airbus A320", code: "320" },
      flags: { checkinAvailable: false, returnToAirport: false, routeChanged: false },
      operatingBy: {},
      departure: {
        scheduled: {
          airport: "Sheremetyevo",
          airportCode: "SVO",
          city: "Moscow",
          cityCode: "MOW",
          countryCode: "RU",
        },
        checkingStatus: "closed",
        times: {
          scheduledDeparture: {
            dayChange: { value: 0, title: "" },
            local: "2022-05-27T10:00:00",
            localTime: "10:00",
            tzOffset: 3,
            utc: "2022-05-27T07:00:00Z",
          },
        },
      },
      arrival: {
        scheduled: {
          airport: "Pulkovo",
          airportCode: "LED",
          city: "Saint Petersburg",
          cityCode: "LED",
          countryCode: "RU",
        },
        times: {
          scheduledArrival: {
            dayChange: { value: 0, title: "" },
            local: "2022-05-27T11:30:00",
            localTime: "11:30",
            tzOffset: 3,
            utc: "2022-05-27T08:30:00Z",
          },
        },
      },
    },
  };

  it("uses DETAILS translation keys", () => {
    const result = buildScheduleDetailsSeo(stubT, [flight], "ru", CANONICAL, flightIds);

    expect(result.title).toContain("SEO.SCHEDULE.DETAILS.TITLE");
    expect(result.title).toContain("flights=SU 0012");
    expect(result.title).toContain("date=27.05.2022");
  });

  it("sets canonical to the details URL", () => {
    const result = buildScheduleDetailsSeo(stubT, [flight], "ru", CANONICAL, flightIds);

    expect(result.canonical).toBe(
      "https://www.aeroflot.ru/ru/schedule/SU0012-20220527",
    );
  });

  it("includes hreflang entries", () => {
    const result = buildScheduleDetailsSeo(stubT, [flight], "ru", CANONICAL, flightIds);

    expect(result.hreflang).toHaveLength(10);
  });

  it("sets og.type to article for details", () => {
    const result = buildScheduleDetailsSeo(stubT, [flight], "ru", CANONICAL, flightIds);

    expect(result.og.type).toBe("article");
  });

  it("handles multiple flights in display", () => {
    const multiFlightIds: IScheduleFlightId[] = [
      { carrier: "SU", flightNumber: "0012", date: "20220527" },
      { carrier: "SU", flightNumber: "0013", date: "20220527" },
    ];

    const result = buildScheduleDetailsSeo(stubT, [flight], "ru", CANONICAL, multiFlightIds);

    expect(result.title).toContain("SU 0012, SU 0013");
  });
});
