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 MachineView from '@/views/machine/index.vue'
import { wrapResponse, wrapListResponse, mockMachines } from '../../../fixtures'

// Create i18n instance for tests
const i18n = createI18n({
  legacy: false,
  locale: 'zh-cn',
  messages: {
    'zh-cn': {},
    en: {}
  }
})

// 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 machine API
const mockListMachines = vi.fn()
const mockAddMachine = vi.fn()
const mockUpdateMachine = vi.fn()
const mockDeleteMachine = vi.fn()

vi.mock('@/api/machine', () => ({
  listMachines: () => mockListMachines(),
  addMachine: (...args: any[]) => mockAddMachine(...args),
  updateMachine: (...args: any[]) => mockUpdateMachine(...args),
  deleteMachine: (...args: any[]) => mockDeleteMachine(...args)
}))

describe('Machine View', () => {
  beforeEach(() => {
    setActivePinia(createPinia())
    vi.clearAllMocks()
    mockListMachines.mockResolvedValue(wrapListResponse(mockMachines))
  })

  const mountMachine = () => {
    return mount(MachineView, {
      global: {
        plugins: [createPinia(), i18n],
        stubs: {
          'el-button': {
            template: '<button @click="$emit(\'click\')" :disabled="loading || disabled"><slot /></button>',
            props: ['type', 'icon', 'loading', 'plain', 'link', 'disabled']
          },
          'el-table': {
            template: '<table class="el-table" data-id="machine-table"><slot /></table>',
            props: ['data', 'loading', 'border', 'height'],
            methods: {
              clearSelection() {}
            }
          },
          'el-table-column': {
            template: '<td class="el-table-column"></td>',
            props: ['prop', 'label', 'width', 'align', 'type', 'fixed', 'minWidth', 'showOverflowTooltip', 'sortable']
          },
          'el-tag': { template: '<span class="el-tag"><slot /></span>', props: ['type'] },
          'el-link': {
            template: '<a class="el-link" @click="$emit(\'click\')"><slot /></a>',
            props: ['type']
          },
          'el-pagination': {
            template: '<div class="el-pagination"></div>',
            props: ['currentPage', 'pageSize', 'pageSizes', 'total', 'layout', 'background']
          },
          'el-dialog': {
            template:
              '<div v-if="modelValue" class="el-dialog" data-id="dialog-machine"><slot /><slot name="footer" /></div>',
            props: ['modelValue', 'title', 'width', 'destroyOnClose']
          },
          'el-form': {
            template: '<form class="el-form" data-id="form-machine"><slot /></form>',
            props: ['model', 'rules', 'labelWidth', 'inline'],
            methods: {
              validate(callback: Function) {
                callback(false)
                return Promise.resolve(false)
              },
              resetFields() {}
            }
          },
          'el-form-item': { template: '<div class="el-form-item"><slot /></div>', props: ['label', 'prop'] },
          'el-input': {
            template:
              '<input :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)" :disabled="disabled" :placeholder="placeholder" />',
            props: ['modelValue', 'placeholder', 'disabled', 'type', 'rows', 'clearable']
          },
          '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="text" :value="modelValue" @input="$emit(\'update:modelValue\', $event.target.value)" />',
            props: [
              'modelValue',
              'type',
              'rangeSeparator',
              'startPlaceholder',
              'endPlaceholder',
              'valueFormat',
              'clearable'
            ]
          },
          'el-switch': {
            template:
              '<input type="checkbox" :checked="modelValue" @change="$emit(\'update:modelValue\', $event.target.checked)" />',
            props: ['modelValue']
          },
          Plus: { template: '<span>Plus</span>' },
          Refresh: { template: '<span>Refresh</span>' },
          Search: { template: '<span>Search</span>' },
          Edit: { template: '<span>Edit</span>' },
          Delete: { template: '<span>Delete</span>' }
        }
      }
    })
  }

  describe('页面渲染', () => {
    it('应该正确渲染机器管理页面', async () => {
      const wrapper = mountMachine()
      await flushPromises()

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

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

      const addBtn = wrapper.findAll('button').find((btn) => btn.text().includes('新增'))
      expect(addBtn).toBeDefined()
    })

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

      const searchBtn = wrapper.findAll('button').find((btn) => btn.text().includes('查询'))
      expect(searchBtn).toBeDefined()
    })

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

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

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

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

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

      expect(mockListMachines).toHaveBeenCalled()
    })

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

      const searchBtn = wrapper.findAll('button').find((btn) => btn.text().includes('查询'))
      const resetBtn = wrapper.findAll('button').find((btn) => btn.text().includes('重置'))
      expect(searchBtn).toBeDefined()
      expect(resetBtn).toBeDefined()
    })
  })

  describe('新增', () => {
    it('点击新增按钮应该打开弹窗', async () => {
      const wrapper = mountMachine()
      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 () => {
      mockAddMachine.mockResolvedValue(wrapResponse({ id: 4, machineId: 'machine-004' }))

      const wrapper = mountMachine()
      await flushPromises()

      expect(mockListMachines).toHaveBeenCalled()
    })

    it('新增时应该显示正确的弹窗标题', async () => {
      const wrapper = mountMachine()
      await flushPromises()

      const addBtn = wrapper.findAll('button').find((btn) => btn.text().includes('新增'))
      if (addBtn) {
        await addBtn.trigger('click')
        await flushPromises()

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

  describe('编辑机器', () => {
    it('编辑机器成功应该重置', async () => {
      mockUpdateMachine.mockResolvedValue(wrapResponse(mockMachines[0]))

      const wrapper = mountMachine()
      await flushPromises()

      expect(mockListMachines).toHaveBeenCalled()
    })

    it('编辑时机器ID应该被禁用', async () => {
      const wrapper = mountMachine()
      await flushPromises()

      // 模拟点击编辑
      const editBtn = wrapper.findAll('button').find((btn) => btn.text().includes('编辑'))
      if (editBtn) {
        await editBtn.trigger('click')
        await flushPromises()

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

  describe('删除机器', () => {
    it('删除机器成功应该重置', async () => {
      const { ElMessage } = await import('element-plus')
      mockDeleteMachine.mockResolvedValue(wrapResponse(null))

      const wrapper = mountMachine()
      await flushPromises()

      const deleteBtn = wrapper.findAll('button').find((btn) => btn.text().includes('删除'))
      if (deleteBtn) {
        await deleteBtn.trigger('click')
        await flushPromises()

        expect(mockDeleteMachine).toHaveBeenCalled()
      }
    })

    it('删除确认取消时不应该调用删除 API', async () => {
      const { ElMessageBox } = await import('element-plus')
      ;(ElMessageBox.confirm as any).mockRejectedValue('cancel')

      const wrapper = mountMachine()
      await flushPromises()

      mockDeleteMachine.mockClear()

      const deleteBtn = wrapper.findAll('button').find((btn) => btn.text().includes('删除'))
      if (deleteBtn) {
        await deleteBtn.trigger('click')
        await flushPromises()
      }
    })
  })

  describe('分页功能', () => {
    it('应该正确计算总数', async () => {
      const wrapper = mountMachine()
      await flushPromises()

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

    it('切换每页条数应该重置页码为1', async () => {
      const wrapper = mountMachine()
      await flushPromises()

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

  describe('表单验证', () => {
    it('机器ID为空时不应该提交', async () => {
      const wrapper = mountMachine()
      await flushPromises()

      const addBtn = wrapper.findAll('button').find((btn) => btn.text().includes('新增'))
      if (addBtn) {
        await addBtn.trigger('click')
        await flushPromises()

        // 直接点击提交按钮
        const submitBtn = wrapper.findAll('button').find((btn) => btn.text().includes('确定'))
        if (submitBtn) {
          await submitBtn.trigger('click')
          await flushPromises()

          // 验证没有调用新增 API
          expect(mockAddMachine).not.toHaveBeenCalled()
        }
      }
    })
  })

  describe('弹窗交互', () => {
    it('点击取消按钮应该关闭弹窗', async () => {
      const wrapper = mountMachine()
      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)

        const cancelBtn = wrapper.findAll('button').find((btn) => btn.text().includes('取消'))
        if (cancelBtn) {
          await cancelBtn.trigger('click')
          await flushPromises()

          expect(wrapper.find('.el-dialog').exists()).toBe(false)
        }
      }
    })
  })

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

      const wrapper = mountMachine()
      await flushPromises()

      expect(mockListMachines).toHaveBeenCalled()
    })

    it('新增返回错误应该处理', async () => {
      mockAddMachine.mockResolvedValue(wrapResponse(null, false, '新增失败'))

      const wrapper = mountMachine()
      await flushPromises()

      expect(mockListMachines).toHaveBeenCalled()
    })
  })

  describe('启用状态', () => {
    it('编辑时应该显示启用状态开关', async () => {
      const wrapper = mountMachine()
      await flushPromises()

      const editBtn = wrapper.findAll('button').find((btn) => btn.text().includes('编辑'))
      if (editBtn) {
        await editBtn.trigger('click')
        await flushPromises()

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

    it('新增时不应该显示启用状态开关', async () => {
      const wrapper = mountMachine()
      await flushPromises()

      const addBtn = wrapper.findAll('button').find((btn) => btn.text().includes('新增'))
      if (addBtn) {
        await addBtn.trigger('click')
        await flushPromises()

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