import { describe, expect, it } from "vitest";
import { createMockDb } from "../../../testing/index";
import type { Transaction } from "../generated/kysely-tailordb";
import { CreditNoteNotEditableError, InvalidCreditNoteLineError } from "../lib/errors.generated";
import {
  baseCreditNote,
  baseCreditNoteLine,
  baseCreditNoteLineInput,
  issuedCreditNote,
} from "../testing/fixtures";
import { commandCtx, expectErr, expectOk } from "../testing/commandTestUtils";
import { run } from "./updateSalesCreditNote";

describe("updateSalesCreditNote", () => {
  it("updates draft credit-note lines", async () => {
    const { db, spies } = createMockDb<Transaction>();
    spies.select.mockReturnValueOnce(baseCreditNote);
    spies.update.mockReturnValueOnce({
      ...baseCreditNote,
      reason: "Updated",
      updatedAt: new Date(),
    });
    spies.insert.mockReturnValueOnce(baseCreditNoteLine);

    const result = await run(
      db,
      {
        salesCreditNoteId: baseCreditNote.id,
        reason: "Updated",
        lines: [baseCreditNoteLineInput],
      },
      commandCtx,
    );

    expectOk(result);
    expect(spies.delete).toHaveBeenCalled();
    expect(spies.set).toHaveBeenCalledWith(expect.objectContaining({ reason: "Updated" }));
  });

  it("returns error when updating an issued credit note", async () => {
    const { db, spies } = createMockDb<Transaction>();
    spies.select.mockReturnValueOnce(issuedCreditNote);

    const result = await run(
      db,
      { salesCreditNoteId: issuedCreditNote.id, reason: "Updated" },
      commandCtx,
    );

    expectErr(result, CreditNoteNotEditableError);
  });

  it("returns error when correction content is invalid", async () => {
    const { db, spies } = createMockDb<Transaction>();
    spies.select.mockReturnValueOnce(baseCreditNote);

    const result = await run(
      db,
      {
        salesCreditNoteId: baseCreditNote.id,
        lines: [{ ...baseCreditNoteLineInput, salesInvoiceLineId: "" }],
      },
      commandCtx,
    );

    expectErr(result, InvalidCreditNoteLineError);
  });
});
