import { describe, it, expect, vi, beforeEach } from 'vitest'
import { tradingApi } from '../trading'
import { apiClient } from '../client'
import { OrderSide, OrderType } from '../../types'

vi.mock('../client')

describe('tradingApi', () => {
    beforeEach(() => {
        vi.clearAllMocks()
    })

    describe('createOrder', () => {
        it('calls correct endpoint with order data', async () => {
            const order = {
                exchange_id: 1,
                symbol: 'BTC/USD',
                side: OrderSide.BUY,
                order_type: OrderType.MARKET,
                quantity: 0.1,
                paper_trading: true,
            }
            const mockResponse = { data: { id: 1, ...order, status: 'pending' } }
            vi.mocked(apiClient.post).mockResolvedValue(mockResponse)

            const result = await tradingApi.createOrder(order)

            expect(apiClient.post).toHaveBeenCalledWith('/api/trading/orders', order)
            expect(result).toEqual(mockResponse.data)
        })
    })

    describe('getOrders', () => {
        it('calls correct endpoint with default parameters', async () => {
            const mockOrders = [{ id: 1, symbol: 'BTC/USD' }]
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockOrders })

            const result = await tradingApi.getOrders()

            expect(apiClient.get).toHaveBeenCalledWith('/api/trading/orders', {
                params: { paper_trading: true, limit: 100 },
            })
            expect(result).toEqual(mockOrders)
        })

        it('passes custom parameters', async () => {
            const mockOrders = [{ id: 1 }]
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockOrders })

            await tradingApi.getOrders(false, 50)

            expect(apiClient.get).toHaveBeenCalledWith('/api/trading/orders', {
                params: { paper_trading: false, limit: 50 },
            })
        })
    })

    describe('getOrder', () => {
        it('calls correct endpoint with order ID', async () => {
            const mockOrder = { id: 123, symbol: 'ETH/USD' }
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockOrder })

            const result = await tradingApi.getOrder(123)

            expect(apiClient.get).toHaveBeenCalledWith('/api/trading/orders/123')
            expect(result).toEqual(mockOrder)
        })
    })

    describe('cancelOrder', () => {
        it('calls correct endpoint to cancel order', async () => {
            vi.mocked(apiClient.post).mockResolvedValue({ data: {} })

            await tradingApi.cancelOrder(123)

            expect(apiClient.post).toHaveBeenCalledWith('/api/trading/orders/123/cancel')
        })
    })

    describe('cancelAllOrders', () => {
        it('calls correct endpoint with paper trading param', async () => {
            const mockResponse = {
                status: 'success',
                cancelled_count: 5,
                failed_count: 0,
                total_orders: 5,
            }
            vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse })

            const result = await tradingApi.cancelAllOrders(true)

            expect(apiClient.post).toHaveBeenCalledWith('/api/trading/orders/cancel-all', null, {
                params: { paper_trading: true },
            })
            expect(result).toEqual(mockResponse)
        })
    })

    describe('getPositions', () => {
        it('calls correct endpoint', async () => {
            const mockPositions = [{ id: 1, symbol: 'BTC/USD', quantity: 0.5 }]
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockPositions })

            const result = await tradingApi.getPositions()

            expect(apiClient.get).toHaveBeenCalledWith('/api/trading/positions', {
                params: { paper_trading: true },
            })
            expect(result).toEqual(mockPositions)
        })
    })

    describe('getBalance', () => {
        it('calls correct endpoint', async () => {
            const mockBalance = { total: 10000, available: 8000 }
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockBalance })

            const result = await tradingApi.getBalance()

            expect(apiClient.get).toHaveBeenCalledWith('/api/trading/balance', {
                params: { paper_trading: true },
            })
            expect(result).toEqual(mockBalance)
        })
    })
})
