/**
 * EN: Pact consumer test — Order Service consuming Wallet Service.
 * VI: Pact consumer test — Order Service sử dụng Wallet Service.
 *
 * Boundary: order -> wallet
 * Contract: Order Service calls POST /api/v1/payments/create to initiate payment.
 */
import { describe, it, expect } from 'vitest';
import { PactV3, MatchersV3 } from '@pact-foundation/pact';
import path from 'path';
import { fileURLToPath } from 'url';

const { like, string, uuid, decimal, boolean } = MatchersV3;

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const PACT_DIR = path.resolve(__dirname, '../../pacts');

const provider = new PactV3({
  consumer: 'OrderService',
  provider: 'WalletService',
  dir: PACT_DIR,
  logLevel: 'warn',
});

// ---------------------------------------------------------------------------
// Consumer-side client (mirrors WalletServiceClient in OrderService.Infrastructure)
// ---------------------------------------------------------------------------
interface CreatePaymentRequest {
  orderId: string;
  amount: number;
  gateway: string;
  returnUrl: string;
  ipAddress: string;
  description: string;
}

async function createPayment(baseUrl: string, request: CreatePaymentRequest) {
  const res = await fetch(`${baseUrl}/api/v1/payments/create`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(request),
  });
  if (!res.ok) return null;
  return res.json();
}

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
describe('OrderService → WalletService contract', () => {
  const ORDER_ID = '550e8400-e29b-41d4-a716-446655440010';

  describe('POST /api/v1/payments/create', () => {
    it('returns payment URL when order is valid', async () => {
      await provider
        .addInteraction({
          states: [{ description: `order ${ORDER_ID} exists and is payable` }],
          uponReceiving: 'a request to create payment for an order',
          withRequest: {
            method: 'POST',
            path: '/api/v1/payments/create',
            headers: { 'Content-Type': 'application/json' },
            body: {
              orderId: uuid(ORDER_ID),
              amount: decimal(175000),
              gateway: string('vnpay'),
              returnUrl: string('https://app.goodgo.vn/payment/callback'),
              ipAddress: string('127.0.0.1'),
              description: string(`Payment for order ${ORDER_ID}`),
            },
          },
          willRespondWith: {
            status: 200,
            headers: { 'Content-Type': 'application/json' },
            body: {
              success: boolean(true),
              data: like({
                paymentId: string('pay_abc123'),
                paymentUrl: string('https://sandbox.vnpayment.vn/pay?vnp_TxnRef=abc'),
                expiredAt: string('2026-03-23T03:43:20Z'),
              }),
            },
          },
        })
        .executeTest(async (mockServer) => {
          const result = await createPayment(mockServer.url, {
            orderId: ORDER_ID,
            amount: 175000,
            gateway: 'vnpay',
            returnUrl: 'https://app.goodgo.vn/payment/callback',
            ipAddress: '127.0.0.1',
            description: `Payment for order ${ORDER_ID}`,
          });
          expect(result).not.toBeNull();
          expect(result.success).toBe(true);
          expect(result.data.paymentUrl).toBeTruthy();
        });
    });

    it('returns error when amount is invalid', async () => {
      await provider
        .addInteraction({
          states: [{ description: 'payment validation is enforced' }],
          uponReceiving: 'a request to create payment with zero amount',
          withRequest: {
            method: 'POST',
            path: '/api/v1/payments/create',
            headers: { 'Content-Type': 'application/json' },
            body: {
              orderId: uuid(ORDER_ID),
              amount: decimal(0),
              gateway: string('vnpay'),
              returnUrl: string('https://app.goodgo.vn/payment/callback'),
              ipAddress: string('127.0.0.1'),
              description: string('invalid payment'),
            },
          },
          willRespondWith: {
            status: 400,
            headers: { 'Content-Type': 'application/json' },
            body: {
              success: boolean(false),
              error: like({ code: string('INVALID_AMOUNT') }),
            },
          },
        })
        .executeTest(async (mockServer) => {
          const result = await createPayment(mockServer.url, {
            orderId: ORDER_ID,
            amount: 0,
            gateway: 'vnpay',
            returnUrl: 'https://app.goodgo.vn/payment/callback',
            ipAddress: '127.0.0.1',
            description: 'invalid payment',
          });
          expect(result).toBeNull();
        });
    });
  });
});
