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

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

// 日本相关测试数据
const TEST_DATA = {
  name: '東京テスト環境',
  address: '東京都渋谷区神宮前1-2-3',
  // 用于恢复的原始数据
  originalName: '初台測試環境',
  originalAddress: ''
}

test.describe('LSS管理 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('LSS管理页面正确显示', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 验证页面标题
    await expect(page.locator('text=LSS 管理')).toBeVisible()

    // 验证搜索表单元素
    await expect(page.getByPlaceholder('LSS ID')).toBeVisible()
    await expect(page.getByPlaceholder('名称')).toBeVisible()
    await expect(page.getByRole('button', { name: 'Search' })).toBeVisible()
    await expect(page.getByRole('button', { name: 'Reset' })).toBeVisible()

    // 验证表头
    await expect(page.locator('th:has-text("LSS ID")')).toBeVisible()
    await expect(page.locator('th:has-text("Name")')).toBeVisible()
    await expect(page.locator('th:has-text("Address")')).toBeVisible()
    await expect(page.locator('th:has-text("IP")')).toBeVisible()
    await expect(page.locator('th:has-text("Actions")')).toBeVisible()
  })

  test('编辑LSS节点 - 修改Name和Address', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 等待表格加载
    await page.waitForTimeout(1000)

    // 找到数据行中的编辑按钮（Actions列第一个按钮）
    const editButton = page.locator('tbody tr').first().locator('button').nth(1)
    await expect(editButton).toBeVisible({ timeout: 10000 })
    await editButton.click()

    // 验证编辑对话框打开
    const dialog = page.locator('.el-drawer, .el-dialog').filter({ hasText: 'LSS详情' })
    await expect(dialog).toBeVisible({ timeout: 5000 })

    // 修改 Name 字段
    const nameInput = dialog
      .locator('input')
      .filter({ hasText: /名称|Name/ })
      .or(dialog.locator('label:has-text("Name")').locator('..').locator('input'))
      .first()

    // 使用更通用的方式定位 Name 输入框
    const nameField = dialog.getByPlaceholder('请输入名称')
    await nameField.clear()
    await nameField.fill(TEST_DATA.name)

    // 修改 Address 字段
    const addressField = dialog.getByPlaceholder('请输入地址')
    await addressField.clear()
    await addressField.fill(TEST_DATA.address)

    // 点击 Update 按钮保存
    await dialog.getByRole('button', { name: 'Update' }).click()

    // 等待对话框关闭
    await expect(dialog).not.toBeVisible({ timeout: 10000 })

    // 验证列表中数据已更新
    await page.waitForTimeout(500)
    const firstRow = page.locator('tbody tr').first()
    await expect(firstRow).toContainText(TEST_DATA.name)
    await expect(firstRow).toContainText(TEST_DATA.address)
  })

  test('查询LSS节点', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 等待表格加载
    await page.waitForTimeout(1000)

    // 在名称搜索框输入关键词
    await page.getByPlaceholder('名称').fill('東京')

    // 点击搜索
    await page.getByRole('button', { name: 'Search' }).click()
    await page.waitForTimeout(500)

    // 验证搜索结果
    const tableRows = page.locator('tbody tr')
    const rowCount = await tableRows.count()

    if (rowCount > 0) {
      // 验证每行都包含搜索关键词
      for (let i = 0; i < rowCount; i++) {
        const row = tableRows.nth(i)
        const rowText = await row.textContent()
        expect(rowText).toContain('東京')
      }
    }
  })

  test('重置搜索条件', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 填入搜索条件
    await page.getByPlaceholder('LSS ID').fill('test-id')
    await page.getByPlaceholder('名称').fill('test-name')

    // 点击重置
    await page.getByRole('button', { name: 'Reset' }).click()
    await page.waitForTimeout(300)

    // 验证搜索条件已清空
    await expect(page.getByPlaceholder('LSS ID')).toHaveValue('')
    await expect(page.getByPlaceholder('名称')).toHaveValue('')
  })

  test('查看LSS节点设备列表', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 等待表格加载
    await page.waitForTimeout(1000)

    // 点击 Device List 列的按钮
    const deviceListButton = page.locator('tbody tr').first().locator('button').first()
    await expect(deviceListButton).toBeVisible({ timeout: 10000 })
    await deviceListButton.click()

    // 验证设备列表面板打开
    const devicePanel = page.locator('.el-drawer, .el-dialog').filter({ hasText: '设备列表' })
    await expect(devicePanel).toBeVisible({ timeout: 5000 })

    // 验证设备列表表头
    await expect(devicePanel.locator('th:has-text("设备ID")')).toBeVisible()
    await expect(devicePanel.locator('th:has-text("名称")')).toBeVisible()

    // 关闭面板
    await devicePanel.locator('button[aria-label*="Close"], .el-drawer__close-btn, .el-dialog__close').first().click()
    await expect(devicePanel).not.toBeVisible({ timeout: 5000 })
  })

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

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

    // 验证跳转到 LSS 管理页面
    await expect(page).toHaveURL(/\/lss/)
    await expect(page.locator('text=LSS 管理')).toBeVisible()
  })
})

