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

import { PaymentRepository } from "@/data/repositories/payment_repository";
import {
  GiftProductsResponseSchema,
  TipMessageResponseSchema,
} from "@/data/schemas/payment";
import type { PaymentApi } from "@/data/services/api";
import { Result } from "@/utils/result";

describe("PaymentRepository", () => {
  it("forwards chat action attribution only in the owned order request", async () => {
    const createOrder = vi.fn().mockResolvedValue({
      orderId: "pay_xxx",
      payParams: null,
    });
    const repository = new PaymentRepository({
      createOrder,
    } as unknown as PaymentApi);

    const result = await repository.createOrder(
      "vip_monthly",
      "stripe",
      true,
      undefined,
      undefined,
      "019c8f8d-17d3-7a42-b1cc-b6927b1927d5",
    );

    expect(createOrder).toHaveBeenCalledWith({
      planId: "vip_monthly",
      payChannel: "stripe",
      autoRenew: true,
      chatActionId: "019c8f8d-17d3-7a42-b1cc-b6927b1927d5",
    });
    expect(Result.isOk(result)).toBe(true);
  });

  it("loads a character gift catalog without adapting product metadata", async () => {
    const catalog = GiftProductsResponseSchema.parse({
      characterId: "elio",
      categories: [
        {
          category: "coffee",
          name: "Coffee",
          productCount: 1,
          imageUrl: null,
        },
      ],
      plans: [
        {
          planId: "tip_coffee_usd_9_99",
          planName: "Golden Reserve",
          orderType: "tip",
          tipType: "coffee_medium",
          category: "coffee",
          characterId: "elio",
          description: "Buy Elio a coffee",
          imageUrl: null,
          amountCents: 999,
          currency: "USD",
          autoRenew: false,
          isFirstRechargeOffer: false,
          firstRechargeDiscountPercent: 0,
          promotionType: null,
        },
      ],
    });
    const getGiftProducts = vi.fn().mockResolvedValue(catalog);
    const repository = new PaymentRepository({
      getGiftProducts,
    } as unknown as PaymentApi);

    const result = await repository.getGiftProducts("elio");

    expect(getGiftProducts).toHaveBeenCalledWith("elio");
    expect(Result.isOk(result) && result.data).toBe(catalog);
  });

  it("validates and forwards a Tip message order id", async () => {
    const tipMessage = TipMessageResponseSchema.parse({
      orderId: "pay_xxx",
      characterId: "elio",
      planId: "tip_coffee_usd_9_99",
      productName: "Golden Reserve",
      tipCount: 1,
      poolIndex: 1,
      message: "Thank you.",
    });
    const getTipMessage = vi.fn().mockResolvedValue(tipMessage);
    const repository = new PaymentRepository({
      getTipMessage,
    } as unknown as PaymentApi);

    const result = await repository.getTipMessage("pay_xxx");

    expect(getTipMessage).toHaveBeenCalledWith({ orderId: "pay_xxx" });
    expect(Result.isOk(result) && result.data.message).toBe("Thank you.");
  });
});
