import { test, expect, registerUser } from '../fixtures';

test.describe('Payments API', () => {
  let accessToken: string;

  test.beforeAll(async ({ request }) => {
    const { accessToken: token } = await registerUser(request);
    accessToken = token;
  });

  test.describe('POST /payments — Create payment', () => {
    test('creates a VNPay payment and returns payment URL', async ({ request }) => {
      const res = await request.post('payments', {
        data: {
          provider: 'VNPAY',
          type: 'LISTING_FEE',
          amountVND: '500000',
          description: 'E2E test listing fee payment',
          returnUrl: 'https://example.com/payments/callback',
        },
        headers: { Authorization: `Bearer ${accessToken}` },
      });

      // Payment creation may fail if VNPay not configured — accept 201 or 502/503
      if (res.status() >= 500) {
        test.skip(true, 'Payment gateway not configured in test env');
        return;
      }

      expect(res.status()).toBe(201);
      const body = await res.json();
      expect(body).toHaveProperty('paymentId');
      expect(body).toHaveProperty('paymentUrl');
    });

    test('rejects payment with missing required fields', async ({ request }) => {
      const res = await request.post('payments', {
        data: { provider: 'VNPAY' },
        headers: { Authorization: `Bearer ${accessToken}` },
      });

      expect(res.ok()).toBeFalsy();
      expect(res.status()).toBe(400);
    });

    test('rejects payment with invalid provider', async ({ request }) => {
      const res = await request.post('payments', {
        data: {
          provider: 'INVALID_PROVIDER',
          type: 'LISTING_FEE',
          amountVND: '500000',
          description: 'Invalid provider test',
          returnUrl: 'https://example.com/callback',
        },
        headers: { Authorization: `Bearer ${accessToken}` },
      });

      expect(res.ok()).toBeFalsy();
      expect(res.status()).toBe(400);
    });

    test('rejects payment with invalid type', async ({ request }) => {
      const res = await request.post('payments', {
        data: {
          provider: 'VNPAY',
          type: 'INVALID_TYPE',
          amountVND: '500000',
          description: 'Invalid type test',
          returnUrl: 'https://example.com/callback',
        },
        headers: { Authorization: `Bearer ${accessToken}` },
      });

      expect(res.ok()).toBeFalsy();
      expect(res.status()).toBe(400);
    });

    test('rejects unauthenticated payment creation', async ({ request }) => {
      const res = await request.post('payments', {
        data: {
          provider: 'VNPAY',
          type: 'LISTING_FEE',
          amountVND: '500000',
          description: 'Unauth test',
          returnUrl: 'https://example.com/callback',
        },
      });

      expect(res.status()).toBe(401);
    });
  });

  test.describe('GET /payments — List transactions', () => {
    test('returns paginated transaction list for authenticated user', async ({ request }) => {
      const res = await request.get('payments', {
        headers: { Authorization: `Bearer ${accessToken}` },
      });

      expect(res.status()).toBe(200);
      const body = await res.json();
      expect(body).toHaveProperty('items');
      expect(Array.isArray(body.items)).toBeTruthy();
    });

    test('supports pagination params', async ({ request }) => {
      const res = await request.get('payments', {
        params: { limit: 5, offset: 0 },
        headers: { Authorization: `Bearer ${accessToken}` },
      });

      expect(res.status()).toBe(200);
      const body = await res.json();
      expect(body.items.length).toBeLessThanOrEqual(5);
    });

    test('rejects unauthenticated transaction list', async ({ request }) => {
      const res = await request.get('payments');

      expect(res.status()).toBe(401);
    });
  });

  test.describe('GET /payments/:id — Get payment status', () => {
    test('returns 401 for unauthenticated request', async ({ request }) => {
      const res = await request.get('payments/some-payment-id');

      expect(res.status()).toBe(401);
    });

    test('returns 404 for non-existent payment', async ({ request }) => {
      const res = await request.get('payments/non-existent-payment-id', {
        headers: { Authorization: `Bearer ${accessToken}` },
      });

      expect(res.ok()).toBeFalsy();
      expect([404, 400]).toContain(res.status());
    });
  });

  test.describe('POST /payments/:id/refund — Refund (admin only)', () => {
    test('rejects refund from non-admin user', async ({ request }) => {
      const res = await request.post('payments/some-id/refund', {
        data: { reason: 'Test refund from non-admin' },
        headers: { Authorization: `Bearer ${accessToken}` },
      });

      expect(res.ok()).toBeFalsy();
      expect([401, 403]).toContain(res.status());
    });
  });
});
