import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import { authService } from './auth'
import { apiClient } from './apiClient'

// Mock the apiClient module
vi.mock('./apiClient', () => ({
    apiClient: {
        post: vi.fn(),
        setToken: vi.fn()
    }
}))

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

    afterEach(() => {
        vi.restoreAllMocks()
    })

    describe('login', () => {
        it('should login successfully with valid credentials', async () => {
            // apiClient now returns data directly, not response.data
            const mockData = {
                token: 'jwt-token-123',
                expires_at: '2024-12-23T00:00:00Z'
            }
            vi.mocked(apiClient.post).mockResolvedValue(mockData)

            const result = await authService.login({
                username: 'admin',
                password: 'admin123'
            })

            expect(apiClient.post).toHaveBeenCalledWith('/v1/auth/login', {
                username: 'admin',
                password: 'admin123'
            })
            expect(result.token).toBe('jwt-token-123')
            expect(result.expiresAt).toBe('2024-12-23T00:00:00Z')
        })

        it('should throw error for invalid credentials', async () => {
            const error = new Error('Unauthorized')
                ; (error as any).response = { status: 401 }
            vi.mocked(apiClient.post).mockRejectedValue(error)

            await expect(
                authService.login({
                    username: 'admin',
                    password: 'wrongpassword'
                })
            ).rejects.toThrow('Unauthorized')

            expect(apiClient.post).toHaveBeenCalledWith('/v1/auth/login', {
                username: 'admin',
                password: 'wrongpassword'
            })
        })

        it('should throw error for non-existent user', async () => {
            const error = new Error('User not found')
                ; (error as any).response = { status: 401 }
            vi.mocked(apiClient.post).mockRejectedValue(error)

            await expect(
                authService.login({
                    username: 'nonexistent',
                    password: 'password'
                })
            ).rejects.toThrow()
        })
    })

    describe('logout', () => {
        it('should call logout endpoint', async () => {
            vi.mocked(apiClient.post).mockResolvedValue({})

            await authService.logout()

            expect(apiClient.post).toHaveBeenCalledWith('/v1/auth/logout')
        })

        it('should handle logout errors gracefully', async () => {
            vi.mocked(apiClient.post).mockRejectedValue(new Error('Network error'))

            await expect(authService.logout()).rejects.toThrow('Network error')
        })
    })
})
