import { NextRequest, NextResponse } from 'next/server'
import { cookies } from 'next/headers'
import { h5PageRepo } from '@/lib/database/repositories/h5-page.repo'
import { parseAppSecrets, type AppSecrets } from '@/lib/h5/app-secrets'
import { verifyJwt, JwtVerifyError, type JwtPayload } from '@/lib/h5/jwt'
import { externalUserService } from '@/lib/external/external-user-service'
import {
  signH5Cookie,
  h5CookieName,
  h5CookieTtl,
  h5CookieSerializeOptions,
  getH5CookieSecret,
} from '@/lib/h5/cookie'

export const runtime = 'nodejs'
export const dynamic = 'force-dynamic'

/**
 * POST /api/h5/auth/[slug] — JS bridge 传递 JWT。
 *
 * APP WebView 加载完成后通过 postMessage 把 JWT 传给 H5 前端，
 * 前端 POST 到此路由换取 cookie，URL 不留 token。
 */
export async function POST(
  req: NextRequest,
  { params }: { params: Promise<{ slug: string }> },
): Promise<NextResponse> {
  const { slug } = await params
  const page = h5PageRepo.findBySlug(slug)

  if (!page || !page.enabled) {
    return NextResponse.json({ error: 'Not Found' }, { status: 404 })
  }

  let body: { token?: string }
  try {
    body = await req.json()
  } catch {
    return NextResponse.json({ error: 'Invalid JSON' }, { status: 400 })
  }

  if (!body.token) {
    return NextResponse.json({ error: 'Missing token' }, { status: 400 })
  }

  const appSecrets: AppSecrets = parseAppSecrets(page.appSecrets)

  let payload: JwtPayload
  try {
    payload = verifyJwt(body.token, appSecrets)
  } catch (err) {
    if (err instanceof JwtVerifyError) {
      const status = err.code === 'unknown_iss' || err.code === 'expired' ? 401 : 400
      return NextResponse.json({ error: err.message, code: err.code }, { status })
    }
    return NextResponse.json({ error: 'JWT verification failed' }, { status: 400 })
  }

  const ownerUserId = h5PageRepo.resolveOwnerUserIdByWorkspace(page.workspaceId)
  if (!ownerUserId) {
    return NextResponse.json({ error: 'No owner found for workspace' }, { status: 500 })
  }

  const externalUserId = externalUserService.resolveOrCreate({
    channelType: 'h5',
    channelId: page.id,
    platformUserId: payload.sub,
    platformName: payload.name,
    ownerUserId,
  })

  const secret = getH5CookieSecret()
  const cookieValue = signH5Cookie(
    {
      pageId: page.id,
      appId: payload.iss,
      externalUserId,
      exp: Math.floor(Date.now() / 1000) + h5CookieTtl(),
      name: payload.name ?? '',
    },
    secret,
  )

  const cookieStore = await cookies()
  cookieStore.set(h5CookieName(), cookieValue, h5CookieSerializeOptions())

  return NextResponse.json({
    ok: true,
    appId: payload.iss,
    externalUserId,
    name: payload.name ?? null,
  })
}
