import { describe, expect, it } from "vitest";

import { UnlockPrivateResponse } from "@/data/dto/chat";

describe("UnlockPrivateResponse", () => {
  it("parses a successful single-message unlock response", () => {
    const response = UnlockPrivateResponse.from({
      unlocked: true,
      content: "完整消息内容",
      reason: "ok",
      creditBalance: 9180,
      creditsCharged: 10,
      requiredCredits: 10,
      shortfallCredits: 0,
      lockDetail: {
        locked: false,
        showContent: true,
        showUpgrade: false,
        reason: null,
        hint: null,
        detail: null,
      },
    });

    expect(response.unlocked).toBe(true);
    expect(response.content).toBe("完整消息内容");
    expect(response.reason).toBe("ok");
    expect(response.creditBalance).toBe(9180);
    expect(response.creditsCharged).toBe(10);
    expect(response.requiredCredits).toBe(10);
    expect(response.shortfallCredits).toBe(0);
    expect(response.lockDetail.locked).toBe(false);
  });

  it("parses an insufficient-balance unlock response", () => {
    const response = UnlockPrivateResponse.from({
      unlocked: false,
      content: "",
      reason: "insufficient_balance",
      creditBalance: 5,
      creditsCharged: 0,
      requiredCredits: 10,
      shortfallCredits: 5,
      lockDetail: {
        locked: true,
        showContent: false,
        showUpgrade: true,
        reason: "insufficient_balance",
        hint: "Insufficient credits.",
        detail: {
          messageId: "msg_001",
        },
      },
    });

    expect(response.unlocked).toBe(false);
    expect(response.reason).toBe("insufficient_balance");
    expect(response.creditBalance).toBe(5);
    expect(response.creditsCharged).toBe(0);
    expect(response.requiredCredits).toBe(10);
    expect(response.shortfallCredits).toBe(5);
    expect(response.lockDetail.showUpgrade).toBe(true);
  });

  it("defaults nullable content to an empty string", () => {
    const response = UnlockPrivateResponse.from({
      unlocked: false,
      content: null,
      reason: "insufficient_balance",
      lockDetail: {
        locked: true,
        showContent: false,
        showUpgrade: true,
        reason: "insufficient_balance",
        hint: null,
        detail: null,
      },
    });

    expect(response.content).toBe("");
  });

  it("defaults nullable credit fields to zero", () => {
    const response = UnlockPrivateResponse.from({
      unlocked: false,
      content: "",
      reason: "insufficient_balance",
      creditBalance: null,
      creditsCharged: null,
      requiredCredits: null,
      shortfallCredits: null,
      lockDetail: {
        locked: true,
        showContent: false,
        showUpgrade: true,
        reason: "insufficient_balance",
        hint: null,
        detail: null,
      },
    });

    expect(response.creditBalance).toBe(0);
    expect(response.creditsCharged).toBe(0);
    expect(response.requiredCredits).toBe(0);
    expect(response.shortfallCredits).toBe(0);
  });

  it("defaults nullable lock detail through schema helpers", () => {
    const response = UnlockPrivateResponse.from({
      unlocked: false,
      content: "",
      reason: "insufficient_balance",
      lockDetail: null,
    });

    expect(response.lockDetail).toEqual({
      locked: false,
      showContent: true,
      showUpgrade: false,
      reason: null,
      hint: null,
      detail: null,
    });
  });
});
