// FX Service Unit Tests

import { fxService } from '@/core/fx/fx.service';
import { createTestSovereignBank, cleanDatabase } from '@/__tests__/utils/test-db';
import { testPrisma } from '@/__tests__/utils/test-db';
import { FxOrderType, FxTradeType } from '@/shared/types';

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

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

  describe('submitOrder', () => {
    it('should submit a market order', async () => {
      const bank = await createTestSovereignBank();

      const result = await fxService.submitOrder(bank.id, {
        pair: 'USD/EUR',
        amount: '1000.00',
        orderType: FxOrderType.MARKET,
        settlement: 'RTGS',
      });

      expect(result.tradeId).toBeDefined();
      expect(result.status).toBe('pending');
    });

    it('should submit a limit order with price', async () => {
      const bank = await createTestSovereignBank();

      const result = await fxService.submitOrder(bank.id, {
        pair: 'USD/EUR',
        amount: '1000.00',
        orderType: FxOrderType.LIMIT,
        limitPrice: '0.85',
        settlement: 'RTGS',
      });

      expect(result.tradeId).toBeDefined();
    });

    it('should reject limit order without price', async () => {
      const bank = await createTestSovereignBank();

      await expect(
        fxService.submitOrder(bank.id, {
          pair: 'USD/EUR',
          amount: '1000.00',
          orderType: FxOrderType.LIMIT,
          settlement: 'RTGS',
        })
      ).rejects.toThrow();
    });
  });

  describe('executeTrade', () => {
    it('should execute a pending trade', async () => {
      const bank = await createTestSovereignBank();

      const orderResult = await fxService.submitOrder(bank.id, {
        pair: 'USD/EUR',
        amount: '1000.00',
        orderType: FxOrderType.MARKET,
        settlement: 'RTGS',
      });

      const trade = await fxService.executeTrade(orderResult.tradeId);

      expect(trade.status).toBe('executed');
      expect(trade.executedAt).toBeDefined();
    });

    it('should reject executing non-existent trade', async () => {
      await expect(fxService.executeTrade('NON-EXISTENT')).rejects.toThrow();
    });
  });
});

