import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount, flushPromises } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import StatsView from '@/views/stats/index.vue'
import { wrapResponse, mockDashboardStats } from '../../../fixtures'

// Mock element-plus
vi.mock('element-plus', () => ({
  ElMessage: {
    success: vi.fn(),
    error: vi.fn(),
    info: vi.fn()
  }
}))

// Mock stats API
const mockGetDashboardStats = vi.fn()
vi.mock('@/api/stats', () => ({
  getDashboardStats: () => mockGetDashboardStats()
}))

describe('Stats View', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    vi.clearAllMocks()
    mockGetDashboardStats.mockResolvedValue(wrapResponse(mockDashboardStats))
  })

  const mountStats = () => {
    return mount(StatsView, {
      global: {
        plugins: [createPinia()],
        stubs: {
          'el-card': { template: '<div class="el-card"><slot /><slot name="header" /></div>', props: ['shadow'] },
          'el-form': { template: '<form class="el-form"><slot /></form>' },
          'el-form-item': { template: '<div class="el-form-item"><slot /></div>', props: ['label'] },
          'el-button': {
            template: '<button @click="$emit(\'click\')" :disabled="loading"><slot /></button>',
            props: ['type', 'icon', 'loading']
          },
          'el-row': { template: '<div class="el-row"><slot /></div>', props: ['gutter'] },
          'el-col': { template: '<div class="el-col"><slot /></div>', props: ['xs', 'sm', 'lg'] },
          'el-statistic': {
            template:
              '<div class="el-statistic"><span class="title">{{ title }}</span><span class="value">{{ value }}</span><slot name="prefix" /></div>',
            props: ['title', 'value', 'suffix']
          },
          'el-icon': { template: '<span class="el-icon"><slot /></span>' },
          'el-empty': {
            template: '<div class="el-empty"><slot name="image" />{{ description }}</div>',
            props: ['description']
          },
          Monitor: { template: '<span>Monitor</span>' },
          VideoCamera: { template: '<span>VideoCamera</span>' },
          Connection: { template: '<span>Connection</span>' },
          CircleCheck: { template: '<span>CircleCheck</span>' },
          TrendCharts: { template: '<span>TrendCharts</span>' },
          Refresh: { template: '<span>Refresh</span>' }
        }
      }
    })
  }

  describe('页面渲染', () => {
    it('应该正确渲染统计页面', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.find('.page-container').exists()).toBe(true)
    })

    it('应该显示刷新按钮', async () => {
      const wrapper = mountStats()
      await flushPromises()

      const refreshBtn = wrapper.find('.filter-card button')
      expect(refreshBtn.exists()).toBe(true)
      expect(refreshBtn.text()).toContain('刷新')
    })

    it('应该显示统计卡片', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.find('.summary-cards').exists()).toBe(true)
    })

    it('应该显示状态图表区域', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.find('.status-card').exists()).toBe(true)
    })
  })

  describe('数据加载', () => {
    it('页面加载时应该获取统计数据', async () => {
      mountStats()
      await flushPromises()

      expect(mockGetDashboardStats).toHaveBeenCalled()
    })

    it('应该正确显示机器总数', async () => {
      const wrapper = mountStats()
      await flushPromises()

      const stats = wrapper.findAll('.el-statistic')
      expect(stats.length).toBeGreaterThan(0)
    })

    it('应该正确显示摄像头总数', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.html()).toContain(String(mockDashboardStats.cameraTotal))
    })

    it('应该正确显示通道总数', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.html()).toContain(String(mockDashboardStats.channelTotal))
    })

    it('应该正确计算在线率', async () => {
      const wrapper = mountStats()
      await flushPromises()

      const expectedRate = Math.round((mockDashboardStats.cameraOnline / mockDashboardStats.cameraTotal) * 100)
      expect(wrapper.html()).toContain(String(expectedRate))
    })
  })

  describe('刷新功能', () => {
    it('点击刷新按钮应该重新加载数据', async () => {
      const wrapper = mountStats()
      await flushPromises()

      mockGetDashboardStats.mockClear()

      const refreshBtn = wrapper.find('.filter-card button')
      await refreshBtn.trigger('click')
      await flushPromises()

      expect(mockGetDashboardStats).toHaveBeenCalled()
    })
  })

  describe('状态条显示', () => {
    it('应该显示在线状态条', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.find('.status-item.online').exists()).toBe(true)
    })

    it('应该显示离线状态条', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.find('.status-item.offline').exists()).toBe(true)
    })

    it('应该显示已启用状态条', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.find('.status-item.enabled').exists()).toBe(true)
    })

    it('应该显示已禁用状态条', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.find('.status-item.disabled').exists()).toBe(true)
    })
  })

  describe('更新时间显示', () => {
    it('数据加载后应该显示更新时间', async () => {
      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.find('.update-time').exists()).toBe(true)
    })
  })

  describe('错误处理', () => {
    it('API 返回错误码应该正确处理', async () => {
      mockGetDashboardStats.mockResolvedValue(wrapResponse(null, false, '服务器错误'))

      mountStats()
      await flushPromises()

      expect(mockGetDashboardStats).toHaveBeenCalled()
    })

    it('API 返回空数据应该正确处理', async () => {
      mockGetDashboardStats.mockResolvedValue(wrapResponse(null))

      mountStats()
      await flushPromises()

      expect(mockGetDashboardStats).toHaveBeenCalled()
    })
  })

  describe('空数据处理', () => {
    it('无数据时在线率应该为 0', async () => {
      mockGetDashboardStats.mockResolvedValue(
        wrapResponse({
          machineTotal: 0,
          machineEnabled: 0,
          cameraTotal: 0,
          cameraOnline: 0,
          cameraOffline: 0,
          channelTotal: 0
        })
      )

      const wrapper = mountStats()
      await flushPromises()

      expect(wrapper.html()).toContain('0')
    })
  })
})
