import { describe, it, expect } from "vitest";
import { buildCountryCityRows } from "./buildCountryCityRows.js";
import { transformDictionaries } from "@/shared/dictionaries/index.js";
import type { IDictionaries, IRawDictionaries } from "@/shared/dictionaries/index.js";

function makeRaw(overrides: Partial<IRawDictionaries> = {}): IRawDictionaries {
  return { regions: [], countries: [], cities: [], airports: [], ...overrides };
}

function dict(raw: Partial<IRawDictionaries>): IDictionaries {
  return transformDictionaries(makeRaw(raw), "ru");
}

describe("buildCountryCityRows — empty and missing", () => {
  it("returns [] for missing region id", () => {
    const d = dict({
      regions: [{ world_region_id: 500374, title: { ru: "Россия и страны СНГ" } }],
    });
    expect(buildCountryCityRows(d, 99999)).toEqual([]);
  });

  it("returns [] when region has no countries", () => {
    const d = dict({
      regions: [{ world_region_id: 500374, title: { ru: "Россия и страны СНГ" } }],
    });
    expect(buildCountryCityRows(d, 500374)).toEqual([]);
  });
});

describe("buildCountryCityRows — RU pinning", () => {
  it("pins RU country first within its region, others alphabetical", () => {
    const d = dict({
      regions: [{ world_region_id: 500374, title: { ru: "Россия и страны СНГ" } }],
      countries: [
        { code: "BY", title: { ru: "Беларусь" }, world_region_id: 500374 },
        { code: "RU", title: { ru: "Россия" }, world_region_id: 500374 },
        { code: "AM", title: { ru: "Армения" }, world_region_id: 500374 },
      ],
      cities: [
        { code: "BYN", title: { ru: "Минск" }, country_code: "BY", has_afl_flights: true, location: { lat: 53, lon: 27 } },
        { code: "YER", title: { ru: "Ереван" }, country_code: "AM", has_afl_flights: true, location: { lat: 40, lon: 44 } },
        { code: "LED", title: { ru: "Санкт-Петербург" }, country_code: "RU", has_afl_flights: true, location: { lat: 60, lon: 30 } },
      ],
      airports: [
        { code: "MSQ", city_code: "BYN", title: { ru: "Минск аэропорт" }, has_afl_flights: true, location: { lat: 53, lon: 27 } },
        { code: "EVN", city_code: "YER", title: { ru: "Звартноц" }, has_afl_flights: true, location: { lat: 40, lon: 44 } },
        { code: "LED", city_code: "LED", title: { ru: "Пулково" }, has_afl_flights: true, location: { lat: 60, lon: 30 } },
      ],
    });

    const rows = buildCountryCityRows(d, 500374);
    const countryOrder = rows
      .map((r) => r.countryName)
      .filter((n): n is string => Boolean(n));
    expect(countryOrder[0]).toBe("Россия");
    expect(countryOrder).toEqual(["Россия", "Армения", "Беларусь"]);
  });
});

describe("buildCountryCityRows — MOW pinning inside RU", () => {
  it("pins MOW first among RU cities", () => {
    const d = dict({
      regions: [{ world_region_id: 500374, title: { ru: "Россия" } }],
      countries: [{ code: "RU", title: { ru: "Россия" }, world_region_id: 500374 }],
      cities: [
        { code: "KZN", title: { ru: "Казань" }, country_code: "RU", has_afl_flights: true, location: { lat: 55, lon: 49 } },
        { code: "LED", title: { ru: "Санкт-Петербург" }, country_code: "RU", has_afl_flights: true, location: { lat: 60, lon: 30 } },
        { code: "MOW", title: { ru: "Москва" }, country_code: "RU", has_afl_flights: true, location: { lat: 55, lon: 37 } },
      ],
      airports: [
        { code: "KZN", city_code: "KZN", title: { ru: "Казань аэропорт" }, has_afl_flights: true, location: { lat: 55, lon: 49 } },
        { code: "LED", city_code: "LED", title: { ru: "Пулково" }, has_afl_flights: true, location: { lat: 60, lon: 30 } },
        { code: "SVO", city_code: "MOW", title: { ru: "Шереметьево" }, has_afl_flights: true, location: { lat: 55, lon: 37 } },
      ],
    });

    const rows = buildCountryCityRows(d, 500374);
    expect(rows.length).toBeGreaterThan(0);
    expect(rows[0]!.city1!.code).toBe("MOW");
  });
});

