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

/**
 * UGC 作品状态字段拆分验证测试
 *
 * 所有 API 请求直接发到后端 localhost:8580，绕过前端代理。
 */

// ── 配置 ──
const API_BASE = process.env.API_BASE_URL || 'http://localhost:8580/api'
const AUTH = {
  username: process.env.TEST_USERNAME || 'demo',
  password: process.env.TEST_PASSWORD || 'demo123456',
  tenantCode: process.env.TEST_TENANT_CODE || 'gdlib',
}

const VALID_STATUSES = ['draft', 'unpublished', 'pending_review', 'published', 'rejected']

// ── Helper ──
function url(path: string) {
  return `${API_BASE}${path}`
}

// ── Fixture ──
type Fixtures = { api: APIRequestContext }

const apiTest = test.extend<Fixtures>({
  api: async ({}, use) => {
    // 用 requestFactory（顶层 import）创建独立上下文来登录
    const loginCtx = await requestFactory.newContext({})
    const loginResp = await loginCtx.post(url('/public/auth/login'), {
      data: { username: AUTH.username, password: AUTH.password, tenantCode: AUTH.tenantCode },
    })
    const loginJson = await loginResp.json()
    await loginCtx.dispose()

    if (loginJson.code !== 200 || !loginJson.data?.token) {
      throw new Error(`登录失败: ${JSON.stringify(loginJson)}`)
    }
    const token = loginJson.data.token

    // 创建带 auth header 的 API 上下文
    const api = await requestFactory.newContext({
      extraHTTPHeaders: { Authorization: `Bearer ${token}` },
    })
    await use(api)
    await api.dispose()
  },
})

// ══════════════════════════════════════════════════════
// 1. 我的作品列表 — status 是字符串枚举
// ══════════════════════════════════════════════════════

apiTest('S-01 我的作品列表 — status 字段为字符串', async ({ api }) => {
  const resp = await api.get(url('/public/works?page=1&pageSize=5'))
  const json = await resp.json()

  expect(json.code).toBe(200)
  expect(json.data.list).toBeInstanceOf(Array)

  for (const work of json.data.list) {
    expect(
      VALID_STATUSES.includes(work.status),
      `作品 id=${work.id} 的 status="${work.status}" 不是合法字符串枚举值`,
    ).toBe(true)
  }

  console.log(`✓ S-01: 返回 ${json.data.list.length} 条作品，status 全部为字符串`)
})

apiTest('S-02 我的作品列表 — 按 status=draft 筛选', async ({ api }) => {
  const resp = await api.get(url('/public/works?page=1&pageSize=50&status=draft'))
  const json = await resp.json()

  expect(json.code).toBe(200)
  for (const work of json.data.list) {
    expect(work.status).toBe('draft')
  }
  console.log(`✓ S-02: draft 筛选返回 ${json.data.list.length} 条`)
})

apiTest('S-03 我的作品列表 — 按 status=unpublished 筛选', async ({ api }) => {
  const resp = await api.get(url('/public/works?page=1&pageSize=50&status=unpublished'))
  const json = await resp.json()

  expect(json.code).toBe(200)
  for (const work of json.data.list) {
    expect(work.status).toBe('unpublished')
  }
  console.log(`✓ S-03: unpublished 筛选返回 ${json.data.list.length} 条`)
})

apiTest('S-04 我的作品列表 — 按 status=published 筛选', async ({ api }) => {
  const resp = await api.get(url('/public/works?page=1&pageSize=50&status=published'))
  const json = await resp.json()

  expect(json.code).toBe(200)
  for (const work of json.data.list) {
    expect(work.status).toBe('published')
  }
  console.log(`✓ S-04: published 筛选返回 ${json.data.list.length} 条`)
})

apiTest('S-05 我的作品列表 — 按 status=pending_review 筛选', async ({ api }) => {
  const resp = await api.get(url('/public/works?page=1&pageSize=50&status=pending_review'))
  const json = await resp.json()

  expect(json.code).toBe(200)
  for (const work of json.data.list) {
    expect(work.status).toBe('pending_review')
  }
  console.log(`✓ S-05: pending_review 筛选返回 ${json.data.list.length} 条`)
})

apiTest('S-06 我的作品列表 — 按 status=rejected 筛选', async ({ api }) => {
  const resp = await api.get(url('/public/works?page=1&pageSize=50&status=rejected'))
  const json = await resp.json()

  expect(json.code).toBe(200)
  for (const work of json.data.list) {
    expect(work.status).toBe('rejected')
  }
  console.log(`✓ S-06: rejected 筛选返回 ${json.data.list.length} 条`)
})

