import { test, expect, type Page } from '@playwright/test'

// 测试账号配置
const TEST_USERNAME = process.env.TEST_USERNAME || 'admin'
const TEST_PASSWORD = process.env.TEST_PASSWORD || '123456'

// 生成唯一的测试机器ID
const generateMachineId = () => `TEST_${Date.now()}`

// data-id 选择器辅助函数
const byDataId = (id: string) => `[data-id="${id}"]`

test.describe('机器管理 CRUD 测试', () => {
  // 登录辅助函数
  async function login(page: Page) {
    await page.goto('/login')
    await page.evaluate(() => {
      localStorage.clear()
      document.cookie.split(';').forEach((c) => {
        document.cookie = c.replace(/^ +/, '').replace(/=.*/, '=;expires=' + new Date().toUTCString() + ';path=/')
      })
    })
    await page.reload()

    await page.getByPlaceholder('用户名').fill(TEST_USERNAME)
    await page.getByPlaceholder('密码').fill(TEST_PASSWORD)
    await page.getByRole('button', { name: '登录' }).click()
    await expect(page).not.toHaveURL(/\/login/, { timeout: 15000 })
  }

  test('机器管理页面正确显示', async ({ page }) => {
    await login(page)
    await page.goto('/machine')

    // 验证页面元素
    await expect(page.locator(byDataId('btn-add-machine'))).toBeVisible()
    await expect(page.locator(byDataId('btn-search'))).toBeVisible()
    await expect(page.locator(byDataId('btn-reset'))).toBeVisible()
    await expect(page.locator(byDataId('machine-table'))).toBeVisible()

    // 验证表头 - 使用 thead 来区分表单标签和表头
    await expect(page.locator('thead').getByText('机器ID')).toBeVisible()
    await expect(page.locator('thead').getByText('名称')).toBeVisible()
    await expect(page.locator('thead').getByText('位置')).toBeVisible()
  })

  test('查询和重置功能', async ({ page }) => {
    await login(page)
    await page.goto('/machine')

    // 等待表格加载
    await expect(page.locator(byDataId('machine-table'))).toBeVisible()

    // 点击查询按钮
    await page.locator(byDataId('btn-search')).click()
    await page.waitForTimeout(500)

    // 表格应该仍然可见
    await expect(page.locator(byDataId('machine-table'))).toBeVisible()

    // 点击重置按钮
    await page.locator(byDataId('btn-reset')).click()
    await page.waitForTimeout(500)

    // 表格应该仍然可见
    await expect(page.locator(byDataId('machine-table'))).toBeVisible()
  })

  test('新增机器完整流程', async ({ page }) => {
    await login(page)
    await page.goto('/machine')

    const machineId = generateMachineId()
    const machineName = `测试机器_${Date.now()}`

    // 点击新增按钮
    await page.locator(byDataId('btn-add-machine')).click()

    // 验证弹窗打开
    const dialog = page.locator(byDataId('dialog-machine'))
    await expect(dialog).toBeVisible()
    await expect(page.locator('.el-dialog__title')).toContainText('新增机器')

    // 填写表单 - 使用 dialog 作为容器来定位输入框
    await dialog.locator(byDataId('input-machine-id')).fill(machineId)
    await dialog.locator(byDataId('input-name')).fill(machineName)
    await dialog.locator(byDataId('input-location')).fill('测试位置')
    await dialog.locator(byDataId('input-description')).fill('E2E测试创建的机器')

    // 等待提交按钮可用后点击
    const submitBtn = page.locator(byDataId('btn-submit'))
    await expect(submitBtn).toBeEnabled()
    await submitBtn.click()

    // 等待成功消息或弹窗关闭（API成功或失败都会关闭弹窗）
    const successPromise = page
      .locator('.el-message--success')
      .waitFor({ timeout: 10000 })
      .catch(() => null)
    const dialogClosePromise = expect(dialog).not.toBeVisible({ timeout: 10000 })

    await Promise.race([successPromise, dialogClosePromise])

    // 如果弹窗关闭了，说明操作已完成
    await expect(dialog).not.toBeVisible({ timeout: 5000 })
  })

  test('编辑机器功能', async ({ page }) => {
    await login(page)
    await page.goto('/machine')

    // 等待表格加载
    await expect(page.locator(byDataId('machine-table'))).toBeVisible()
    await page.waitForTimeout(1000)

    // 点击第一行的名称链接
    const firstNameLink = page.locator('[data-id^="link-edit-"]').first()

    // 等待数据加载，确保有可编辑的数据
    await expect(firstNameLink).toBeVisible({ timeout: 10000 })

    await firstNameLink.click()

    // 验证弹窗打开
    const dialog = page.locator(byDataId('dialog-machine'))
    await expect(dialog).toBeVisible()
    await expect(page.locator('.el-dialog__title')).toContainText('编辑机器')

    // 修改名称 - 使用 data-id 定位输入框
    const nameInput = dialog.locator(byDataId('input-name'))
    await nameInput.clear()
    await nameInput.fill(`编辑测试_${Date.now()}`)

    // 等待提交按钮可用后点击
    const submitBtn = page.locator(byDataId('btn-submit'))
    await expect(submitBtn).toBeEnabled()
    await submitBtn.click()

    // 验证弹窗关闭
    await expect(dialog).not.toBeVisible({ timeout: 15000 })
  })

  test('删除机器功能', async ({ page }) => {
    await login(page)
    await page.goto('/machine')

    // 等待表格加载
    await expect(page.locator(byDataId('machine-table'))).toBeVisible()
    await page.waitForTimeout(1000)

    // 找到第一个删除按钮并点击
    const deleteBtn = page.locator('[data-id^="btn-delete-"]').first()

    // 确保有数据可以删除
    await expect(deleteBtn).toBeVisible({ timeout: 10000 })

    await deleteBtn.click()

    // 确认删除对话框出现
    await expect(page.locator('.el-message-box')).toBeVisible()
    await page.locator('.el-message-box').getByRole('button', { name: '确定' }).click()

    // 等待确认对话框关闭（删除操作已执行）
    await expect(page.locator('.el-message-box')).not.toBeVisible({ timeout: 10000 })

    // 验证表格仍然可见（删除后页面正常）
    await expect(page.locator(byDataId('machine-table'))).toBeVisible()
  })

  test('新增机器表单验证', async ({ page }) => {
    await login(page)
    await page.goto('/machine')

    // 点击新增按钮
    await page.locator(byDataId('btn-add-machine')).click()
    await expect(page.locator(byDataId('dialog-machine'))).toBeVisible()

    // 直接点击确定，不填写任何内容
    await page.locator(byDataId('btn-submit')).click()

    // 验证显示验证错误 - 使用 dialog 容器来定位错误消息
    const dialog = page.locator(byDataId('dialog-machine'))
    await expect(dialog.getByText('请输入机器ID')).toBeVisible()
    await expect(dialog.getByText('请输入名称')).toBeVisible()
  })

  test('取消新增机器', async ({ page }) => {
    await login(page)
    await page.goto('/machine')

    // 点击新增按钮
    await page.locator(byDataId('btn-add-machine')).click()
    const dialog = page.locator(byDataId('dialog-machine'))
    await expect(dialog).toBeVisible()

    // 填写部分内容
    await dialog.locator(byDataId('input-machine-id')).fill('TEST_CANCEL')

    // 点击取消
    await page.locator(byDataId('btn-cancel')).click()

    // 验证弹窗关闭
    await expect(dialog).not.toBeVisible()
  })

  test('从侧边栏导航到机器管理', async ({ page }) => {
    await login(page)

    // 点击侧边栏机器管理菜单项
    await page.getByText('机器管理').first().click()

    // 验证跳转到机器管理页面
    await expect(page).toHaveURL(/\/machine/)
    await expect(page.locator(byDataId('btn-add-machine'))).toBeVisible()
  })
})
