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

/**
 * 公众端注册流程测试
 * 验证手机号必填功能
 */

/** 公众端登录/注册页面路径 */
const REGISTER_PATH = '/p/login'

/** Mock 注册 API 的响应 */
async function setupRegisterApiMocks(page: import('@playwright/test').Page) {
  // 拦截注册 API
  await page.route('**/api/public/auth/register', async (route) => {
    const request = route.request()
    const postData = request.postDataJSON()

    // 模拟后端校验逻辑
    if (!postData?.phone) {
      await route.fulfill({
        status: 400,
        contentType: 'application/json',
        body: JSON.stringify({ code: 400, message: '手机号不能为空' }),
      })
      return
    }

    if (!/^1[3-9]\d{9}$/.test(postData.phone)) {
      await route.fulfill({
        status: 400,
        contentType: 'application/json',
        body: JSON.stringify({ code: 400, message: '手机号格式不正确' }),
      })
      return
    }

    if (postData.phone === '13800000000') {
      await route.fulfill({
        status: 400,
        contentType: 'application/json',
        body: JSON.stringify({ code: 400, message: '该手机号已注册' }),
      })
      return
    }

    // 注册成功
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        code: 200,
        message: 'success',
        data: {
          token: 'mock-jwt-token-for-test',
          user: {
            id: 999,
            username: postData.username,
            nickname: postData.nickname,
            phone: postData.phone,
            avatar: null,
            city: null,
            gender: null,
            userType: 'adult',
            roles: ['public_user'],
            permissions: [],
          },
        },
      }),
    })
  })

  // 拦截登录 API（切换到登录模式时需要）
  await page.route('**/api/public/auth/login', async (route) => {
    await route.fulfill({
      status: 200,
      contentType: 'application/json',
      body: JSON.stringify({
        code: 200,
        message: 'success',
        data: {
          token: 'mock-jwt-token-for-test',
          user: {
            id: 1,
            username: 'demo',
            nickname: '测试用户',
            phone: '13800138000',
            avatar: null,
            city: null,
            gender: null,
            userType: 'adult',
            roles: ['public_user'],
            permissions: [],
          },
        },
      }),
    })
  })
}