// ══════════════════════════════════════════════════════
// 2. 创建作品 — 初始 status 为 draft
// ══════════════════════════════════════════════════════

apiTest('S-07 创建作品 — 初始 status 为 draft', async ({ api }) => {
  const resp = await api.post(url('/public/works'), {
    data: {
      title: `[E2E] 状态验证_${Date.now()}`,
      description: 'Playwright 自动创建',
      visibility: 'private',
    },
  })
  const json = await resp.json()

  expect(json.code).toBe(200)
  expect(json.data.status).toBe('draft')
  expect(typeof json.data.status).toBe('string')
  console.log(`✓ S-07: 创建作品 id=${json.data.id}, status="${json.data.status}"`)

  // 清理
  if (json.data.id) {
    await api.delete(url(`/public/works/${json.data.id}`))
  }
})

// ══════════════════════════════════════════════════════
// 3. draft 不可发布
// ══════════════════════════════════════════════════════

apiTest('S-08 发布作品 — draft 状态不可发布', async ({ api }) => {
  const createResp = await api.post(url('/public/works'), {
    data: { title: `[E2E] 发布测试_${Date.now()}`, visibility: 'private' },
  })
  const createJson = await createResp.json()
  expect(createJson.code).toBe(200)
  const workId = createJson.data.id

  const publishResp = await api.post(url(`/public/works/${workId}/publish`))
  const publishJson = await publishResp.json()
  expect(publishJson.code).toBe(400)
  console.log(`✓ S-08: draft 发布被拒绝，code=${publishJson.code}, msg="${publishJson.message}"`)

  await api.delete(url(`/public/works/${workId}`))
})

// ══════════════════════════════════════════════════════
// 4. 创作历史
// ══════════════════════════════════════════════════════

apiTest('S-09 创作历史 — 作品 status 为字符串', async ({ api }) => {
  const resp = await api.get(url('/public/creation/history?page=1&pageSize=5'))
  const json = await resp.json()

  expect(json.code).toBe(200)
  if (json.data?.list?.length > 0) {
    for (const work of json.data.list) {
      expect(
        VALID_STATUSES.includes(work.status),
        `创作历史 id=${work.id} status="${work.status}" 不合法`,
      ).toBe(true)
    }
  }
  console.log(`✓ S-09: 创作历史 ${json.data?.list?.length ?? 0} 条`)
})

// ══════════════════════════════════════════════════════
// 5. 作品详情
// ══════════════════════════════════════════════════════

apiTest('S-10 作品详情 — status + leaiStatus 字段', async ({ api }) => {
  const listResp = await api.get(url('/public/works?page=1&pageSize=1'))
  const listJson = await listResp.json()

  if (listJson.data?.list?.length > 0) {
    const workId = listJson.data.list[0].id
    const detailResp = await api.get(url(`/public/works/${workId}`))
    const detailJson = await detailResp.json()

    expect(detailJson.code).toBe(200)
    const work = detailJson.data.work

    // status 必须是合法字符串
    expect(VALID_STATUSES.includes(work.status)).toBe(true)

    // leaiStatus 应为数字
    if (work.leaiStatus != null) {
      expect(typeof work.leaiStatus).toBe('number')
    }
    console.log(`✓ S-10: 作品详情 status="${work.status}", leaiStatus=${work.leaiStatus}`)
  } else {
    console.log('⚠ S-10: 没有作品可测试详情')
  }
})

// ══════════════════════════════════════════════════════
// 6. 作品广场
// ══════════════════════════════════════════════════════

apiTest('S-11 作品广场 — 只返回已发布作品', async ({ api }) => {
  const resp = await api.get(url('/public/gallery?page=1&pageSize=10'))
  const json = await resp.json()

  expect(json.code).toBe(200)
  if (json.data?.list?.length > 0) {
    for (const work of json.data.list) {
      expect(work.status).toBe('published')
    }
  }
  console.log(`✓ S-11: 广场 ${json.data?.list?.length ?? 0} 条已发布作品`)
})

// ══════════════════════════════════════════════════════
// 7. 收藏列表
// ══════════════════════════════════════════════════════

apiTest('S-12 我的收藏 — status 为字符串', async ({ api }) => {
  const resp = await api.get(url('/public/mine/favorites?page=1&pageSize=5'))
  const json = await resp.json()

  expect(json.code).toBe(200)
  if (json.data?.list?.length > 0) {
    for (const item of json.data.list) {
      if (item.status) {
        expect(VALID_STATUSES.includes(item.status)).toBe(true)
      }
    }
  }
  console.log(`✓ S-12: 收藏 ${json.data?.list?.length ?? 0} 条`)
})
