// server/api/auth/verify.post.js
import jwt from 'jsonwebtoken'
import Member from '../../models/member.js'

export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  const token = body?.token

  if (!token) {
    throw createError({
      statusCode: 400,
      statusMessage: 'Token is required',
    })
  }

  const config = useRuntimeConfig(event)

  let decoded
  try {
    decoded = jwt.verify(token, config.jwtSecret)
  } catch {
    throw createError({
      statusCode: 401,
      statusMessage: 'Invalid or expired token',
    })
  }

  const member = await Member.findById(decoded.memberId)

  if (!member) {
    throw createError({
      statusCode: 401,
      statusMessage: 'Invalid or expired token',
    })
  }

  if (member.status === 'suspended') {
    throw createError({
      statusCode: 403,
      statusMessage: 'Account is suspended',
    })
  }

  if (member.status === 'cancelled') {
    throw createError({
      statusCode: 403,
      statusMessage: 'Account is cancelled',
    })
  }

  // Single-use enforcement: jti must match and must not have been used
  if (!decoded.jti || decoded.jti !== member.magicLinkJti || member.magicLinkJtiUsed) {
    throw createError({
      statusCode: 401,
      statusMessage: 'Invalid or expired token',
    })
  }

  // Atomically burn the token before issuing session
  await Member.findByIdAndUpdate(
    member._id,
    { $set: { magicLinkJtiUsed: true, lastLogin: new Date() } },
    { runValidators: false }
  )

  // Issue session token with tokenVersion claim for revocation support
  const sessionToken = jwt.sign(
    { memberId: member._id, email: member.email, tv: member.tokenVersion },
    config.jwtSecret,
    { expiresIn: '7d' },
  )

  setCookie(event, 'auth-token', sessionToken, {
    httpOnly: true,
    secure: process.env.NODE_ENV === 'production',
    sameSite: 'lax',
    path: '/',
    maxAge: 60 * 60 * 24 * 7, // 7 days
  })

  const redirectUrl = member.role === 'admin' ? '/admin' : '/member/dashboard'
  return { success: true, redirectUrl }
})
