import { describe, expect, it } from "vitest";
import { refreshExactProduct } from "../src/core/directRefresh.js";
import { HttpStatusError } from "../src/core/politeHttp.js";
import type { FetchContext, StoreAdapter } from "../src/core/types.js";

const adapter: StoreAdapter = {
  id: "fake",
  displayName: "Fake",
  storeHomepage: "https://fake.example",
  enabled: true,
  timeoutMs: 100,
  fetchRaw: async () => "",
  parse: () => [],
};
const target = {
  url: "https://fake.example/item",
  sourceRef: null,
  expectedBrand: "MANN-FILTER",
  expectedPartNumber: "W 712/52",
};

describe("direct product parser", () => {
  it("selects the exact identity when JSON-LD sku and mpn differ", async () => {
    const html = `<script type="application/ld+json">${JSON.stringify({
      "@type": "Product",
      brand: { "@type": "Brand", name: "MANN-FILTER" },
      sku: "W712/52-MANN",
      mpn: "W 712/52",
      name: "Oil filter",
      offers: { price: 7.41, availability: "https://schema.org/InStock" },
    })}</script>`;
    const ctx = { http: { get: async () => html } } as unknown as FetchContext;
    const result = await refreshExactProduct(adapter, target, ctx);
    expect(result).toMatchObject({
      status: "found",
      offer: { partNumber: "W 712/52", priceEur: 7.41, inStock: true },
    });
  });

  it("does not turn an unknown schema.org availability value into out of stock", async () => {
    const html = `<script type="application/ld+json">${JSON.stringify({
      "@type": "Product",
      brand: { "@type": "Brand", name: "MANN-FILTER" },
      mpn: "W 712/52",
      name: "Oil filter",
      offers: { price: 7.41, availability: "https://schema.org/SomeFutureStatus" },
    })}</script>`;
    const ctx = { http: { get: async () => html } } as unknown as FetchContext;
    const result = await refreshExactProduct(adapter, target, ctx);
    expect(result).toMatchObject({ status: "found", offer: { inStock: null } });
  });

  it("treats only explicit product HTTP 404/410 as not found", async () => {
    const ctx = {
      http: { get: async () => { throw new HttpStatusError("fake", target.url, 404); } },
    } as unknown as FetchContext;
    await expect(refreshExactProduct(adapter, target, ctx)).resolves.toEqual({ status: "not_found" });
  });

  it("reads Trodo's server product meta before Vue hydrates the price block", async () => {
    const trodo = { ...adapter, id: "trodo", fetchMode: "onDemand" as const };
    const html = `<html><head><title>Oil filter BOSCH 0 986 452 041</title>
      <meta name="description" content="Oil filter 0 986 452 041 no BOSCH. Tikai 6.32 EUR."></head>
      <body><div class="product-info"><div class="product-main-info"></div><span class="on-stock">Pieejams.</span></div></body></html>`;
    const ctx = { browser: { fetchPageHtml: async () => html } } as unknown as FetchContext;
    const result = await refreshExactProduct(trodo, {
      ...target,
      expectedBrand: "BOSCH",
      expectedPartNumber: "0 986 452 041",
    }, ctx);
    expect(result).toMatchObject({ status: "found", offer: { priceEur: 6.32, partNumber: "0 986 452 041" } });
  });

  it("reads EUAutodalas availability from product meta content", async () => {
    const eu = { ...adapter, id: "euautodalas", fetchMode: "onDemand" as const };
    const html = `<title>MANN-FILTER W 712/52</title><div itemtype="https://schema.org/Product">
      <h1>MANN-FILTER W 712/52</h1><meta itemprop="price" content="8.43">
      <meta itemprop="availability" content="https://schema.org/InStock"></div>`;
    const ctx = { browser: { fetchPageHtml: async () => html } } as unknown as FetchContext;
    const result = await refreshExactProduct(eu, target, ctx);
    expect(result).toMatchObject({ status: "found", offer: { priceEur: 8.43, inStock: true, availability: "Pieejams" } });
  });

  it("normalizes Handler supplier status and keeps its shipping date out of availability", async () => {
    const handler = { ...adapter, id: "handler", fetchMode: "onDemand" as const };
    const html = `<main><h1>MANN-FILTER W 712/52</h1>
      <div class="selected-part-offer-table-row">
        <div class="selected-part-offer-table-row-td"><span class="text-red-300">Uz pasūtījumu</span>
          <span>Piegādātājs bez precīzas informācijas.</span><span class="text-gray-500">24 July</span></div>
        <span class="font-semibold whitespace-nowrap">5.00 €</span>
      </div>
      <div class="selected-part-offer-table-row">
        <div class="selected-part-offer-table-row-td"><span class="text-gray-600">8 gb.</span>
          <span class="text-gray-500">27 July</span></div>
        <span class="font-semibold whitespace-nowrap">5.00 €</span>
      </div></main>`;
    const ctx = { browser: { fetchPageHtml: async () => html } } as unknown as FetchContext;
    const result = await refreshExactProduct(handler, target, ctx);
    expect(result).toMatchObject({
      status: "found",
      offer: {
        priceEur: 5,
        inStock: true,
        availability: "Pieejams (8 gab.)",
        deliveryNote: "Nosūtīšana: 27 July",
      },
    });
  });

  it("keeps Handler order-only availability as unknown stock", async () => {
    const handler = { ...adapter, id: "handler", fetchMode: "onDemand" as const };
    const html = `<main><h1>MANN-FILTER W 712/52</h1>
      <div class="selected-part-offer-table-row">
        <div class="selected-part-offer-table-row-td"><span class="text-red-300">Uz pasūtījumu</span>
          <span class="text-gray-500">27 July</span></div>
        <span class="font-semibold whitespace-nowrap">5.00 €</span>
      </div></main>`;
    const ctx = { browser: { fetchPageHtml: async () => html } } as unknown as FetchContext;
    const result = await refreshExactProduct(handler, target, ctx);
    expect(result).toMatchObject({
      status: "found",
      offer: { inStock: null, availability: "Uz pasūtījumu", deliveryNote: "Nosūtīšana: 27 July" },
    });
  });
});