test.describe('公众端注册 - 手机号必填', () => {
  test.beforeEach(async ({ page }) => {
    await setupRegisterApiMocks(page)
    await page.goto(REGISTER_PATH)
    // 点击"立即注册"切换到注册模式
    await page.locator('text=立即注册').click()
    // 等待注册表单渲染
    await expect(page.locator('text=创建账号')).toBeVisible()
  })

  test('PR-01 注册表单包含手机号输入框', async ({ page }) => {
    // 验证手机号标签可见
    await expect(page.locator('label:has-text("手机号")')).toBeVisible()
    // 验证手机号输入框可见
    await expect(page.locator('input[placeholder="请输入手机号"]')).toBeVisible()
  })

  test('PR-02 手机号输入框限制最大长度11位', async ({ page }) => {
    const phoneInput = page.locator('input[placeholder="请输入手机号"]')
    await expect(phoneInput).toHaveAttribute('maxlength', '11')
  })

  test('PR-03 登录模式不显示手机号输入框', async ({ page }) => {
    // 点击"去登录"切换回登录模式
    await page.locator('text=去登录').click()
    await expect(page.locator('text=登录')).toBeVisible()

    // 验证手机号输入框不存在
    await expect(page.locator('input[placeholder="请输入手机号"]')).not.toBeVisible()
  })

  test('PR-04 手机号为空时显示必填校验错误', async ({ page }) => {
    // 清空手机号（开发环境可能预填了值）
    const phoneInput = page.locator('input[placeholder="请输入手机号"]')
    await phoneInput.clear()
    // 触发 blur 校验
    await phoneInput.blur()

    // 验证校验错误信息
    await expect(page.locator('.ant-form-item-explain-error')).toContainText('请输入手机号')
  })

  test('PR-05 手机号格式不正确时显示校验错误', async ({ page }) => {
    const phoneInput = page.locator('input[placeholder="请输入手机号"]')
    await phoneInput.fill('12345678901')
    await phoneInput.blur()

    // 验证格式校验错误
    await expect(page.locator('.ant-form-item-explain-error')).toContainText('手机号格式不正确')
  })

  test('PR-06 输入正确的手机号格式不显示错误', async ({ page }) => {
    const phoneInput = page.locator('input[placeholder="请输入手机号"]')
    await phoneInput.fill('13912345678')
    await phoneInput.blur()

    // 验证无校验错误
    await expect(page.locator('.ant-form-item-explain-error')).not.toBeVisible()
  })

  test('PR-07 不传手机号后端返回校验错误', async ({ page }) => {
    // 修改 route 来模拟不传手机号
    let capturedBody: any = null
    await page.route('**/api/public/auth/register', async (route) => {
      capturedBody = route.request().postDataJSON()
      // 模拟后端 @NotBlank 校验
      await route.fulfill({
        status: 400,
        contentType: 'application/json',
        body: JSON.stringify({ code: 400, message: '手机号不能为空' }),
      })
    })

    // 清空手机号并提交（绕过前端校验直接测试 API）
    const phoneInput = page.locator('input[placeholder="请输入手机号"]')
    await phoneInput.clear()

    // 填写其他必填项
    await page.locator('input[placeholder="给自己取个名字吧"]').fill('测试昵称')
    await page.locator('input[placeholder="请输入用户名"]').fill('testuser' + Date.now())
    await page.locator('input[type="password"]').first().fill('test123456')
    await page.locator('input[placeholder="再次输入密码"]').fill('test123456')

    // 点击注册按钮
    await page.locator('button:has-text("注册并登录")').click()

    // 验证 Ant Design 前端表单校验拦截了提交（手机号必填）
    await expect(page.locator('.ant-form-item-explain-error')).toContainText('请输入手机号')
  })

  test('PR-08 注册时传递手机号参数到后端', async ({ page }) => {
    let capturedBody: any = null

    // 重新注册路由来捕获请求体（覆盖 beforeEach 的 setupRegisterApiMocks）
    await page.unroute('**/api/public/auth/register')
    await page.route('**/api/public/auth/register', async (route) => {
      capturedBody = route.request().postDataJSON()
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          code: 200,
          message: 'success',
          data: {
            token: 'mock-token',
            user: { id: 999, username: 'test', nickname: '测试', phone: '13900001111', avatar: null, city: null, gender: null, userType: 'adult', roles: ['public_user'], permissions: [] },
          },
        }),
      })
    })

    // 填写完整注册表单
    await page.locator('input[placeholder="给自己取个名字吧"]').fill('测试昵称')
    await page.locator('input[placeholder="请输入手机号"]').fill('13900001111')
    const uniqueUsername = 'testuser' + Date.now()
    await page.locator('input[placeholder="请输入用户名"]').fill(uniqueUsername)
    await page.locator('input[type="password"]').first().fill('test123456')
    await page.locator('input[placeholder="再次输入密码"]').fill('test123456')

    // 点击注册
    await page.locator('button:has-text("注册并登录")').click()

    // 等待成功提示（说明 API 已被调用）
    await expect(page.locator('.ant-message')).toContainText('注册成功', { timeout: 5000 })

    // 验证请求体包含 phone 字段
    expect(capturedBody).toBeTruthy()
    expect(capturedBody.phone).toBe('13900001111')
  })

  test('PR-09 已注册手机号后端返回错误提示', async ({ page }) => {
    // 使用预定义的"已注册"手机号
    await page.locator('input[placeholder="给自己取个名字吧"]').fill('测试昵称')
    await page.locator('input[placeholder="请输入手机号"]').fill('13800000000')
    await page.locator('input[placeholder="请输入用户名"]').fill('testuser' + Date.now())
    await page.locator('input[type="password"]').first().fill('test123456')
    await page.locator('input[placeholder="再次输入密码"]').fill('test123456')

    // 点击注册
    await page.locator('button:has-text("注册并登录")').click()

    // 验证错误提示（由 mock 返回"该手机号已注册"）
    await expect(page.locator('.ant-message')).toContainText('该手机号已注册', { timeout: 5000 })
  })

  test('PR-10 完整注册流程成功', async ({ page }) => {
    const testSuffix = Date.now()

    // 填写完整注册表单
    await page.locator('input[placeholder="给自己取个名字吧"]').fill('测试昵称')
    await page.locator('input[placeholder="请输入手机号"]').fill('139' + String(testSuffix).slice(-8))
    await page.locator('input[placeholder="请输入用户名"]').fill('e2e' + testSuffix)
    await page.locator('input[type="password"]').first().fill('test123456')
    await page.locator('input[placeholder="再次输入密码"]').fill('test123456')

    // 点击注册
    await page.locator('button:has-text("注册并登录")').click()

    // 验证成功提示
    await expect(page.locator('.ant-message')).toContainText('注册成功', { timeout: 5000 })

    // 验证跳转离开登录页
    await page.waitForURL((url) => !url.pathname.includes('/login'), { timeout: 10_000 })

    // 验证跳转到了活动列表页（/p/activities）
    await expect(page).toHaveURL(/\/p\/activities/)
  })
})
