import { describe, it, expect } from "vitest";
import {
  buildMetadata,
  buildProductJsonLd,
  formatPriceForSchema,
  mapConditionToSchema,
} from "./seo";

describe("mapConditionToSchema", () => {
  it("maps NWT to NewCondition", () => {
    expect(mapConditionToSchema("NWT")).toBe("https://schema.org/NewCondition");
  });

  it.each(["NWOT", "EUC", "GUC", "Fair", "Poor"] as const)(
    "maps %s to UsedCondition",
    (c) => {
      expect(mapConditionToSchema(c)).toBe("https://schema.org/UsedCondition");
    },
  );
});

describe("formatPriceForSchema", () => {
  it("formats 2500 cents as '25.00'", () => {
    expect(formatPriceForSchema(2500)).toBe("25.00");
  });

  it("formats 99 cents as '0.99'", () => {
    expect(formatPriceForSchema(99)).toBe("0.99");
  });

  it("formats 0 as '0.00'", () => {
    expect(formatPriceForSchema(0)).toBe("0.00");
  });
});

describe("buildProductJsonLd", () => {
  it("produces a valid Product schema", () => {
    const jsonLd = buildProductJsonLd(
      {
        id: "abc",
        title: "Vintage Leather Jacket",
        description: "Soft pebbled leather",
        brand: "Levi's",
        condition: "EUC",
        price: 12500,
        imageUrl: "https://cdn.example.com/og/abc.jpg",
      },
      "https://alqove.com/items/abc",
    );

    expect(jsonLd["@context"]).toBe("https://schema.org");
    expect(jsonLd["@type"]).toBe("Product");
    expect(jsonLd.name).toBe("Vintage Leather Jacket");
    expect(jsonLd.brand).toEqual({ "@type": "Brand", name: "Levi's" });
    expect(jsonLd.offers.price).toBe("125.00");
    expect(jsonLd.offers.itemCondition).toBe("https://schema.org/UsedCondition");
  });

  it("defaults availability to InStock and omits seller when status/seller are absent", () => {
    const jsonLd = buildProductJsonLd(
      {
        id: "abc",
        title: "Jacket",
        description: "",
        brand: null,
        condition: "GUC",
        price: 1000,
        imageUrl: null,
      },
      "https://alqove.com/items/abc",
    );

    expect(jsonLd.offers.availability).toBe("https://schema.org/InStock");
    expect(jsonLd.offers.seller).toBeUndefined();
    expect(jsonLd.image).toEqual([]);
    expect(jsonLd.brand).toBeUndefined();
  });

  it("marks non-active items as OutOfStock", () => {
    const jsonLd = buildProductJsonLd(
      {
        id: "abc",
        title: "Jacket",
        description: "",
        brand: null,
        condition: "GUC",
        price: 1000,
        imageUrl: null,
        status: "sold",
      },
      "https://alqove.com/items/abc",
    );

    expect(jsonLd.offers.availability).toBe("https://schema.org/OutOfStock");
  });

  it("keeps active items InStock and exposes the store as the seller", () => {
    const jsonLd = buildProductJsonLd(
      {
        id: "abc",
        title: "Jacket",
        description: "",
        brand: null,
        condition: "GUC",
        price: 1000,
        imageUrl: null,
        status: "active",
        sellerName: "Thrifted Threads",
      },
      "https://alqove.com/items/abc",
    );

    expect(jsonLd.offers.availability).toBe("https://schema.org/InStock");
    expect(jsonLd.offers.seller).toEqual({
      "@type": "Organization",
      name: "Thrifted Threads",
    });
  });
});

describe("buildMetadata", () => {
  it("falls back to the generated brand card", () => {
    const meta = buildMetadata({ title: "Browse", description: "Everything." });

    // Next only merges the `opengraph-image` file convention into routes that
    // declare no openGraph block; every route built here declares one, so the
    // default has to name the generated route explicitly. The previous default
    // pointed at /og/default.jpg, which was never shipped — so every share card
    // 404'd.
    expect(meta.openGraph?.images).toEqual([
      { url: "https://alqove.com/opengraph-image", width: 1200, height: 630 },
    ]);
    expect(meta.twitter?.images).toEqual(["https://alqove.com/opengraph-image"]);
  });

  it("uses an explicit image when the caller supplies one", () => {
    const meta = buildMetadata({
      title: "Jacket",
      description: "Soft pebbled leather.",
      image: "https://cdn.example.com/og/jacket.jpg",
    });

    expect(meta.openGraph?.images).toEqual([
      { url: "https://cdn.example.com/og/jacket.jpg", width: 1200, height: 630 },
    ]);
    expect(meta.twitter?.images).toEqual(["https://cdn.example.com/og/jacket.jpg"]);
  });

  it("does not double up the site name when the title already carries it", () => {
    expect(buildMetadata({ title: "Alqove Admin", description: "x" }).title)
      .toBe("Alqove Admin");
    expect(buildMetadata({ title: "Cart", description: "x" }).title)
      .toBe("Cart — Alqove");
  });
});
