import { readFileSync } from "node:fs";
import { describe, expect, it } from "vitest";
import { handler } from "../src/adapters/handler.js";
import { normalizeQuery } from "../src/core/normalize.js";
import { OfferSchema } from "../src/core/types.js";

const canonicalize = (v: string): string => v.toUpperCase().replace(/[^A-Z0-9]/g, "");
const json = readFileSync("fixtures/handler/W71252.json", "utf-8");

describe("handler adapter (fixture: W71252, recorded 2026-07-11)", () => {
  const offers = handler.parse(json, normalizeQuery("W 712/52")!);

  it("collapses the marketplace to one offer per distinct part", () => {
    expect(offers.length).toBe(18);
    // No duplicate (brand, partNumber) pairs survive the collapse.
    const keys = offers.map((o) => `${o.brand}|${o.partNumber}`);
    expect(new Set(keys).size).toBe(keys.length);
  });

  it("every offer passes schema validation", () => {
    for (const o of offers) expect(OfferSchema.safeParse(o).success, JSON.stringify(o)).toBe(true);
  });

  it("keeps the cheapest MANN offer with delivery and product URL", () => {
    const mann = offers.find((o) => o.brand === "MANN");
    expect(mann).toBeDefined();
    expect(mann!.partNumber).toBe("W 712/52");
    expect(canonicalize(mann!.partNumber)).toBe("W71252"); // ranks as the searched number
    expect(mann!.priceEur).toBe(5.17); // cheapest of the MANN supplier offers
    expect(mann!.title).toBe("Eļļas filtrs");
    expect(mann!.availability).toBe("Pieejams (26 gab.)");
    expect(mann!.deliveryNote).toBe("Piegāde ~6 d.");
    expect(mann!.url).toBe("https://handler.lv/lv/Product/35118355-4a17-11e6-80d1-901b0e934e21");
    expect(mann!.sourceRef).toBe("35118355-4a17-11e6-80d1-901b0e934e21");
  });

  it("includes cross-brand analogues with prices", () => {
    const brands = new Set(offers.map((o) => o.brand));
    for (const b of ["Bosch", "FILTRON", "MAHLE", "Valeo"]) expect(brands.has(b)).toBe(true);
    for (const o of offers) expect(o.priceEur).toBeGreaterThan(0);
  });
});
