import { describe, it, expect } from 'vitest'
import { testClient } from 'hono/testing'
import { dashRoutes } from '@/server/api'
import {
  setupIntegrationDatabaseHooks,
} from '~/utils/server/integration-test-db'

// 设置集成测试钩子
setupIntegrationDatabaseHooks()

describe('财务数据API集成测试', () => {
  const client = testClient(dashRoutes).api.v1

  describe('GET /outlook - 获取财务数据', () => {
    it('应该成功返回财务数据结构', async () => {
      const response = await client.dash.outlook.$get()

      expect(response.status).toBe(200)

      if (response.status === 200) {
        const responseData = await response.json()

        // 验证响应结构
        expect(responseData).toHaveProperty('code', 200)
        expect(responseData).toHaveProperty('msg', '查询成功')
        expect(responseData).toHaveProperty('rows')
        expect(Array.isArray(responseData.rows)).toBe(true)

        // 验证第一个数据行的结构
        const firstRow = responseData.rows[0]
        expect(firstRow).toHaveProperty('assetTotalNet')
        expect(firstRow).toHaveProperty('profitTotalNet')
        expect(firstRow).toHaveProperty('incomeStatement')
        expect(firstRow).toHaveProperty('assetLiabilityRatio')

        // 验证资产总额与资产净额数据结构
        expect(Array.isArray(firstRow.assetTotalNet)).toBe(true)
        if (firstRow.assetTotalNet.length > 0) {
          const assetData = firstRow.assetTotalNet[0]
          expect(assetData).toHaveProperty('id')
          expect(assetData).toHaveProperty('year')
          expect(assetData).toHaveProperty('assetTotal')
          expect(assetData).toHaveProperty('assetNet')
          expect(assetData).toHaveProperty('dataDeadline')
          expect(assetData).toHaveProperty('createTime')
          expect(assetData).toHaveProperty('updateTime')
        }

        // 验证利润总额与净利润数据结构
        expect(Array.isArray(firstRow.profitTotalNet)).toBe(true)
        if (firstRow.profitTotalNet.length > 0) {
          const profitData = firstRow.profitTotalNet[0]
          expect(profitData).toHaveProperty('id')
          expect(profitData).toHaveProperty('year')
          expect(profitData).toHaveProperty('profitTotal')
          expect(profitData).toHaveProperty('profitNet')
          expect(profitData).toHaveProperty('dataDeadline')
          expect(profitData).toHaveProperty('createTime')
          expect(profitData).toHaveProperty('updateTime')
        }

        // 验证收入数据结构
        expect(Array.isArray(firstRow.incomeStatement)).toBe(true)
        if (firstRow.incomeStatement.length > 0) {
          const incomeData = firstRow.incomeStatement[0]
          expect(incomeData).toHaveProperty('id')
          expect(incomeData).toHaveProperty('year')
          expect(incomeData).toHaveProperty('income')
          expect(incomeData).toHaveProperty('dataDeadline')
          expect(incomeData).toHaveProperty('createTime')
          expect(incomeData).toHaveProperty('updateTime')
        }

        // 验证资产负债率数据结构
        expect(Array.isArray(firstRow.assetLiabilityRatio)).toBe(true)
        if (firstRow.assetLiabilityRatio.length > 0) {
          const ratioData = firstRow.assetLiabilityRatio[0]
          expect(ratioData).toHaveProperty('id')
          expect(ratioData).toHaveProperty('year')
          expect(ratioData).toHaveProperty('assetLiabilityRatio')
          expect(ratioData).toHaveProperty('dataDeadline')
          expect(ratioData).toHaveProperty('createTime')
          expect(ratioData).toHaveProperty('updateTime')
        }
      }
    })

    it('应该返回正确的mock数据值', async () => {
      const response = await client.dash.outlook.$get()

      expect(response.status).toBe(200)

      if (response.status === 200) {
        const responseData = await response.json()
        const firstRow = responseData.rows[0]

        // 验证资产数据值
        const assetData = firstRow.assetTotalNet[0]
        expect(assetData.assetTotal).toBe(150000000)
        expect(assetData.assetNet).toBe(120000000)
        expect(assetData.year).toBe(2024)

        // 验证利润数据值
        const profitData = firstRow.profitTotalNet[0]
        expect(profitData.profitTotal).toBe(25000000)
        expect(profitData.profitNet).toBe(20000000)
        expect(profitData.year).toBe(2024)

        // 验证收入数据值
        const incomeData = firstRow.incomeStatement[0]
        expect(incomeData.income).toBe(80000000)
        expect(incomeData.year).toBe(2024)

        // 验证资产负债率数据值
        const ratioData = firstRow.assetLiabilityRatio[0]
        expect(ratioData.assetLiabilityRatio).toBe(45.2)
        expect(ratioData.year).toBe(2024)
      }
    })

    it('应该包含多个年份的数据', async () => {
      const response = await client.dash.outlook.$get()

      expect(response.status).toBe(200)

      if (response.status === 200) {
        const responseData = await response.json()
        const firstRow = responseData.rows[0]

        // 验证每个数据模块都包含多个年份的数据
        expect(firstRow.assetTotalNet.length).toBeGreaterThan(1)
        expect(firstRow.profitTotalNet.length).toBeGreaterThan(1)
        expect(firstRow.incomeStatement.length).toBeGreaterThan(1)
        expect(firstRow.assetLiabilityRatio.length).toBeGreaterThan(1)

        // 验证年份数据
        const assetYears = firstRow.assetTotalNet.map((item: any) => item.year)
        expect(assetYears).toContain(2024)
        expect(assetYears).toContain(2023)

        const profitYears = firstRow.profitTotalNet.map((item: any) => item.year)
        expect(profitYears).toContain(2024)
        expect(profitYears).toContain(2023)

        const incomeYears = firstRow.incomeStatement.map((item: any) => item.year)
        expect(incomeYears).toContain(2024)
        expect(incomeYears).toContain(2023)

        const ratioYears = firstRow.assetLiabilityRatio.map((item: any) => item.year)
        expect(ratioYears).toContain(2024)
        expect(ratioYears).toContain(2023)
      }
    })

    it('应该正确处理错误场景', async () => {
      // 由于这是一个简单的mock API，主要测试正常流程
      // 错误处理在路由中已有基本实现
      const response = await client.dash.outlook.$get()
      expect(response.status).toBe(200)
    })
  })

  describe('API性能测试', () => {
    it('响应时间应小于100ms', async () => {
      const startTime = Date.now()
      const response = await client.dash.outlook.$get()
      const endTime = Date.now()
      const responseTime = endTime - startTime

      expect(response.status).toBe(200)
      expect(responseTime).toBeLessThan(100) // 响应时间应小于100ms
    })
  })
})