import { NextRequest, NextResponse } from 'next/server'
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'

/**
 * H5 入口路由。
 *
 * GET /h5/[slug]?token=<JWT>
 *   1. 查 h5_pages WHERE slug=? AND enabled=1（不存在 → 404）
 *   2. 验签 JWT → 通过 ExternalUserService 解析/创建外部用户身份
 *   3. 签发 forge_h5 cookie（2h，存 externalUserId UUID）
 *   4. 302 → /h5/c?slug=xxx（干净 URL，无 token）
 *
 * GET /h5/[slug]（无 token）
 *   302 → /h5/c?slug=xxx（cookie 已存在则前端进入对话；失效则渲染过期态）
 */

/**
 * 构造跳转用的 origin。
 *
 * 反向代理（Nginx）后面 req.nextUrl.origin 可能拿到内网绑定地址（如 0.0.0.0:33000），
 * 导致 302 跳转到浏览器无法访问的地址。优先取 FORGE_PUBLIC_URL；
 * 没配则从 X-Forwarded-* 头推导。
 */
function resolveRedirectOrigin(req: NextRequest): string {
  const publicUrl = process.env.FORGE_PUBLIC_URL
  if (publicUrl) return publicUrl.replace(/\/$/, '')
  const proto = req.headers.get('x-forwarded-proto') || req.nextUrl.protocol.replace(':', '')
  const host = req.headers.get('x-forwarded-host') || req.headers.get('host') || req.nextUrl.host
  return `${proto}://${host}`
}

export async function GET(
  req: NextRequest,
  { params }: { params: Promise<{ slug: string }> },
): Promise<NextResponse> {
  const { slug } = await params
  const page = h5PageRepo.findBySlug(slug)

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

  const token = req.nextUrl.searchParams.get('token')

  const origin = resolveRedirectOrigin(req)

  if (!token) {
    return NextResponse.redirect(new URL(`/h5/c?slug=${encodeURIComponent(slug)}`, origin), 302)
  }

  const result = consumeJwt(token, page.appSecrets, page.id, page.workspaceId)
  if ('error' in result) {
    return new NextResponse(result.error, { status: result.errorStatus })
  }

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

  const redirectUrl = new URL(`/h5/c?slug=${encodeURIComponent(slug)}`, origin)
  const response = NextResponse.redirect(redirectUrl, 302)
  response.cookies.set(h5CookieName(), cookieValue, h5CookieSerializeOptions())

  if (payload.name) {
    response.headers.set('X-H5-User-Name', encodeURIComponent(payload.name))
  }

  return response
}

/** 验签 JWT 并通过 ExternalUserService 解析/创建外部用户身份 */
function consumeJwt(
  token: string,
  appSecretsJson: string,
  pageId: string,
  workspaceId: string,
):
  | { externalUserId: string; payload: JwtPayload }
  | { error: string; errorStatus: number } {
  const appSecrets: AppSecrets = parseAppSecrets(appSecretsJson)

  try {
    const payload = verifyJwt(token, appSecrets)

    // 解析 owner（workspace 的 owner_user_id）
    const ownerUserId = h5PageRepo.resolveOwnerUserIdByWorkspace(workspaceId)
    if (!ownerUserId) {
      return { error: 'No owner found for workspace', errorStatus: 500 }
    }

    // 通过统一身份服务解析/创建外部用户
    const externalUserId = externalUserService.resolveOrCreate({
      channelType: 'h5',
      channelId: pageId,
      platformUserId: payload.sub,
      platformName: payload.name,
      ownerUserId,
    })

    return { externalUserId, payload }
  } catch (err) {
    if (err instanceof JwtVerifyError) {
      const status = err.code === 'unknown_iss' || err.code === 'expired' ? 401 : 400
      return { error: err.message, errorStatus: status }
    }
    return { error: 'JWT verification failed', errorStatus: 400 }
  }
}
