import { describe, it, expect, vi, beforeEach } from 'vitest'
import { adminService } from './adminService'
import { apiClient } from './apiClient'

// Mock apiClient
vi.mock('./apiClient', () => ({
    apiClient: {
        get: vi.fn(),
        post: vi.fn(),
        put: vi.fn(),
        patch: vi.fn(),
        delete: vi.fn(),
    }
}))

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

    describe('Users', () => {
        it('listUsers should call correct endpoint with pagination', async () => {
            const mockResponse = { users: [], total: 0, page: 1, page_size: 10 }
            vi.mocked(apiClient.get).mockResolvedValue(mockResponse)

            const result = await adminService.listUsers(1, 10)

            expect(apiClient.get).toHaveBeenCalledWith('/v1/users?page=1&page_size=10')
            expect(result).toEqual(mockResponse)
        })

        it('getUser should call correct endpoint with id', async () => {
            const mockUser = { id: 'abc123', name: 'Test User' }
            vi.mocked(apiClient.get).mockResolvedValue(mockUser)

            const result = await adminService.getUser('abc123')

            expect(apiClient.get).toHaveBeenCalledWith('/v1/users/abc123')
            expect(result).toEqual(mockUser)
        })

        it('createUser should POST user data', async () => {
            const userData = {
                company_id: 'comp1',
                role: 'Colaborador',
                name: 'New User',
                username: 'newuser',
                email: 'new@test.com',
                password: '123456'
            }
            const mockResponse = { id: 'new123', ...userData }
            vi.mocked(apiClient.post).mockResolvedValue(mockResponse)

            const result = await adminService.createUser(userData)

            expect(apiClient.post).toHaveBeenCalledWith('/v1/users', userData)
            expect(result).toEqual(mockResponse)
        })

        it('updateUser should PUT user data with id', async () => {
            const updateData = { name: 'Updated Name' }
            const mockResponse = { id: 'abc123', name: 'Updated Name' }
            vi.mocked(apiClient.put).mockResolvedValue(mockResponse)

            const result = await adminService.updateUser('abc123', updateData)

            expect(apiClient.put).toHaveBeenCalledWith('/v1/users/abc123', updateData)
            expect(result).toEqual(mockResponse)
        })

        it('deleteUser should DELETE user by id', async () => {
            vi.mocked(apiClient.delete).mockResolvedValue({})

            await adminService.deleteUser('abc123')

            expect(apiClient.delete).toHaveBeenCalledWith('/v1/users/abc123')
        })
    })

    describe('Companies', () => {
        it('listCompanies should call correct endpoint', async () => {
            const mockResponse = { tenants: [], total: 0, page: 1, page_size: 20 }
            vi.mocked(apiClient.get).mockResolvedValue(mockResponse)

            const result = await adminService.listCompanies(1, 20)

            expect(apiClient.get).toHaveBeenCalledWith('/v1/companies?page=1&page_size=20')
            expect(result).toEqual(mockResponse)
        })

        it('createCompany should POST company data', async () => {
            const companyData = {
                cnpj: '12345678000100',
                corporate_name: 'Test Company',
                category: 'farmacia',
                license_number: 'LIC123',
                latitude: -16.32,
                longitude: -48.95,
                city: 'Anápolis',
                state: 'GO'
            }
            vi.mocked(apiClient.post).mockResolvedValue({ id: 'comp1', ...companyData })

            await adminService.createCompany(companyData)

            expect(apiClient.post).toHaveBeenCalledWith('/v1/companies', companyData)
        })

        it('updateCompany should PATCH company data', async () => {
            const updateData = { corporate_name: 'Updated Name' }
            vi.mocked(apiClient.patch).mockResolvedValue({ id: 'comp1', ...updateData })

            await adminService.updateCompany('comp1', updateData)

            expect(apiClient.patch).toHaveBeenCalledWith('/v1/companies/comp1', updateData)
        })

        it('verifyCompany should PATCH verify endpoint', async () => {
            vi.mocked(apiClient.patch).mockResolvedValue({ id: 'comp1', is_verified: true })

            await adminService.verifyCompany('comp1')

            expect(apiClient.patch).toHaveBeenCalledWith('/v1/companies/comp1/verify', {})
        })

        it('deleteCompany should DELETE company by id', async () => {
            vi.mocked(apiClient.delete).mockResolvedValue({})

            await adminService.deleteCompany('comp1')

            expect(apiClient.delete).toHaveBeenCalledWith('/v1/companies/comp1')
        })
    })

    describe('Products', () => {
        it('listProducts should call correct endpoint', async () => {
            const mockResponse = { products: [], total: 0, page: 1, page_size: 20 }
            vi.mocked(apiClient.get).mockResolvedValue(mockResponse)

            const result = await adminService.listProducts(1, 20)

            expect(apiClient.get).toHaveBeenCalledWith('/v1/products?page=1&page_size=20')
            expect(result).toEqual(mockResponse)
        })

        it('createProduct should POST product data', async () => {
            const productData = {
                seller_id: 'seller1',
                name: 'Dipirona 500mg',
                description: 'Analgésico',
                batch: 'L2024001',
                expires_at: '2025-12-31',
                price_cents: 1299,
                stock: 100
            }
            vi.mocked(apiClient.post).mockResolvedValue({ id: 'prod1', ...productData })

            await adminService.createProduct(productData)

            expect(apiClient.post).toHaveBeenCalledWith('/v1/products', productData)
        })

        it('updateProduct should PATCH product data', async () => {
            const updateData = { price_cents: 1599, stock: 50 }
            vi.mocked(apiClient.patch).mockResolvedValue({ id: 'prod1', ...updateData })

            await adminService.updateProduct('prod1', updateData)

            expect(apiClient.patch).toHaveBeenCalledWith('/v1/products/prod1', updateData)
        })

        it('deleteProduct should DELETE product by id', async () => {
            vi.mocked(apiClient.delete).mockResolvedValue({})

            await adminService.deleteProduct('prod1')

            expect(apiClient.delete).toHaveBeenCalledWith('/v1/products/prod1')
        })
    })

    describe('Orders', () => {
        it('listOrders should call correct endpoint', async () => {
            const mockResponse = { orders: [], total: 0, page: 1, page_size: 20 }
            vi.mocked(apiClient.get).mockResolvedValue(mockResponse)

            const result = await adminService.listOrders(1, 20)

            expect(apiClient.get).toHaveBeenCalledWith('/v1/orders?page=1&page_size=20')
            expect(result).toEqual(mockResponse)
        })

        it('updateOrderStatus should PATCH status endpoint', async () => {
            vi.mocked(apiClient.patch).mockResolvedValue({})

            await adminService.updateOrderStatus('order1', 'Pago')

            expect(apiClient.patch).toHaveBeenCalledWith('/v1/orders/order1/status', { status: 'Pago' })
        })

        it('deleteOrder should DELETE order by id', async () => {
            vi.mocked(apiClient.delete).mockResolvedValue({})

            await adminService.deleteOrder('order1')

            expect(apiClient.delete).toHaveBeenCalledWith('/v1/orders/order1')
        })
    })
})