describe("buildCountryCityRows — pairing", () => {
  it("pairs two single-airport cities on the same row", () => {
    const d = dict({
      regions: [{ world_region_id: 500374, title: { ru: "Россия" } }],
      countries: [{ code: "RU", title: { ru: "Россия" }, world_region_id: 500374 }],
      cities: [
        { code: "AAA", title: { ru: "Гор А" }, country_code: "RU", has_afl_flights: true, location: { lat: 1, lon: 1 } },
        { code: "BBB", title: { ru: "Гор Б" }, country_code: "RU", has_afl_flights: true, location: { lat: 2, lon: 2 } },
      ],
      airports: [
        { code: "AAA", city_code: "AAA", title: { ru: "Аэропорт А" }, has_afl_flights: true, location: { lat: 1, lon: 1 } },
        { code: "BBB", city_code: "BBB", title: { ru: "Аэропорт Б" }, has_afl_flights: true, location: { lat: 2, lon: 2 } },
      ],
    });

    const rows = buildCountryCityRows(d, 500374);
    expect(rows).toHaveLength(1);
    expect(rows[0]!.city1!.code).toBe("AAA");
    expect(rows[0]!.city2!.code).toBe("BBB");
    expect(rows[0]!.city1Airports).toBeUndefined();
  });

  it("puts a multi-airport city on its own row with city1Airports populated", () => {
    const d = dict({
      regions: [{ world_region_id: 500374, title: { ru: "Россия" } }],
      countries: [{ code: "RU", title: { ru: "Россия" }, world_region_id: 500374 }],
      cities: [
        { code: "MOW", title: { ru: "Москва" }, country_code: "RU", has_afl_flights: true, location: { lat: 55, lon: 37 } },
        { code: "ZZZ", title: { ru: "Город Я" }, country_code: "RU", has_afl_flights: true, location: { lat: 3, lon: 3 } },
      ],
      airports: [
        { code: "SVO", city_code: "MOW", title: { ru: "Шереметьево" }, has_afl_flights: true, location: { lat: 55, lon: 37 } },
        { code: "DME", city_code: "MOW", title: { ru: "Домодедово" }, has_afl_flights: true, location: { lat: 55, lon: 37 } },
        { code: "ZZZ", city_code: "ZZZ", title: { ru: "Аэропорт Я" }, has_afl_flights: true, location: { lat: 3, lon: 3 } },
      ],
    });

    const rows = buildCountryCityRows(d, 500374);
    expect(rows).toHaveLength(2);
    expect(rows[0]!.city1!.code).toBe("MOW");
    expect(rows[0]!.city2).toBeNull();
    expect(rows[0]!.city1Airports?.length).toBe(2);
    expect(rows[1]!.city1!.code).toBe("ZZZ");
    expect(rows[1]!.city2).toBeNull();
  });

  it("handles odd-count cities by leaving city2 null on last row", () => {
    const d = dict({
      regions: [{ world_region_id: 500374, title: { ru: "Россия" } }],
      countries: [{ code: "RU", title: { ru: "Россия" }, world_region_id: 500374 }],
      cities: [
        { code: "AAA", title: { ru: "Гор А" }, country_code: "RU", has_afl_flights: true, location: { lat: 1, lon: 1 } },
        { code: "BBB", title: { ru: "Гор Б" }, country_code: "RU", has_afl_flights: true, location: { lat: 2, lon: 2 } },
        { code: "CCC", title: { ru: "Гор В" }, country_code: "RU", has_afl_flights: true, location: { lat: 3, lon: 3 } },
      ],
      airports: [
        { code: "AAA", city_code: "AAA", title: { ru: "Аэропорт А" }, has_afl_flights: true, location: { lat: 1, lon: 1 } },
        { code: "BBB", city_code: "BBB", title: { ru: "Аэропорт Б" }, has_afl_flights: true, location: { lat: 2, lon: 2 } },
        { code: "CCC", city_code: "CCC", title: { ru: "Аэропорт В" }, has_afl_flights: true, location: { lat: 3, lon: 3 } },
      ],
    });

    const rows = buildCountryCityRows(d, 500374);
    expect(rows).toHaveLength(2);
    expect(rows[1]!.city2).toBeNull();
  });
});

describe("buildCountryCityRows — countryName placement", () => {
  it("sets countryName only on the first row of each country block", () => {
    const d = dict({
      regions: [{ world_region_id: 500374, title: { ru: "Россия и страны СНГ" } }],
      countries: [
        { code: "RU", title: { ru: "Россия" }, world_region_id: 500374 },
        { code: "BY", title: { ru: "Беларусь" }, world_region_id: 500374 },
      ],
      cities: [
        { code: "AAA", title: { ru: "Гор А" }, country_code: "RU", has_afl_flights: true, location: { lat: 1, lon: 1 } },
        { code: "BBB", title: { ru: "Гор Б" }, country_code: "RU", has_afl_flights: true, location: { lat: 2, lon: 2 } },
        { code: "CCC", title: { ru: "Гор В" }, country_code: "RU", has_afl_flights: true, location: { lat: 3, lon: 3 } },
        { code: "DDD", title: { ru: "Гор Д" }, country_code: "BY", has_afl_flights: true, location: { lat: 4, lon: 4 } },
      ],
      airports: [
        { code: "AAA", city_code: "AAA", title: { ru: "Аэропорт А" }, has_afl_flights: true, location: { lat: 1, lon: 1 } },
        { code: "BBB", city_code: "BBB", title: { ru: "Аэропорт Б" }, has_afl_flights: true, location: { lat: 2, lon: 2 } },
        { code: "CCC", city_code: "CCC", title: { ru: "Аэропорт В" }, has_afl_flights: true, location: { lat: 3, lon: 3 } },
        { code: "DDD", city_code: "DDD", title: { ru: "Аэропорт Д" }, has_afl_flights: true, location: { lat: 4, lon: 4 } },
      ],
    });

    const rows = buildCountryCityRows(d, 500374);
    expect(rows[0]!.countryName).toBe("Россия");
    expect(rows[1]!.countryName).toBeUndefined();
    expect(rows[2]!.countryName).toBe("Беларусь");
  });
});
