import { test, expect } from '../fixtures/leai.fixture'
import { randomWorkId } from '../fixtures/leai.fixture'
import { fileURLToPath } from 'url'
import path from 'path'

/**
 * P2: 端到端完整流程测试
 */

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

const MOCK_H5_PATH = path.resolve(__dirname, '../utils/mock-h5.html')

test.describe('端到端：创作完整流程', () => {

  test('E2E-1: iframe 创作主流程', async ({ loggedInPage, sendWebhook }) => {
    // ── 步骤 1: 拦截 token API ──
    await loggedInPage.route('**/leai-auth/token', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          code: 200,
          data: {
            token: 'e2e_test_token',
            orgId: 'gdlib',
            h5Url: 'http://localhost:3001',
            phone: '13800001111',
          },
        }),
      })
    })
    await loggedInPage.route('http://192.168.1.72:3001/**', async (route) => {
      await route.fulfill({ status: 200, contentType: 'text/html', path: MOCK_H5_PATH })
    })

    // ── 步骤 2: 访问创作页 ──
    await loggedInPage.goto('/p/create')
    const iframe = loggedInPage.locator('iframe').first()
    await expect(iframe).toBeVisible({ timeout: 10_000 })

    // ── 步骤 3: 模拟 Webhook status=1 (PENDING) ──
    const workId = randomWorkId()
    const result1 = await sendWebhook({
      event: 'work.status_changed',
      data: { work_id: workId, status: 1, phone: '13800001111', title: 'E2E测试绘本' },
    })
    expect(result1.status).toBe(200)

    // ── 步骤 4: 模拟 Webhook status=2 (PROCESSING) ──
    const result2 = await sendWebhook({
      event: 'work.progress',
      data: { work_id: workId, status: 2, progress: 50, progressMessage: '正在绘制插画...' },
    })
    expect(result2.status).toBe(200)

    // ── 步骤 5: 模拟 Webhook status=3 (COMPLETED) ──
    const result3 = await sendWebhook({
      event: 'work.status_changed',
      data: {
        work_id: workId,
        status: 3,
        title: 'E2E测试绘本',
        pageList: [
          { imageUrl: 'https://cdn.example.com/e2e/page1.png', text: '第一页' },
          { imageUrl: 'https://cdn.example.com/e2e/page2.png', text: '第二页' },
        ],
      },
    })
    expect(result3.status).toBe(200)

    // ── 步骤 6: 模拟 Webhook status=5 (DUBBED) ──
    const result5 = await sendWebhook({
      event: 'work.status_changed',
      data: {
        work_id: workId,
        status: 5,
        title: 'E2E测试绘本',
        author: 'E2E测试作者',
        pageList: [
          { imageUrl: 'https://cdn.example.com/e2e/page1.png', text: '第一页', audioUrl: 'https://cdn.example.com/e2e/audio1.mp3' },
          { imageUrl: 'https://cdn.example.com/e2e/page2.png', text: '第二页', audioUrl: 'https://cdn.example.com/e2e/audio2.mp3' },
        ],
      },
    })
    expect(result5.status).toBe(200)

    // 全流程无报错即通过
  })

  test('E2E-2: Token 过期自动刷新', async ({ loggedInPage }) => {
    let tokenCallCount = 0
    let refreshCallCount = 0

    await loggedInPage.route('**/leai-auth/token', async (route) => {
      tokenCallCount++
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          code: 200,
          data: { token: 'initial_token', orgId: 'gdlib', h5Url: 'http://localhost:3001', phone: '13800001111' },
        }),
      })
    })

    await loggedInPage.route('**/leai-auth/refresh-token', async (route) => {
      refreshCallCount++
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          code: 200,
          data: { token: 'refreshed_token', orgId: 'gdlib', phone: '13800001111' },
        }),
      })
    })

    await loggedInPage.route('http://192.168.1.72:3001/**', async (route) => {
      await route.fulfill({ status: 200, contentType: 'text/html', path: MOCK_H5_PATH })
    })

    await loggedInPage.goto('/p/create')
    const iframe = loggedInPage.locator('iframe').first()
    await expect(iframe).toBeVisible({ timeout: 10_000 })
    expect(tokenCallCount).toBe(1)

    // 模拟 H5 发送 TOKEN_EXPIRED
    await loggedInPage.evaluate(() => {
      window.dispatchEvent(new MessageEvent('message', {
        data: { source: 'leai-creation', version: 1, type: 'TOKEN_EXPIRED', payload: { messageId: 'm1' } },
        origin: '*',
      }))
    })

    await loggedInPage.waitForTimeout(2000)
    expect(refreshCallCount).toBe(1)

    // iframe 应继续正常显示
    await expect(iframe).toBeVisible()
  })

  test('E2E-3: Webhook 幂等 + 状态不回退', async ({ sendWebhook }) => {
    const workId = randomWorkId()

    // 发送 status=1 (PENDING)
    const r1 = await sendWebhook({
      event: 'work.status_changed',
      data: { work_id: workId, status: 1, phone: '13800001111' },
    })
    expect(r1.status).toBe(200)

    // 发送 status=3 (COMPLETED)
    const r3 = await sendWebhook({
      event: 'work.status_changed',
      data: { work_id: workId, status: 3, title: '幂等测试' },
    })
    expect(r3.status).toBe(200)

    // 发送旧状态 status=2 (PROCESSING) — 应被忽略
    const r2 = await sendWebhook({
      event: 'work.status_changed',
      data: { work_id: workId, status: 2, progress: 80 },
    })
    expect(r2.status).toBe(200)
    // V4.0 规则：status=2 <= status=3，忽略

    // 发送 status=-1 (FAILED) — 强制覆盖
    const rf = await sendWebhook({
      event: 'work.status_changed',
      data: { work_id: workId, status: -1, failReason: '测试强制失败' },
    })
    expect(rf.status).toBe(200)
    // V4.0 规则：FAILED 强制更新
  })

  test('E2E-4: 创作失败 → 重试流程', async ({ loggedInPage, sendWebhook }) => {
    const failedWorkId = randomWorkId()

    // 模拟 Webhook 推送失败
    const r1 = await sendWebhook({
      event: 'work.status_changed',
      data: { work_id: failedWorkId, status: 1, phone: '13800001111' },
    })
    expect(r1.status).toBe(200)

    const rf = await sendWebhook({
      event: 'work.status_changed',
      data: { work_id: failedWorkId, status: -1, failReason: 'AI处理超时' },
    })
    expect(rf.status).toBe(200)

    // 用户回到创作页重新开始
    await loggedInPage.route('**/leai-auth/token', async (route) => {
      await route.fulfill({
        status: 200,
        contentType: 'application/json',
        body: JSON.stringify({
          code: 200,
          data: { token: 'retry_token', orgId: 'gdlib', h5Url: 'http://localhost:3001', phone: '13800001111' },
        }),
      })
    })
    await loggedInPage.route('http://192.168.1.72:3001/**', async (route) => {
      await route.fulfill({ status: 200, contentType: 'text/html', path: MOCK_H5_PATH })
    })

    await loggedInPage.goto('/p/create')
    const iframe = loggedInPage.locator('iframe').first()
    await expect(iframe).toBeVisible({ timeout: 10_000 })

    // 新一轮创作成功
    const newWorkId = randomWorkId()
    const r2 = await sendWebhook({
      event: 'work.status_changed',
      data: { work_id: newWorkId, status: 1, phone: '13800001111' },
    })
    expect(r2.status).toBe(200)

    const r3 = await sendWebhook({
      event: 'work.status_changed',
      data: { work_id: newWorkId, status: 3, title: '重试成功绘本' },
    })
    expect(r3.status).toBe(200)
  })
})
