import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { describe, it, expect, beforeAll, afterEach, afterAll } from 'vitest'
import { getStats } from '@/api/stats'

const mockStats = [
  {
    id: 1,
    provider_id: 'prov-1',
    model_name: 'gpt-4',
    request_count: 100,
    date: '2025-01-15',
  },
  {
    id: 2,
    provider_id: 'prov-2',
    model_name: 'claude-3',
    request_count: 50,
    date: '2025-01-16',
  },
]

describe('stats API', () => {
  const server = setupServer()

  beforeAll(() => server.listen({ onUnhandledRequest: 'bypass' }))
  afterEach(() => server.resetHandlers())
  afterAll(() => server.close())

  describe('getStats', () => {
    it('calls /api/stats without params', async () => {
      let receivedUrl: string | null = null

      server.use(
        http.get('http://localhost:3000/api/stats', ({ request }) => {
          receivedUrl = request.url
          return HttpResponse.json(mockStats)
        })
      )

      const result = await getStats()

      expect(receivedUrl).toMatch(/\/api\/stats$/)
      expect(result).toEqual([
        {
          id: 1,
          providerId: 'prov-1',
          modelName: 'gpt-4',
          requestCount: 100,
          date: '2025-01-15',
        },
        {
          id: 2,
          providerId: 'prov-2',
          modelName: 'claude-3',
          requestCount: 50,
          date: '2025-01-16',
        },
      ])
    })

    it('builds correct query string with snake_case keys when params are provided', async () => {
      let receivedUrl: string | null = null

      server.use(
        http.get('http://localhost:3000/api/stats', ({ request }) => {
          receivedUrl = request.url
          return HttpResponse.json([])
        })
      )

      await getStats({
        providerId: 'prov-1',
        modelName: 'gpt-4',
        startDate: '2025-01-01',
        endDate: '2025-01-31',
      })

      expect(receivedUrl).toContain('provider_id=prov-1')
      expect(receivedUrl).toContain('model_name=gpt-4')
      expect(receivedUrl).toContain('start_date=2025-01-01')
      expect(receivedUrl).toContain('end_date=2025-01-31')
    })

    it('omits undefined params from query string', async () => {
      let receivedUrl: string | null = null

      server.use(
        http.get('http://localhost:3000/api/stats', ({ request }) => {
          receivedUrl = request.url
          return HttpResponse.json([])
        })
      )

      await getStats({
        providerId: 'prov-1',
      })

      expect(receivedUrl).toContain('provider_id=prov-1')
      expect(receivedUrl).not.toContain('model_name')
      expect(receivedUrl).not.toContain('start_date')
      expect(receivedUrl).not.toContain('end_date')
    })

    it('returns UsageStats array with camelCase keys', async () => {
      server.use(
        http.get('http://localhost:3000/api/stats', () => {
          return HttpResponse.json(mockStats)
        })
      )

      const result = await getStats()

      expect(result).toHaveLength(2)
      expect(result[0]).toEqual({
        id: 1,
        providerId: 'prov-1',
        modelName: 'gpt-4',
        requestCount: 100,
        date: '2025-01-15',
      })
      expect(result[1]).toEqual({
        id: 2,
        providerId: 'prov-2',
        modelName: 'claude-3',
        requestCount: 50,
        date: '2025-01-16',
      })
    })
  })
})
