// Payment Service Unit Tests

import { paymentService } from '@/core/payments/payment.service';
import { PaymentPriority } from '@/shared/types';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { Decimal } from '@prisma/client/runtime/library';

describe('PaymentService', () => {
  beforeEach(async () => {
    await cleanDatabase();
  });

  afterAll(async () => {
    await testPrisma.$disconnect();
  });

  describe('processPayment', () => {
    it('should process a valid payment', async () => {
      const bank = await createTestSovereignBank();
      const sourceAccount = await createTestBankAccount({
        sovereignBankId: bank.id,
        accountNumber: 'SOURCE-001',
        balance: '1000.00',
      });
      const destinationAccount = await createTestBankAccount({
        sovereignBankId: bank.id,
        accountNumber: 'DEST-001',
        balance: '500.00',
      });

      const result = await paymentService.initiatePayment({
        debtorAccount: sourceAccount.accountNumber,
        creditorAccount: destinationAccount.accountNumber,
        amount: '100.00',
        currency: 'USD',
        priority: PaymentPriority.NORMAL,
        assetType: 'fiat',
      });

      expect(result.status).toBe('completed');
      expect(result.paymentId).toBeDefined();

      // Verify balances
      const updatedSource = await testPrisma.bankAccount.findUnique({
        where: { id: sourceAccount.id },
      });
      const updatedDest = await testPrisma.bankAccount.findUnique({
        where: { id: destinationAccount.id },
      });

      expect(updatedSource?.balance.toString()).toBe('900.00');
      expect(updatedDest?.balance.toString()).toBe('600.00');
    });

    it('should reject payment with insufficient balance', async () => {
      const bank = await createTestSovereignBank();
      const sourceAccount = await createTestBankAccount({
        sovereignBankId: bank.id,
        balance: '50.00',
      });
      const destinationAccount = await createTestBankAccount({
        sovereignBankId: bank.id,
      });

      await expect(
        paymentService.initiatePayment({
          debtorAccount: sourceAccount.accountNumber,
          creditorAccount: destinationAccount.accountNumber,
          amount: '100.00',
          currency: 'USD',
          priority: PaymentPriority.NORMAL,
          assetType: 'fiat',
        })
      ).rejects.toThrow();
    });

    it('should validate currency codes match', async () => {
      const bank = await createTestSovereignBank();
      const sourceAccount = await createTestBankAccount({
        sovereignBankId: bank.id,
        currencyCode: 'USD',
        balance: '1000.00',
      });
      const destinationAccount = await createTestBankAccount({
        sovereignBankId: bank.id,
        currencyCode: 'EUR',
      });

      await expect(
        paymentService.initiatePayment({
          debtorAccount: sourceAccount.accountNumber,
          creditorAccount: destinationAccount.accountNumber,
          amount: '100.00',
          currency: 'USD',
          priority: PaymentPriority.NORMAL,
          assetType: 'fiat',
        })
      ).rejects.toThrow();
    });
  });
});

