/**
 * Trading Service Tests - ML Trade Execution
 */

import { describe, it, expect, vi, beforeEach } from 'vitest';

// Mock fetch globally
const mockFetch = vi.fn();
vi.stubGlobal('fetch', mockFetch);

// Mock localStorage
const mockLocalStorage = {
  getItem: vi.fn(() => 'test-token'),
  setItem: vi.fn(),
  removeItem: vi.fn(),
  clear: vi.fn(),
  key: vi.fn(),
  length: 0,
};
vi.stubGlobal('localStorage', mockLocalStorage);

describe('Trading Service - ML Execution', () => {
  beforeEach(() => {
    mockFetch.mockClear();
    mockLocalStorage.getItem.mockReturnValue('test-token');
  });

  describe('executeMLTrade', () => {
    it('should execute a trade successfully', async () => {
      const mockResult = {
        success: true,
        trade_id: 'trade-123',
        order_id: 'order-456',
        executed_price: 1.08500,
        lot_size: 0.1,
        message: 'Trade executed successfully',
      };

      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: async () => mockResult,
      });

      const { executeMLTrade } = await import('../services/trading.service');
      const result = await executeMLTrade({
        symbol: 'EURUSD',
        direction: 'buy',
        source: 'ict',
        entry_price: 1.085,
        stop_loss: 1.08,
        take_profit: 1.095,
        lot_size: 0.1,
      });

      expect(mockFetch).toHaveBeenCalledWith(
        expect.stringContaining('/api/trade/execute'),
        expect.objectContaining({
          method: 'POST',
          headers: expect.objectContaining({
            'Authorization': 'Bearer test-token',
          }),
        })
      );
      expect(result.success).toBe(true);
      expect(result.executed_price).toBe(1.085);
    });

    it('should handle trade execution failure', async () => {
      mockFetch.mockResolvedValueOnce({
        ok: false,
        json: async () => ({ detail: 'Insufficient margin' }),
      });

      const { executeMLTrade } = await import('../services/trading.service');
      const result = await executeMLTrade({
        symbol: 'EURUSD',
        direction: 'buy',
        source: 'ensemble',
        lot_size: 10,
      });

      expect(result.success).toBe(false);
      expect(result.error).toBe('Insufficient margin');
    });
  });

  describe('getMT4Account', () => {
    it('should fetch MT4 account info', async () => {
      const mockAccount = {
        account_id: '12345',
        broker: 'Demo Broker',
        balance: 10000,
        equity: 10500,
        connected: true,
      };

      mockFetch.mockResolvedValueOnce({
        ok: true,
        json: async () => mockAccount,
      });

      const { getMT4Account } = await import('../services/trading.service');
      const result = await getMT4Account();

      expect(result).toEqual(mockAccount);
      expect(result?.connected).toBe(true);
    });

    it('should return null when not connected', async () => {
      mockFetch.mockResolvedValueOnce({ ok: false });

      const { getMT4Account } = await import('../services/trading.service');
      const result = await getMT4Account();
      expect(result).toBeNull();
    });
  });

  describe('getLLMAgentHealth', () => {
    it('should return true when healthy', async () => {
      mockFetch.mockResolvedValueOnce({ ok: true });

      const { getLLMAgentHealth } = await import('../services/trading.service');
      const result = await getLLMAgentHealth();
      expect(result).toBe(true);
    });

    it('should return false on error', async () => {
      mockFetch.mockRejectedValueOnce(new Error('Connection refused'));

      const { getLLMAgentHealth } = await import('../services/trading.service');
      const result = await getLLMAgentHealth();
      expect(result).toBe(false);
    });
  });
});
