import { createKyselyMock } from "@tailor-platform/sdk/vitest";
import { describe, it } from "vitest";
import type { Namespace } from "../generated/kysely-tailordb";
import {
  CompanyNotFoundError,
  SalespricelistNotEditableError,
  SalespricelistNotFoundError,
} from "../lib/errors.generated";
import { commandCtx, expectErr, expectOk } from "../testing/commandTestUtils";
import { baseCompany, basePriceList, draftPriceList } from "../testing/fixtures";
import { mockOrgQueries } from "../testing/moduleMocks";
import { run } from "./updateSalesPriceList";

describe("updateSalesPriceList", () => {
  it("updates mutable SalesPriceList fields", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    const updated = {
      ...draftPriceList,
      name: "Updated List",
      updatedAt: new Date("2024-01-02T00:00:00.000Z"),
    };
    mock.enqueueResults([draftPriceList], [updated]);

    const result = await mock.withTx((trx) =>
      run(
        trx,
        { salesPriceListId: draftPriceList.id, name: "Updated List", priority: 20 },
        commandCtx,
        mockOrgQueries(baseCompany),
      ),
    );

    expectOk(result);
  });

  it("returns error when SalesPriceList does not exist", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([]);

    const result = await mock.withTx((trx) =>
      run(
        trx,
        { salesPriceListId: draftPriceList.id, name: "Updated List" },
        commandCtx,
        mockOrgQueries(baseCompany),
      ),
    );

    expectErr(result, SalespricelistNotFoundError);
  });

  it("returns error when SalesPriceList is not editable", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([{ ...basePriceList, status: "INACTIVE" }]);

    const result = await mock.withTx((trx) =>
      run(
        trx,
        { salesPriceListId: basePriceList.id, name: "Updated List" },
        commandCtx,
        mockOrgQueries(baseCompany),
      ),
    );

    expectErr(result, SalespricelistNotEditableError);
  });

  it("returns error when the company backing the price list does not exist", async () => {
    const mock = createKyselyMock<Namespace["main-db"]>();
    mock.enqueueResults([draftPriceList]);

    const result = await mock.withTx((trx) =>
      run(
        trx,
        { salesPriceListId: draftPriceList.id, name: "Updated List" },
        commandCtx,
        mockOrgQueries(null),
      ),
    );

    expectErr(result, CompanyNotFoundError);
  });
});
