// Comprehensive Settlement Tests

import { atomicSettlementService } from '@/core/settlement/isn/atomic-settlement.service';
import { createTestSovereignBank, createTestBankAccount, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';

describe('Settlement - Comprehensive Tests', () => {
  beforeEach(async () => {
    await cleanDatabase();
  });

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

  describe('Cross-Chain Settlement', () => {
    it('should settle transactions across different asset chains', async () => {
      const bank1 = await createTestSovereignBank({ sovereignCode: 'BANK1' });
      const bank2 = await createTestSovereignBank({ sovereignCode: 'BANK2' });

      const account1 = await createTestBankAccount({
        sovereignBankId: bank1.id,
        assetType: 'fiat',
        balance: '1000.00',
      });
      const account2 = await createTestBankAccount({
        sovereignBankId: bank2.id,
        assetType: 'cbdc',
        balance: '500.00',
      });

      const result = await atomicSettlementService.settleAtomically({
        transactions: [
          {
            sourceAccountId: account1.id,
            destinationAccountId: account2.id,
            amount: '100.00',
            currencyCode: 'USD',
          },
        ],
        referenceId: 'CROSS-CHAIN-001',
      });

      expect(result.success).toBe(true);
    });
  });

  describe('Atomic Rollback', () => {
    it('should rollback all transactions if any fails', async () => {
      const bank = await createTestSovereignBank();
      const account1 = await createTestBankAccount({
        sovereignBankId: bank.id,
        balance: '50.00',
      });
      const account2 = await createTestBankAccount({
        sovereignBankId: bank.id,
      });
      const account3 = await createTestBankAccount({
        sovereignBankId: bank.id,
      });

      // First transaction should succeed, second should fail
      await expect(
        atomicSettlementService.settleAtomically({
          transactions: [
            {
              sourceAccountId: account1.id,
              destinationAccountId: account2.id,
              amount: '30.00',
              currencyCode: 'USD',
            },
            {
              sourceAccountId: account1.id,
              destinationAccountId: account3.id,
              amount: '30.00', // This will fail due to insufficient balance
              currencyCode: 'USD',
            },
          ],
          referenceId: 'ROLLBACK-001',
        })
      ).rejects.toThrow();

      // Verify no changes were made (rollback worked)
      const updatedAccount1 = await testPrisma.bankAccount.findUnique({
        where: { id: account1.id },
      });
      expect(updatedAccount1?.balance.toString()).toBe('50.00');
    });
  });

  describe('Multi-Leg Transactions', () => {
    it('should settle multi-legged transactions atomically', async () => {
      const bank = await createTestSovereignBank();
      const account1 = await createTestBankAccount({
        sovereignBankId: bank.id,
        balance: '1000.00',
      });
      const account2 = await createTestBankAccount({
        sovereignBankId: bank.id,
        balance: '500.00',
      });
      const account3 = await createTestBankAccount({
        sovereignBankId: bank.id,
        balance: '300.00',
      });

      const result = await atomicSettlementService.settleAtomically({
        transactions: [
          {
            sourceAccountId: account1.id,
            destinationAccountId: account2.id,
            amount: '100.00',
            currencyCode: 'USD',
          },
          {
            sourceAccountId: account2.id,
            destinationAccountId: account3.id,
            amount: '50.00',
            currencyCode: 'USD',
          },
        ],
        referenceId: 'MULTI-LEG-001',
      });

      expect(result.success).toBe(true);
      expect(result.entryIds.length).toBeGreaterThan(0);
    });
  });

  describe('Settlement Time Performance', () => {
    it('should complete settlement within acceptable time', async () => {
      const bank = await createTestSovereignBank();
      const account1 = await createTestBankAccount({
        sovereignBankId: bank.id,
        balance: '1000.00',
      });
      const account2 = await createTestBankAccount({
        sovereignBankId: bank.id,
      });

      const startTime = Date.now();
      const result = await atomicSettlementService.settleAtomically({
        transactions: [
          {
            sourceAccountId: account1.id,
            destinationAccountId: account2.id,
            amount: '100.00',
            currencyCode: 'USD',
          },
        ],
        referenceId: 'PERF-001',
      });
      const endTime = Date.now();

      expect(result.success).toBe(true);
      expect(result.settlementTime).toBeLessThan(1000); // Should complete in < 1 second
      expect(endTime - startTime).toBeLessThan(2000); // Actual time < 2 seconds
    });
  });
});

