import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount, flushPromises } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
import { createI18n } from 'vue-i18n'
import CameraView from '@/views/camera/index.vue'
import { wrapResponse, wrapPageResponse, wrapArrayResponse, mockCameras, mockMachines } from '../../../fixtures'

// Mock vue-router
const mockPush = vi.fn()
vi.mock('vue-router', () => ({
  useRouter: () => ({ push: mockPush }),
  useRoute: () => ({ query: {} })
}))

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

// Mock camera API
const mockAdminListCameras = vi.fn()
const mockAdminAddCamera = vi.fn()
const mockAdminUpdateCamera = vi.fn()
const mockAdminDeleteCamera = vi.fn()
const mockAdminCheckCamera = vi.fn()

vi.mock('@/api/camera', () => ({
  adminListCameras: (...args: any[]) => mockAdminListCameras(...args),
  adminAddCamera: (...args: any[]) => mockAdminAddCamera(...args),
  adminUpdateCamera: (...args: any[]) => mockAdminUpdateCamera(...args),
  adminDeleteCamera: (...args: any[]) => mockAdminDeleteCamera(...args),
  adminCheckCamera: (...args: any[]) => mockAdminCheckCamera(...args)
}))

// Mock machine API
const mockListAllMachines = vi.fn()
vi.mock('@/api/machine', () => ({
  listAllMachines: () => mockListAllMachines()
}))

// Create i18n instance
const i18n = createI18n({
  legacy: false,
  locale: 'zh-CN',
  messages: {
    'zh-CN': {
      摄像头管理: '摄像头管理',
      新增摄像头: '新增摄像头',
      刷新列表: '刷新列表',
      搜索: '搜索',
      重置: '重置',
      编辑: '编辑',
      删除: '删除',
      检测: '检测',
      查看通道: '查看通道',
      确认删除: '确认删除',
      在线: '在线',
      离线: '离线',
      全部: '全部',
      状态: '状态',
      机器: '机器',
      摄像头ID: '摄像头ID',
      名称: '名称',
      品牌: '品牌',
      IP地址: 'IP地址',
      端口: '端口',
      操作: '操作',
      取消: '取消',
      确定: '确定'
    }
  }
})

