/**
 * Integration tests for URL round-tripping.
 *
 * Verifies: build URL from params -> parse URL -> params match original.
 * Also verifies that parsed params produce correct API call parameters.
 *
 * @vitest-environment jsdom
 */

import { describe, it, expect } from "vitest";
import {
  buildOnlineBoardUrl,
  parseOnlineBoardUrl,
  type OnlineBoardParams,
} from "@/features/online-board/url.js";

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------

describe("URL round-trip integration", () => {
  const roundTrip = (params: OnlineBoardParams) => {
    const url = buildOnlineBoardUrl(params);
    const parsed = parseOnlineBoardUrl(url);
    return { url, parsed };
  };

  it("round-trips start page", () => {
    const params: OnlineBoardParams = { type: "start" };
    const { parsed } = roundTrip(params);
    expect(parsed).toEqual({ type: "start" });
  });

  it("round-trips flight search", () => {
    const params: OnlineBoardParams = {
      type: "flight",
      carrier: "SU",
      flightNumber: "100",
      date: "20250115",
    };
    const { url, parsed } = roundTrip(params);
    expect(url).toBe("onlineboard/flight/SU0100-20250115");
    expect(parsed).not.toBeNull();
    expect(parsed!.type).toBe("flight");
    if (parsed!.type === "flight") {
      expect(parsed!.carrier).toBe("SU");
      // Flight number gets zero-padded to 4 digits during build
      expect(parsed!.flightNumber).toBe("0100");
      expect(parsed!.date).toBe("20250115");
    }
  });

  it("round-trips flight search with suffix", () => {
    const params: OnlineBoardParams = {
      type: "flight",
      carrier: "SU",
      flightNumber: "100",
      suffix: "A",
      date: "20250115",
    };
    const { url, parsed } = roundTrip(params);
    expect(url).toBe("onlineboard/flight/SU0100A-20250115");
    expect(parsed).not.toBeNull();
    if (parsed!.type === "flight") {
      expect(parsed!.suffix).toBe("A");
    }
  });

  it("round-trips departure search", () => {
    const params: OnlineBoardParams = {
      type: "departure",
      station: "SVO",
      date: "20250115",
    };
    const { url, parsed } = roundTrip(params);
    expect(url).toBe("onlineboard/departure/SVO-20250115");
    expect(parsed).toEqual(params);
  });

  it("round-trips departure search with time range", () => {
    const params: OnlineBoardParams = {
      type: "departure",
      station: "SVO",
      date: "20250115",
      timeFrom: "0800",
      timeTo: "1200",
    };
    const { url, parsed } = roundTrip(params);
    expect(url).toBe("onlineboard/departure/SVO-20250115-08001200");
    expect(parsed).toEqual(params);
  });

  it("round-trips arrival search", () => {
    const params: OnlineBoardParams = {
      type: "arrival",
      station: "JFK",
      date: "20250115",
    };
    const { url, parsed } = roundTrip(params);
    expect(url).toBe("onlineboard/arrival/JFK-20250115");
    expect(parsed).toEqual(params);
  });

  it("round-trips route search", () => {
    const params: OnlineBoardParams = {
      type: "route",
      departure: "SVO",
      arrival: "JFK",
      date: "20250115",
    };
    const { url, parsed } = roundTrip(params);
    expect(url).toBe("onlineboard/route/SVO-JFK-20250115");
    expect(parsed).toEqual(params);
  });

  it("round-trips route search with time range", () => {
    const params: OnlineBoardParams = {
      type: "route",
      departure: "SVO",
      arrival: "JFK",
      date: "20250115",
      timeFrom: "0600",
      timeTo: "1800",
    };
    const { url, parsed } = roundTrip(params);
    expect(url).toBe("onlineboard/route/SVO-JFK-20250115-06001800");
    expect(parsed).toEqual(params);
  });

  it("round-trips details URL", () => {
    const params: OnlineBoardParams = {
      type: "details",
      carrier: "SU",
      flightNumber: "100",
      date: "20250115",
    };
    const { url, parsed } = roundTrip(params);
    expect(url).toBe("onlineboard/SU0100-20250115");
    expect(parsed).not.toBeNull();
    expect(parsed!.type).toBe("details");
  });

  it("returns null for invalid URL", () => {
    expect(parseOnlineBoardUrl("")).toBeNull();
    expect(parseOnlineBoardUrl("not-a-board-url")).toBeNull();
    expect(parseOnlineBoardUrl("onlineboard/invalid/")).toBeNull();
  });

  it("returns null for malformed flight params", () => {
    expect(parseOnlineBoardUrl("onlineboard/flight/")).toBeNull();
    expect(parseOnlineBoardUrl("onlineboard/flight/SU-notadate")).toBeNull();
  });

  it("handles leading slash in parse", () => {
    const parsed = parseOnlineBoardUrl("/onlineboard/departure/SVO-20250115");
    expect(parsed).toEqual({
      type: "departure",
      station: "SVO",
      date: "20250115",
    });
  });

  it("build then parse preserves search semantics for all 4 search types", () => {
    const searchTypes: OnlineBoardParams[] = [
      { type: "flight", carrier: "SU", flightNumber: "0100", date: "20250115" },
      { type: "departure", station: "SVO", date: "20250115" },
      { type: "arrival", station: "JFK", date: "20250115" },
      { type: "route", departure: "SVO", arrival: "JFK", date: "20250115" },
    ];

    for (const params of searchTypes) {
      const url = buildOnlineBoardUrl(params);
      const parsed = parseOnlineBoardUrl(url);
      expect(parsed).not.toBeNull();
      expect(parsed!.type).toBe(params.type);
    }
  });
});
