import { test as base, expect, request as requestFactory, type Page, type APIRequestContext } from '@playwright/test'

/**
 * 认证 Fixture
 * 提供已登录的浏览器上下文和 JWT Token
 */

/** 测试账户（通过环境变量覆盖） */
export const AUTH_CONFIG = {
  username: process.env.TEST_USERNAME || 'demo',
  password: process.env.TEST_PASSWORD || 'demo123456',
  tenantCode: process.env.TEST_TENANT_CODE || 'gdlib',
  /** 后端 API 地址 */
  apiBase: process.env.API_BASE_URL || 'http://localhost:8580/api',
  /** 登录接口路径 */
  loginPath: '/public/auth/login',
}

/** 登录页路径 */
export function loginPath() {
  return '/p/login'
}

/** 创作页路径 */
export function createPath() {
  return '/p/create'
}

/** 作品列表路径 */
export function worksPath() {
  return '/p/works'
}

/**
 * 通过 API 直接获取 JWT Token（绕过 UI 登录）
 */
export async function fetchJwtToken(request: APIRequestContext): Promise<string> {
  const resp = await request.post(`${AUTH_CONFIG.apiBase}${AUTH_CONFIG.loginPath}`, {
    data: {
      username: AUTH_CONFIG.username,
      password: AUTH_CONFIG.password,
      tenantCode: AUTH_CONFIG.tenantCode,
    },
  })
  const json = await resp.json()
  if (json.code !== 200 || !json.data?.token) {
    throw new Error(`登录API失败: ${JSON.stringify(json)}`)
  }
  return json.data.token as string
}

/**
 * 在浏览器页面中执行 UI 登录
 */
export async function doLogin(page: Page): Promise<Page> {
  await page.goto(loginPath())

  // 等待登录表单渲染
  await page.waitForSelector('input[type="password"]', { timeout: 10_000 })

  // 填写用户名（尝试多种选择器兼容不同 UI）
  const usernameSelectors = [
    'input[placeholder*="用户名"]',
    'input[placeholder*="账号"]',
    'input#username',
    'input[name="username"]',
    'input:not([type="password"]):not([type="hidden"])',
  ]
  for (const sel of usernameSelectors) {
    const input = page.locator(sel).first()
    if (await input.count() > 0 && await input.isVisible()) {
      await input.fill(AUTH_CONFIG.username)
      break
    }
  }

  // 填写密码
  await page.locator('input[type="password"]').first().fill(AUTH_CONFIG.password)

  // 点击登录按钮
  const loginBtn = page.locator('button[type="submit"], button:has-text("登录"), button:has-text("登 录")').first()
  await loginBtn.click()

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

  return page
}

/**
 * 扩展 Playwright test fixture
 */
type AuthFixtures = {
  /** 已登录的页面（浏览器模式） */
  loggedInPage: Page
  /** JWT token 字符串 */
  authToken: string
  /** 带 token 的 API 请求上下文 */
  authedApi: APIRequestContext
}

export const test = base.extend<AuthFixtures>({
  loggedInPage: async ({ page }, use) => {
    await doLogin(page)
    await use(page)
  },

  authToken: async ({ request }, use) => {
    const token = await fetchJwtToken(request)
    await use(token)
  },

  authedApi: async ({ request }, use) => {
    const token = await fetchJwtToken(request)
    const context = await requestFactory.newContext({
      baseURL: AUTH_CONFIG.apiBase,
      extraHTTPHeaders: { Authorization: `Bearer ${token}` },
    })
    await use(context)
  },
})

export { expect }
