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

// Same canonical form the frontend uses to flag the searched number.
const canonicalize = (v: string): string => v.toUpperCase().replace(/[^A-Z0-9]/g, "");

// Fixture is the search JSON with each product's price merged in, exactly what
// fetchHtml() returns after the search GET + product-price POST.
const json = readFileSync("fixtures/eoltas/W71252.json", "utf-8");

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

  it("maps exact + analog products to offers", () => {
    expect(offers.length).toBe(16);
  });

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

  it("parses the exact MANN match with cents-to-euro price", () => {
    const mann = offers.find((o) => o.brand === "MANN-FILTER");
    expect(mann).toBeDefined();
    expect(mann!.partNumber).toBe("W 712/52");
    expect(mann!.priceEur).toBe(7.41); // userPrice 741 cents
    expect(mann!.title).toBe("Eļļas filtrs");
    expect(mann!.availability).toBe("Normāls");
    expect(mann!.url).toBe("https://www.eoltas.lv/lv-lv/products/MANN-FILTER/W%20712%252F52/ellas-filtrs");
    expect(mann!.imageUrl).toMatch(/^https:\/\/cdn-1\.eoltas\.lt\//);
  });

  it("ranks the exact match by canonicalized part number", () => {
    const mann = offers.find((o) => o.brand === "MANN-FILTER")!;
    expect(canonicalize(mann.partNumber)).toBe("W71252");
  });

  it("carries spec attributes from the listing", () => {
    const mann = offers.find((o) => o.brand === "MANN-FILTER")!;
    expect(mann.attributes).toContainEqual({ label: "Augstums", value: "92" });
  });

  it("includes cross-referenced analogues from other brands", () => {
    const brands = new Set(offers.map((o) => o.brand));
    expect(brands.has("BOSCH")).toBe(true);
    expect(brands.size).toBeGreaterThan(3);
  });
});
