import { createKyselyMock } from "@tailor-platform/sdk/vitest";
import { describe, expect, it } from "vitest";
import type { Namespace } from "../generated/kysely-tailordb";
import { DuplicateExternalIdentifierError, ListingNotEditableError } from "../lib/errors.generated";
import { commandCtx, expectErr, expectOk } from "../testing/commandTestUtils";
import { baseListing, pausedListing, retiredListing } from "../testing/fixtures";
import { run } from "./updateListing";

describe("updateListing", () => {
  it("updates listing metadata while listing remains active or paused", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    const updated = { ...pausedListing, title: "Updated Title", updatedAt: new Date() };
    mock.enqueueResults([pausedListing], [updated]);

    const result = await mock.withTx((trx) =>
      run(trx, { listingId: pausedListing.id, title: "Updated Title" }, commandCtx),
    );

    expectOk(result);
    expect(mock.updates[0].updateValues()).toEqual(
      expect.objectContaining({ title: "Updated Title" }),
    );
  });

  it("returns error when listing is retired", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([retiredListing]);

    const result = await mock.withTx((trx) =>
      run(trx, { listingId: retiredListing.id, title: "Updated Title" }, commandCtx),
    );

    expectErr(result, ListingNotEditableError);
  });

  it("returns error when updated external identifier conflicts with another listing", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults(
      [baseListing],
      [baseListing, { ...baseListing, id: "listing-99", externalIdentifier: "AMZ-CONFLICT" }],
    );

    const result = await mock.withTx((trx) =>
      run(trx, { listingId: baseListing.id, externalIdentifier: "AMZ-CONFLICT" }, commandCtx),
    );

    expectErr(result, DuplicateExternalIdentifierError);
  });
});
