import { test, expect } from '@playwright/test'
import * as fs from 'fs'
import * as path from 'path'
import * as jwt from 'jsonwebtoken'

const BASE = 'http://localhost:3006/api'

function getJwtSecret(): string {
  const envPath = path.resolve(__dirname, '..', '.env')
  const envContent = fs.readFileSync(envPath, 'utf8')
  const match = envContent.match(/^JWT_SECRET=(.+)$/m)
  return match ? match[1].trim() : 'test-jwt-secret-for-e2e-tests'
}

function signToken(payload: object): string {
  return jwt.sign(payload, getJwtSecret(), { expiresIn: '1h' })
}

const testUserId = '000000000000000000000001'
const testAdminId = '000000000000000000000002'
const userToken = signToken({ userId: testUserId, phone: '13800138000', role: 'user' })
const adminToken = signToken({ userId: testAdminId, phone: '13800138001', role: 'admin' })

test.describe('Backend API (Playwright)', () => {
  test('GET /api/user/info returns 401 without token', async ({ request }) => {
    const res = await request.get(`${BASE}/user/info`)
    expect(res.status()).toBe(401)
  })

  test('POST /api/user/send-code returns 200', async ({ request }) => {
    const res = await request.post(`${BASE}/user/send-code`, {
      data: { phone: '13800138000' },
    })
    expect(res.status()).toBe(200)
    const body = await res.json()
    expect(body.message).toBe('验证码已发送')
  })

  test('POST /api/payment/create returns 401 without auth', async ({ request }) => {
    const res = await request.post(`${BASE}/payment/create`, {
      data: { plan: 'growth' },
    })
    expect(res.status()).toBe(401)
  })

  test('POST /api/progress/checkin returns 401 without auth', async ({ request }) => {
    const res = await request.post(`${BASE}/progress/checkin`)
    expect(res.status()).toBe(401)
  })

  test('POST /api/contribution returns 401 without auth', async ({ request }) => {
    const res = await request.post(`${BASE}/contribution`, {
      data: { company: 'Test', position: '前端工程师' },
    })
    expect(res.status()).toBe(401)
  })

  test('GET /api/progress requires auth', async ({ request }) => {
    const res = await request.get(`${BASE}/progress`)
    expect(res.status()).toBe(401)
  })

  test('GET /api/admin/check requires auth', async ({ request }) => {
    const res = await request.get(`${BASE}/admin/check`)
    expect(res.status()).toBe(401)
  })

  // --- Feedback API ---

  test('POST /api/feedback returns 401 without token', async ({ request }) => {
    const res = await request.post(`${BASE}/feedback`, {
      data: { type: 'suggestion', content: 'test feedback' },
    })
    expect(res.status()).toBe(401)
  })

  test('POST /api/feedback returns 400 with empty content', async ({ request }) => {
    const res = await request.post(`${BASE}/feedback`, {
      data: { content: '' },
      headers: { Authorization: `Bearer ${userToken}` },
    })
    expect(res.status()).toBe(400)
  })

  test('POST /api/feedback returns 201 with valid data', async ({ request }) => {
    const res = await request.post(`${BASE}/feedback`, {
      data: { type: 'bug', content: 'Playwright浏览器端测试提交的问题反馈', contact: 'test@test.com' },
      headers: { Authorization: `Bearer ${userToken}` },
    })
    expect(res.status()).toBe(201)
  })

  test('GET /api/feedback returns 403 for non-admin', async ({ request }) => {
    const res = await request.get(`${BASE}/feedback`, {
      headers: { Authorization: `Bearer ${userToken}` },
    })
    expect(res.status()).toBe(403)
  })

  test('GET /api/feedback returns 200 for admin', async ({ request }) => {
    const res = await request.get(`${BASE}/feedback`, {
      headers: { Authorization: `Bearer ${adminToken}` },
    })
    expect(res.status()).toBe(200)
    const body = await res.json()
    expect(body.items).toBeDefined()
    expect(Array.isArray(body.items)).toBe(true)
    expect(body.total).toBeGreaterThanOrEqual(0)
  })
})
