/**
 * EN: Pact consumer test — Promotion Service consuming Order Service.
 * VI: Pact consumer test — Promotion Service sử dụng Order Service.
 *
 * Boundary: promotion -> order
 * Contracts:
 *   1. GET /api/v1/orders/{orderId} — fetch order to validate promotion eligibility
 *   2. GET /api/v1/orders?customerId={id}&shopId={id} — fetch order history for loyalty check
 */
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, integer, boolean, eachLike } = MatchersV3;

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

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

const ORDER_ID = '550e8400-e29b-41d4-a716-446655440030';
const CUSTOMER_ID = '550e8400-e29b-41d4-a716-446655440031';
const SHOP_ID = '550e8400-e29b-41d4-a716-446655440032';
const BEARER_TOKEN = 'Bearer service-to-service-token';

// ---------------------------------------------------------------------------
// Consumer-side clients
// ---------------------------------------------------------------------------
async function getOrderById(baseUrl: string, orderId: string, token: string) {
  const res = await fetch(`${baseUrl}/api/v1/orders/${orderId}`, {
    headers: { Authorization: token },
  });
  if (!res.ok) return null;
  return res.json();
}

async function getCustomerOrderHistory(
  baseUrl: string,
  customerId: string,
  shopId: string,
  token: string
) {
  const res = await fetch(
    `${baseUrl}/api/v1/orders?customerId=${customerId}&shopId=${shopId}&status=completed`,
    { headers: { Authorization: token } }
  );
  if (!res.ok) return [];
  const body = await res.json();
  return body.data?.items ?? body.data ?? [];
}

// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
describe('PromotionService → OrderService contract', () => {
  describe('GET /api/v1/orders/{orderId}', () => {
    it('returns order with total for promotion validation', async () => {
      await provider
        .addInteraction({
          states: [{ description: `order ${ORDER_ID} is completed` }],
          uponReceiving: 'a request to get order details for promotion eligibility',
          withRequest: {
            method: 'GET',
            path: `/api/v1/orders/${ORDER_ID}`,
            headers: { Authorization: BEARER_TOKEN },
          },
          willRespondWith: {
            status: 200,
            headers: { 'Content-Type': 'application/json' },
            body: {
              success: boolean(true),
              data: like({
                id: uuid(ORDER_ID),
                status: string('completed'),
                totalAmount: decimal(175000),
                customerId: uuid(CUSTOMER_ID),
                shopId: uuid(SHOP_ID),
                createdAt: string('2026-03-23T02:00:00Z'),
              }),
            },
          },
        })
        .executeTest(async (mockServer) => {
          const result = await getOrderById(mockServer.url, ORDER_ID, BEARER_TOKEN);
          expect(result).not.toBeNull();
          expect(result.success).toBe(true);
          expect(result.data.status).toBe('completed');
          expect(typeof result.data.totalAmount).toBe('number');
        });
    });
  });

  describe('GET /api/v1/orders (customer history)', () => {
    it('returns order history for loyalty tier calculation', async () => {
      await provider
        .addInteraction({
          states: [
            {
              description: `customer ${CUSTOMER_ID} has 5 completed orders in shop ${SHOP_ID}`,
            },
          ],
          uponReceiving: 'a request to get completed orders for a customer',
          withRequest: {
            method: 'GET',
            path: '/api/v1/orders',
            query: { customerId: CUSTOMER_ID, shopId: SHOP_ID, status: 'completed' },
            headers: { Authorization: BEARER_TOKEN },
          },
          willRespondWith: {
            status: 200,
            headers: { 'Content-Type': 'application/json' },
            body: {
              success: boolean(true),
              data: like({
                items: eachLike({
                  id: uuid(),
                  totalAmount: decimal(100000),
                  status: string('completed'),
                }),
                totalCount: integer(5),
              }),
            },
          },
        })
        .executeTest(async (mockServer) => {
          const orders = await getCustomerOrderHistory(
            mockServer.url,
            CUSTOMER_ID,
            SHOP_ID,
            BEARER_TOKEN
          );
          expect(Array.isArray(orders)).toBe(true);
          expect(orders.length).toBeGreaterThanOrEqual(1);
          orders.forEach((o: any) => {
            expect(o.status).toBe('completed');
          });
        });
    });
  });
});
