import { beforeEach, describe, expect, it, vi } from "vitest";
import {
  generateQuoteId,
  handleQuoteIdConflict,
  isQuoteIdUniqueConflict,
} from "@/modules/quote/quote-id";
import { QuoteIdConflictError } from "@/modules/quote/types";

vi.mock("@/lib/prisma", () => ({
  prisma: {
    quoteRecord: {
      findFirst: vi.fn(),
    },
    auditLog: {
      create: vi.fn(),
    },
  },
}));

import { prisma } from "@/lib/prisma";

const mockedFindFirst = vi.mocked(prisma.quoteRecord.findFirst);
const mockedAuditCreate = vi.mocked(prisma.auditLog.create);

describe("generateQuoteId", () => {
  beforeEach(() => {
    mockedFindFirst.mockReset();
  });

  it("首日生成 _0001", async () => {
    mockedFindFirst.mockResolvedValue(null);
    const id = await generateQuoteId();
    expect(id).toMatch(/^QTE_\d{8}_0001$/);
  });

  it("递增序号", async () => {
    mockedFindFirst.mockResolvedValue({
      quoteId: "QTE_20260616_0005",
    } as never);
    const id = await generateQuoteId();
    expect(id).toMatch(/_0006$/);
  });
});

describe("isQuoteIdUniqueConflict", () => {
  it("P2002 quote_id → true", () => {
    expect(
      isQuoteIdUniqueConflict({
        code: "P2002",
        meta: { target: ["quote_id"] },
      }),
    ).toBe(true);
  });

  it("其他错误 → false", () => {
    expect(isQuoteIdUniqueConflict({ code: "P2002", meta: { target: ["email"] } })).toBe(false);
  });
});

describe("handleQuoteIdConflict", () => {
  it("写 audit 并抛 QuoteIdConflictError", async () => {
    mockedAuditCreate.mockResolvedValue({} as never);
    await expect(
      handleQuoteIdConflict("QTE_20260616_0001", "CUST_001"),
    ).rejects.toThrow(QuoteIdConflictError);
    expect(mockedAuditCreate).toHaveBeenCalled();
  });
});
