import { describe, it, expect, vi, beforeEach } from 'vitest'
import { strategiesApi } from '../strategies'
import { apiClient } from '../client'

vi.mock('../client')

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

    describe('listStrategies', () => {
        it('calls correct endpoint', async () => {
            const mockStrategies = [{ id: 1, name: 'RSI Strategy' }]
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockStrategies })

            const result = await strategiesApi.listStrategies()

            expect(apiClient.get).toHaveBeenCalledWith('/api/strategies/')
            expect(result).toEqual(mockStrategies)
        })
    })

    describe('getAvailableStrategies', () => {
        it('calls correct endpoint', async () => {
            const mockResponse = { strategies: ['RSI', 'MACD', 'Moving Average'] }
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse })

            const result = await strategiesApi.getAvailableStrategies()

            expect(apiClient.get).toHaveBeenCalledWith('/api/strategies/available')
            expect(result).toEqual(mockResponse)
        })
    })

    describe('createStrategy', () => {
        it('calls correct endpoint with strategy data', async () => {
            const strategy = {
                name: 'My Strategy',
                type: 'RSI',
                symbol: 'BTC/USD',
                parameters: { period: 14 },
                enabled: true,
            }
            const mockResponse = { id: 1, ...strategy }
            vi.mocked(apiClient.post).mockResolvedValue({ data: mockResponse })

            const result = await strategiesApi.createStrategy(strategy)

            expect(apiClient.post).toHaveBeenCalledWith('/api/strategies/', strategy)
            expect(result).toEqual(mockResponse)
        })
    })

    describe('getStrategy', () => {
        it('calls correct endpoint with ID', async () => {
            const mockStrategy = { id: 5, name: 'Test Strategy' }
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockStrategy })

            const result = await strategiesApi.getStrategy(5)

            expect(apiClient.get).toHaveBeenCalledWith('/api/strategies/5')
            expect(result).toEqual(mockStrategy)
        })
    })

    describe('updateStrategy', () => {
        it('calls correct endpoint with updates', async () => {
            const updates = { name: 'Updated Name', enabled: false }
            const mockResponse = { id: 5, ...updates }
            vi.mocked(apiClient.put).mockResolvedValue({ data: mockResponse })

            const result = await strategiesApi.updateStrategy(5, updates)

            expect(apiClient.put).toHaveBeenCalledWith('/api/strategies/5', updates)
            expect(result).toEqual(mockResponse)
        })
    })

    describe('deleteStrategy', () => {
        it('calls correct endpoint', async () => {
            vi.mocked(apiClient.delete).mockResolvedValue({ data: {} })

            await strategiesApi.deleteStrategy(5)

            expect(apiClient.delete).toHaveBeenCalledWith('/api/strategies/5')
        })
    })

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

            await strategiesApi.startStrategy(5)

            expect(apiClient.post).toHaveBeenCalledWith('/api/strategies/5/start')
        })
    })

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

            await strategiesApi.stopStrategy(5)

            expect(apiClient.post).toHaveBeenCalledWith('/api/strategies/5/stop')
        })
    })

    describe('getStrategyStatus', () => {
        it('calls correct endpoint', async () => {
            const mockStatus = { strategy_id: 5, running: true, name: 'Test' }
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockStatus })

            const result = await strategiesApi.getStrategyStatus(5)

            expect(apiClient.get).toHaveBeenCalledWith('/api/strategies/5/status')
            expect(result).toEqual(mockStatus)
        })
    })

    describe('getRunningStrategies', () => {
        it('calls correct endpoint', async () => {
            const mockResponse = {
                total_running: 2,
                strategies: [{ strategy_id: 1 }, { strategy_id: 2 }],
            }
            vi.mocked(apiClient.get).mockResolvedValue({ data: mockResponse })

            const result = await strategiesApi.getRunningStrategies()

            expect(apiClient.get).toHaveBeenCalledWith('/api/strategies/running/all')
            expect(result).toEqual(mockResponse)
        })
    })
})
