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

// Mock client module
vi.mock('../api/client', () => {
  return {
    default: {
      get: vi.fn(),
      post: vi.fn(),
      put: vi.fn(),
      delete: vi.fn(),
    }
  }
})

import client from '../api/client'
import { financeApi } from '../api/finance'

beforeEach(() => {
  vi.clearAllMocks()
})

describe('financeApi', () => {
  // Categories
  describe('categories', () => {
    it('listCategories calls GET finance/categories', async () => {
      const mockData = [{ id: 1, name: 'Еда', emoji: '🍔' }]
      client.get.mockResolvedValue({ data: mockData })
      const result = await financeApi.listCategories()
      expect(client.get).toHaveBeenCalledWith('finance/categories')
      expect(result).toEqual(mockData)
    })

    it('createCategory calls POST finance/categories', async () => {
      const input = { name: 'Test', type: 'expense', emoji: '🧪' }
      const mockData = { id: 1, ...input }
      client.post.mockResolvedValue({ data: mockData })
      const result = await financeApi.createCategory(input)
      expect(client.post).toHaveBeenCalledWith('finance/categories', input)
      expect(result).toEqual(mockData)
    })

    it('updateCategory calls PUT finance/categories/:id', async () => {
      const data = { name: 'Updated' }
      client.put.mockResolvedValue({ data: { id: 5, ...data } })
      const result = await financeApi.updateCategory(5, data)
      expect(client.put).toHaveBeenCalledWith('finance/categories/5', data)
      expect(result.name).toBe('Updated')
    })

    it('deleteCategory calls DELETE finance/categories/:id', async () => {
      client.delete.mockResolvedValue({})
      await financeApi.deleteCategory(3)
      expect(client.delete).toHaveBeenCalledWith('finance/categories/3')
    })
  })

  // Transactions
  describe('transactions', () => {
    it('listTransactions calls GET with params', async () => {
      const mockData = [{ id: 1, amount: 500 }]
      client.get.mockResolvedValue({ data: mockData })
      const params = { month: 3, year: 2026 }
      const result = await financeApi.listTransactions(params)
      expect(client.get).toHaveBeenCalledWith('finance/transactions', { params })
      expect(result).toEqual(mockData)
    })

    it('listTransactions works without params', async () => {
      client.get.mockResolvedValue({ data: [] })
      const result = await financeApi.listTransactions()
      expect(client.get).toHaveBeenCalledWith('finance/transactions', { params: {} })
      expect(result).toEqual([])
    })

    it('createTransaction calls POST', async () => {
      const input = { amount: 100, type: 'expense', category_id: 1, date: '2026-03-01' }
      client.post.mockResolvedValue({ data: { id: 1, ...input } })
      const result = await financeApi.createTransaction(input)
      expect(client.post).toHaveBeenCalledWith('finance/transactions', input)
      expect(result.amount).toBe(100)
    })

    it('updateTransaction calls PUT', async () => {
      const data = { amount: 200 }
      client.put.mockResolvedValue({ data: { id: 7, ...data } })
      const result = await financeApi.updateTransaction(7, data)
      expect(client.put).toHaveBeenCalledWith('finance/transactions/7', data)
      expect(result.amount).toBe(200)
    })

    it('deleteTransaction calls DELETE', async () => {
      client.delete.mockResolvedValue({})
      await financeApi.deleteTransaction(10)
      expect(client.delete).toHaveBeenCalledWith('finance/transactions/10')
    })
  })

  // Summary & Analytics
  describe('summary & analytics', () => {
    it('getSummary calls GET with params', async () => {
      const mockData = { balance: 5000, total_income: 10000, total_expense: 5000 }
      client.get.mockResolvedValue({ data: mockData })
      const result = await financeApi.getSummary({ month: 3, year: 2026 })
      expect(client.get).toHaveBeenCalledWith('finance/summary', { params: { month: 3, year: 2026 } })
      expect(result.balance).toBe(5000)
    })

    it('getAnalytics calls GET with params', async () => {
      const mockData = { monthly_trend: [], avg_daily_expense: 500 }
      client.get.mockResolvedValue({ data: mockData })
      const result = await financeApi.getAnalytics({ months: 6 })
      expect(client.get).toHaveBeenCalledWith('finance/analytics', { params: { months: 6 } })
      expect(result.avg_daily_expense).toBe(500)
    })
  })
})