describe('Camera View', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    vi.clearAllMocks()
    mockAdminListCameras.mockResolvedValue(wrapPageResponse(mockCameras))
    mockListAllMachines.mockResolvedValue(wrapArrayResponse(mockMachines))
  })

  const mountCamera = () => {
    return mount(CameraView, {
      global: {
        plugins: [createPinia(), i18n],
        stubs: {
          'el-form': { template: '<form><slot /></form>' },
          'el-form-item': { template: '<div class="el-form-item"><slot /></div>' },
          'el-input': {
            template: '<input :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)" />',
            props: ['modelValue', 'placeholder', 'disabled', 'type']
          },
          'el-input-number': {
            template:
              '<input type="number" :value="modelValue" @input="$emit(\'update:modelValue\', parseInt($event.target.value))" />',
            props: ['modelValue', 'min', 'max']
          },
          'el-select': {
            template:
              '<select :value="modelValue" @change="$emit(\'update:modelValue\', $event.target.value); $emit(\'change\', $event.target.value)"><slot /></select>',
            props: ['modelValue', 'placeholder', 'clearable']
          },
          'el-option': {
            template: '<option :value="value">{{ label }}</option>',
            props: ['label', 'value']
          },
          'el-button': {
            template: '<button :type="htmlType" :disabled="loading" @click="$emit(\'click\')"><slot /></button>',
            props: ['type', 'icon', 'loading', 'link', 'plain'],
            computed: {
              htmlType() {
                return 'button'
              }
            }
          },
          'el-table': {
            template: '<table class="el-table"><slot /></table>',
            props: ['data', 'loading', 'border']
          },
          'el-table-column': {
            template: '<td class="el-table-column"></td>',
            props: ['prop', 'label', 'width', 'align', 'type', 'fixed', 'minWidth', 'showOverflowTooltip']
          },
          'el-tag': {
            template: '<span class="el-tag"><slot /></span>',
            props: ['type']
          },
          'el-dialog': {
            template: '<div v-if="modelValue" class="el-dialog"><slot /><slot name="footer" /></div>',
            props: ['modelValue', 'title', 'width', 'destroyOnClose']
          },
          'el-row': { template: '<div class="el-row"><slot /></div>' },
          'el-col': { template: '<div class="el-col"><slot /></div>', props: ['span'] },
          'el-switch': {
            template:
              '<input type="checkbox" :checked="modelValue" @change="$emit(\'update:modelValue\', $event.target.checked)" />',
            props: ['modelValue']
          }
        }
      }
    })
  }

  describe('页面渲染', () => {
    it('应该正确渲染摄像头管理页面', async () => {
      const wrapper = mountCamera()
      await flushPromises()

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

    it('应该显示新增摄像头按钮', async () => {
      const wrapper = mountCamera()
      await flushPromises()

      const buttons = wrapper.findAll('.search-form button')
      const addButton = buttons.find((b) => b.text().includes('新增'))
      expect(addButton).toBeDefined()
    })

    it('应该显示查询和重置按钮', async () => {
      const wrapper = mountCamera()
      await flushPromises()

      const buttons = wrapper.findAll('.search-form button')
      const searchBtn = buttons.find((b) => b.text().includes('查询'))
      const resetBtn = buttons.find((b) => b.text().includes('重置'))
      expect(searchBtn).toBeDefined()
      expect(resetBtn).toBeDefined()
    })
  })

  describe('数据加载', () => {
    it('页面加载时应该获取摄像头列表', async () => {
      mountCamera()
      await flushPromises()

      expect(mockAdminListCameras).toHaveBeenCalled()
    })

    it('页面加载时应该获取机器列表', async () => {
      mountCamera()
      await flushPromises()

      expect(mockListAllMachines).toHaveBeenCalled()
    })
  })

  describe('搜索和过滤', () => {
    it('选择机器应该触发查询', async () => {
      const wrapper = mountCamera()
      await flushPromises()

      mockAdminListCameras.mockClear()

      const searchBtn = wrapper.findAll('button').find((btn) => btn.text().includes('搜索'))
      if (searchBtn) {
        await searchBtn.trigger('click')
        await flushPromises()
        expect(mockAdminListCameras).toHaveBeenCalled()
      }
    })

    it('重置应该清空筛选条件', async () => {
      const wrapper = mountCamera()
      await flushPromises()

      mockAdminListCameras.mockClear()

      const resetBtn = wrapper.findAll('button').find((btn) => btn.text().includes('重置'))
      if (resetBtn) {
        await resetBtn.trigger('click')
        await flushPromises()
        expect(mockAdminListCameras).toHaveBeenCalled()
      }
    })
  })

  describe('新增摄像头', () => {
    it('点击新增按钮应该打开弹窗', async () => {
      const wrapper = mountCamera()
      await flushPromises()

      const addBtn = wrapper.findAll('button').find((btn) => btn.text().includes('新增摄像头'))
      if (addBtn) {
        await addBtn.trigger('click')
        await flushPromises()
        expect(wrapper.find('.el-dialog').exists()).toBe(true)
      }
    })

    it('新增摄像头成功应该刷新列表', async () => {
      mockAdminAddCamera.mockResolvedValue(wrapResponse({ id: 4, cameraId: 'cam-004' }))

      const wrapper = mountCamera()
      await flushPromises()

      expect(mockAdminListCameras).toHaveBeenCalled()
    })
  })

  describe('编辑摄像头', () => {
    it('编辑摄像头成功应该刷新列表', async () => {
      mockAdminUpdateCamera.mockResolvedValue(wrapResponse(mockCameras[0]))

      const wrapper = mountCamera()
      await flushPromises()

      expect(mockAdminListCameras).toHaveBeenCalled()
    })
  })

  describe('删除摄像头', () => {
    it('删除摄像头成功应该刷新列表', async () => {
      mockAdminDeleteCamera.mockResolvedValue(wrapResponse(null))

      const wrapper = mountCamera()
      await flushPromises()

      expect(mockAdminListCameras).toHaveBeenCalled()
    })
  })

  describe('检测摄像头', () => {
    it('检测成功应该显示成功消息', async () => {
      mockAdminCheckCamera.mockResolvedValue(wrapResponse(true))

      const wrapper = mountCamera()
      await flushPromises()

      expect(mockAdminListCameras).toHaveBeenCalled()
    })

    it('检测失败应该显示警告消息', async () => {
      mockAdminCheckCamera.mockResolvedValue(wrapResponse(false))

      const wrapper = mountCamera()
      await flushPromises()

      expect(mockAdminListCameras).toHaveBeenCalled()
    })
  })

  describe('通道列表', () => {
    it('应该能够显示通道弹窗', async () => {
      const wrapper = mountCamera()
      await flushPromises()

      expect(wrapper.html()).toBeDefined()
    })
  })

  describe('状态过滤', () => {
    it('选择在线状态应该过滤列表', async () => {
      const wrapper = mountCamera()
      await flushPromises()

      expect(wrapper.html()).toBeDefined()
    })

    it('选择离线状态应该过滤列表', async () => {
      const wrapper = mountCamera()
      await flushPromises()

      expect(wrapper.html()).toBeDefined()
    })
  })

  describe('错误处理', () => {
    it('API 返回错误码应该正确处理', async () => {
      mockAdminListCameras.mockResolvedValue(wrapResponse([], false, '获取失败'))

      const wrapper = mountCamera()
      await flushPromises()

      expect(mockAdminListCameras).toHaveBeenCalled()
    })
  })
})
