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

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

// Mock audit logs
const mockAuditLogs = [
  {
    id: '1',
    created_at: Math.floor(Date.now() / 1000),
    user_id: 'user-1',
    username: 'admin',
    action: 'create',
    resource: 'camera',
    resource_id: 'cam-001',
    ip_address: '192.168.1.1',
    user_agent: 'Mozilla/5.0',
    parsedDetails: { message: '创建了摄像头' }
  },
  {
    id: '2',
    created_at: Math.floor(Date.now() / 1000) - 3600,
    user_id: 'user-1',
    username: 'admin',
    action: 'update',
    resource: 'user',
    resource_id: 'user-2',
    ip_address: '192.168.1.1',
    user_agent: 'Mozilla/5.0',
    parsedDetails: { message: '更新了用户信息' }
  },
  {
    id: '3',
    created_at: Math.floor(Date.now() / 1000) - 7200,
    user_id: 'user-1',
    username: 'admin',
    action: 'login',
    resource: 'auth',
    resource_id: null,
    ip_address: '192.168.1.1',
    user_agent: 'Mozilla/5.0',
    parsedDetails: { message: '用户登录' }
  }
]

// Mock audit API
const mockGetAuditLogs = vi.fn()
vi.mock('@/api/audit', () => ({
  getAuditLogs: (...args: any[]) => mockGetAuditLogs(...args)
}))

describe('Audit View', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    vi.clearAllMocks()
    mockGetAuditLogs.mockResolvedValue(wrapListResponse(mockAuditLogs, 3))
  })

  const mountAudit = () => {
    return mount(AuditView, {
      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-select': {
            template:
              '<select :value="modelValue" @change="$emit(\'update:modelValue\', $event.target.value)"><slot /></select>',
            props: ['modelValue', 'placeholder', 'clearable']
          },
          'el-option': { template: '<option :value="value">{{ label }}</option>', props: ['label', 'value'] },
          'el-date-picker': {
            template:
              '<input type="date" :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)" />',
            props: ['modelValue', 'type', 'rangeSeparator', 'startPlaceholder', 'endPlaceholder', 'valueFormat']
          },
          'el-button': {
            template: '<button @click="$emit(\'click\')" :disabled="loading"><slot /></button>',
            props: ['type', 'icon', 'loading', 'link', 'size']
          },
          'el-row': { template: '<div class="el-row"><slot /></div>', props: ['gutter'] },
          'el-col': { template: '<div class="el-col"><slot /></div>', props: ['xs', 'sm'] },
          'el-statistic': {
            template: '<div class="el-statistic"><span>{{ title }}</span><span>{{ value }}</span></div>',
            props: ['title', 'value']
          },
          'el-table': {
            template: '<table class="el-table"><slot /></table>',
            props: ['data', 'loading', 'border', 'stripe']
          },
          'el-table-column': {
            template: '<td class="el-table-column"></td>',
            props: ['prop', 'label', 'width', 'align', 'showOverflowTooltip', 'fixed', 'minWidth']
          },
          'el-tag': { template: '<span class="el-tag" :class="type"><slot /></span>', props: ['type', 'size'] },
          'el-pagination': {
            template: '<div class="el-pagination"></div>',
            props: ['currentPage', 'pageSize', 'pageSizes', 'total', 'layout']
          },
          'el-dialog': {
            template: '<div v-if="modelValue" class="el-dialog"><slot /><slot name="footer" /></div>',
            props: ['modelValue', 'title', 'width']
          },
          'el-descriptions': { template: '<div class="el-descriptions"><slot /></div>', props: ['column', 'border'] },
          'el-descriptions-item': { template: '<div class="el-descriptions-item"><slot /></div>', props: ['label'] },
          Search: { template: '<span>Search</span>' },
          Refresh: { template: '<span>Refresh</span>' }
        }
      }
    })
  }

  describe('页面渲染', () => {
    it('应该正确渲染审计日志页面', async () => {
      const wrapper = mountAudit()
      await flushPromises()

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

    it('应该显示搜索区域', async () => {
      const wrapper = mountAudit()
      await flushPromises()

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

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

      expect(wrapper.find('.stat-row').exists()).toBe(true)
    })

    it('应该显示数据表格', async () => {
      const wrapper = mountAudit()
      await flushPromises()

      expect(wrapper.find('.el-table').exists()).toBe(true)
    })

    it('应该显示分页组件', async () => {
      const wrapper = mountAudit()
      await flushPromises()

      expect(wrapper.find('.el-pagination').exists()).toBe(true)
    })
  })

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

      expect(mockGetAuditLogs).toHaveBeenCalled()
    })

    it('应该正确传递分页参数', async () => {
      mountAudit()
      await flushPromises()

      expect(mockGetAuditLogs).toHaveBeenCalledWith(
        expect.objectContaining({
          page: 1,
          pageSize: 20
        })
      )
    })
  })

  describe('搜索和过滤', () => {
    it('点击搜索按钮应该触发查询', async () => {
      const wrapper = mountAudit()
      await flushPromises()

      mockGetAuditLogs.mockClear()

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

    it('点击重置按钮应该清空筛选条件', async () => {
      const wrapper = mountAudit()
      await flushPromises()

      mockGetAuditLogs.mockClear()

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

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

      mockGetAuditLogs.mockClear()

      const refreshBtn = wrapper.findAll('button').find((btn) => btn.text().includes('刷新'))
      if (refreshBtn) {
        await refreshBtn.trigger('click')
        await flushPromises()
        expect(mockGetAuditLogs).toHaveBeenCalled()
      }
    })
  })

  describe('操作类型标签', () => {
    it('创建操作应该显示为 success 类型', async () => {
      const wrapper = mountAudit()
      await flushPromises()

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

    it('更新操作应该显示为 warning 类型', async () => {
      const wrapper = mountAudit()
      await flushPromises()

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

    it('删除操作应该显示为 danger 类型', async () => {
      const wrapper = mountAudit()
      await flushPromises()

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

  describe('详情弹窗', () => {
    it('点击详情按钮应该打开弹窗', async () => {
      const wrapper = mountAudit()
      await flushPromises()

      const detailBtn = wrapper.findAll('button').find((btn) => btn.text().includes('详情'))
      if (detailBtn) {
        await detailBtn.trigger('click')
        await flushPromises()
        expect(wrapper.find('.el-dialog').exists()).toBe(true)
      }
    })
  })

  describe('统计计数', () => {
    it('应该正确统计创建操作数量', async () => {
      const wrapper = mountAudit()
      await flushPromises()

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

    it('应该正确统计更新操作数量', async () => {
      const wrapper = mountAudit()
      await flushPromises()

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

  describe('错误处理', () => {
    it('API 返回错误码应该正确处理', async () => {
      mockGetAuditLogs.mockResolvedValue(wrapResponse(null, false, '获取审计日志失败'))

      mountAudit()
      await flushPromises()

      expect(mockGetAuditLogs).toHaveBeenCalled()
    })

    it('API 返回空数据应该正确处理', async () => {
      mockGetAuditLogs.mockResolvedValue(wrapListResponse([], 0))

      mountAudit()
      await flushPromises()

      expect(mockGetAuditLogs).toHaveBeenCalled()
    })
  })

  describe('时间格式化', () => {
    it('应该正确格式化时间戳', async () => {
      const wrapper = mountAudit()
      await flushPromises()

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

  describe('资源类型标签', () => {
    it('应该正确显示资源类型', async () => {
      const wrapper = mountAudit()
      await flushPromises()

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