test.describe('LSS管理 - CodeEditor 组件测试 (JSON模式)', () => {
  // 登录辅助函数
  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 })
  }

  /**
   * 测试 CodeEditor JSON 模式 - 头部显示
   */
  test('CodeEditor JSON模式 - 验证头部显示JSON标签和按钮', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 等待表格加载
    await page.waitForTimeout(1000)

    // 点击 Device List 按钮打开设备列表
    const deviceListButton = page.locator('tbody tr').first().locator('button').first()
    await expect(deviceListButton).toBeVisible({ timeout: 10000 })
    await deviceListButton.click()

    // 等待设备列表面板打开
    const devicePanel = page.locator('.el-drawer, .el-dialog').filter({ hasText: 'Camera List' })
    await expect(devicePanel).toBeVisible({ timeout: 5000 })

    // 点击 Parameter Configuration 的 View 按钮
    const viewButton = devicePanel.locator('tbody tr').first().locator('button:has-text("View")').first()
    await expect(viewButton).toBeVisible({ timeout: 5000 })
    await viewButton.click()

    // 等待参数配置抽屉打开
    const paramsDrawer = page.locator('.el-drawer').filter({ hasText: '参数配置' })
    await expect(paramsDrawer).toBeVisible({ timeout: 5000 })

    // 验证 CodeEditor 头部显示 JSON 标签
    const codeEditor = paramsDrawer.locator('.code-editor')
    await expect(codeEditor).toBeVisible()
    await expect(codeEditor.locator('.editor-header')).toBeVisible()
    await expect(codeEditor.locator('.file-type')).toContainText('JSON')

    // 验证 Copy 按钮存在
    await expect(codeEditor.locator('button:has-text("复制"), button:has-text("Copy")')).toBeVisible()

    // 验证 格式化 按钮存在 (JSON模式特有)
    await expect(codeEditor.locator('button:has-text("格式化")')).toBeVisible()
  })

  /**
   * 测试 CodeEditor JSON 模式 - 复制功能
   */
  test('CodeEditor JSON模式 - 复制按钮功能', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 等待表格加载
    await page.waitForTimeout(1000)

    // 点击 Device List 按钮
    const deviceListButton = page.locator('tbody tr').first().locator('button').first()
    await deviceListButton.click()

    // 等待设备列表面板打开
    const devicePanel = page.locator('.el-drawer, .el-dialog').filter({ hasText: 'Camera List' })
    await expect(devicePanel).toBeVisible({ timeout: 5000 })

    // 点击 Parameter Configuration 的 View 按钮
    const viewButton = devicePanel.locator('tbody tr').first().locator('button:has-text("View")').first()
    await viewButton.click()

    // 等待参数配置抽屉打开
    const paramsDrawer = page.locator('.el-drawer').filter({ hasText: '参数配置' })
    await expect(paramsDrawer).toBeVisible({ timeout: 5000 })

    // 点击复制按钮
    const copyButton = paramsDrawer.locator(
      '.code-editor button:has-text("复制"), .code-editor button:has-text("Copy")'
    )
    await copyButton.click()

    // 验证复制成功提示
    await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 3000 })
  })

  /**
   * 测试 CodeEditor JSON 模式 - 格式化功能
   */
  test('CodeEditor JSON模式 - 格式化按钮功能', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 等待表格加载
    await page.waitForTimeout(1000)

    // 点击 Device List 按钮
    const deviceListButton = page.locator('tbody tr').first().locator('button').first()
    await deviceListButton.click()

    // 等待设备列表面板打开
    const devicePanel = page.locator('.el-drawer, .el-dialog').filter({ hasText: 'Camera List' })
    await expect(devicePanel).toBeVisible({ timeout: 5000 })

    // 点击 Parameter Configuration 的 View 按钮
    const viewButton = devicePanel.locator('tbody tr').first().locator('button:has-text("View")').first()
    await viewButton.click()

    // 等待参数配置抽屉打开
    const paramsDrawer = page.locator('.el-drawer').filter({ hasText: '参数配置' })
    await expect(paramsDrawer).toBeVisible({ timeout: 5000 })

    // 验证格式化按钮可用（如果内容是有效JSON）
    const formatButton = paramsDrawer.locator('.code-editor button:has-text("格式化")')
    await expect(formatButton).toBeVisible()

    // 点击格式化按钮（如果按钮未禁用）
    const isDisabled = await formatButton.isDisabled()
    if (!isDisabled) {
      await formatButton.click()
      // 格式化后内容应该保持有效
      await page.waitForTimeout(300)
    }
  })

  /**
   * 测试 CodeEditor JSON 模式 - 无效JSON显示错误提示
   */
  test('CodeEditor JSON模式 - 无效JSON显示错误提示', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 等待表格加载
    await page.waitForTimeout(1000)

    // 点击 Device List 按钮
    const deviceListButton = page.locator('tbody tr').first().locator('button').first()
    await deviceListButton.click()

    // 等待设备列表面板打开
    const devicePanel = page.locator('.el-drawer, .el-dialog').filter({ hasText: 'Camera List' })
    await expect(devicePanel).toBeVisible({ timeout: 5000 })

    // 点击 Parameter Configuration 的 View 按钮
    const viewButton = devicePanel.locator('tbody tr').first().locator('button:has-text("View")').first()
    await viewButton.click()

    // 等待参数配置抽屉打开
    const paramsDrawer = page.locator('.el-drawer').filter({ hasText: '参数配置' })
    await expect(paramsDrawer).toBeVisible({ timeout: 5000 })

    // 获取编辑器并输入无效JSON
    const codeEditor = paramsDrawer.locator('.code-editor')
    const editorContent = codeEditor.locator('.cm-content')

    // 清空并输入无效JSON
    await editorContent.click()
    await page.keyboard.press('Meta+a')
    await page.keyboard.type('{ invalid json }')

    // 验证错误提示显示
    await expect(codeEditor.locator('.validation-error')).toBeVisible({ timeout: 3000 })
    await expect(codeEditor.locator('.validation-error')).toContainText('JSON 格式错误')

    // 验证格式化按钮被禁用
    const formatButton = codeEditor.locator('button:has-text("格式化")')
    await expect(formatButton).toBeDisabled()
  })

  /**
   * 测试 CodeEditor JSON 模式 - 更新内容并验证保存成功
   */
  test('CodeEditor JSON模式 - 更新参数配置并验证保存成功', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 等待表格加载
    await page.waitForTimeout(1000)

    // 点击 Device List 按钮
    const deviceListButton = page.locator('tbody tr').first().locator('button').first()
    await deviceListButton.click()

    // 等待设备列表面板打开
    const devicePanel = page.locator('.el-drawer, .el-dialog').filter({ hasText: 'Camera List' })
    await expect(devicePanel).toBeVisible({ timeout: 5000 })

    // 点击 Parameter Configuration 的 View 按钮
    const viewButton = devicePanel.locator('tbody tr').first().locator('button:has-text("View")').first()
    await viewButton.click()

    // 等待参数配置抽屉打开
    const paramsDrawer = page.locator('.el-drawer').filter({ hasText: '参数配置' })
    await expect(paramsDrawer).toBeVisible({ timeout: 5000 })

    // 获取当前编辑器内容
    const codeEditor = paramsDrawer.locator('.code-editor')
    const editorContent = codeEditor.locator('.cm-content')

    // 生成唯一标识用于验证更新
    const timestamp = Date.now()
    const testValue = `"testUpdate": "${timestamp}"`

    // 修改JSON内容 - 在现有JSON中添加测试字段
    await editorContent.click()
    await page.keyboard.press('Meta+a')
    // 输入新的有效JSON内容
    await page.keyboard.type(`{\n  ${testValue},\n  "ip": "192.168.0.64"\n}`)

    // 点击更新按钮
    const updateButton = paramsDrawer.locator('button:has-text("更新"), button:has-text("Update")')
    await updateButton.click()

    // 等待更新成功提示
    await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 })

    // 等待抽屉关闭
    await expect(paramsDrawer).not.toBeVisible({ timeout: 5000 })

    // 重新打开参数配置抽屉验证内容已保存
    await page.waitForTimeout(500)
    await viewButton.click()

    // 等待抽屉重新打开
    const paramsDrawerReopened = page.locator('.el-drawer').filter({ hasText: '参数配置' })
    await expect(paramsDrawerReopened).toBeVisible({ timeout: 5000 })

    // 验证内容包含我们添加的测试字段
    const editorContentReopened = paramsDrawerReopened.locator('.cm-content')
    await expect(editorContentReopened).toContainText(timestamp.toString())
  })

  /**
   * 测试 CodeEditor JSON 模式 - 运行参数更新并验证保存成功
   */
  test('CodeEditor JSON模式 - 更新运行参数并验证保存成功', async ({ page }) => {
    await login(page)
    await page.goto('/lss')

    // 等待表格加载
    await page.waitForTimeout(1000)

    // 点击 Device List 按钮
    const deviceListButton = page.locator('tbody tr').first().locator('button').first()
    await deviceListButton.click()

    // 等待设备列表面板打开
    const devicePanel = page.locator('.el-drawer, .el-dialog').filter({ hasText: 'Camera List' })
    await expect(devicePanel).toBeVisible({ timeout: 5000 })

    // 点击 Run Parameters 的 View 按钮（第二个 View 按钮）
    const viewButtons = devicePanel.locator('tbody tr').first().locator('button:has-text("View")')
    const runParamsViewButton = viewButtons.nth(1)
    await expect(runParamsViewButton).toBeVisible({ timeout: 5000 })
    await runParamsViewButton.click()

    // 等待运行参数抽屉打开
    const paramsDrawer = page.locator('.el-drawer').filter({ hasText: '运行参数' })
    await expect(paramsDrawer).toBeVisible({ timeout: 5000 })

    // 获取编辑器
    const codeEditor = paramsDrawer.locator('.code-editor')
    const editorContent = codeEditor.locator('.cm-content')

    // 生成唯一标识用于验证更新
    const timestamp = Date.now()
    const testValue = `"runtimeTest": "${timestamp}"`

    // 修改JSON内容
    await editorContent.click()
    await page.keyboard.press('Meta+a')
    await page.keyboard.type(`{\n  ${testValue}\n}`)

    // 点击更新按钮
    const updateButton = paramsDrawer.locator('button:has-text("更新"), button:has-text("Update")')
    await updateButton.click()

    // 等待更新成功提示
    await expect(page.locator('.el-message--success')).toBeVisible({ timeout: 5000 })

    // 等待抽屉关闭
    await expect(paramsDrawer).not.toBeVisible({ timeout: 5000 })

    // 重新打开运行参数抽屉验证内容已保存
    await page.waitForTimeout(500)
    await runParamsViewButton.click()

    // 等待抽屉重新打开
    const paramsDrawerReopened = page.locator('.el-drawer').filter({ hasText: '运行参数' })
    await expect(paramsDrawerReopened).toBeVisible({ timeout: 5000 })

    // 验证内容包含我们添加的测试字段
    const editorContentReopened = paramsDrawerReopened.locator('.cm-content')
    await expect(editorContentReopened).toContainText(timestamp.toString())
  })
})
