import { verifyRegistrationResponse } from '@simplewebauthn/server'
import { getUserFromToken, readUsers, writeUsers } from '../../../utils/auth.js'
import { getWebAuthnConfig } from '../../../utils/webauthn-config.js'
import { clearRegistrationChallenge, getRegistrationChallenge } from '../../../utils/webauthn-challenges.js'
import { toBase64Url } from '../../../utils/webauthn-encoding.js'
import { writeAuditLog } from '../../../utils/audit-log.js'

export default defineEventHandler(async (event) => {
  // CORS-Header für Cross-Device Authentication
  const requestOrigin = getHeader(event, 'origin')
  if (requestOrigin) {
    setHeader(event, 'Access-Control-Allow-Origin', requestOrigin)
    setHeader(event, 'Access-Control-Allow-Credentials', 'true')
    setHeader(event, 'Access-Control-Allow-Methods', 'POST, OPTIONS')
    setHeader(event, 'Access-Control-Allow-Headers', 'Content-Type, Authorization')
  }

  if (getMethod(event) === 'OPTIONS') {
    return { success: true }
  }

  const token = getCookie(event, 'auth_token')
  const user = token ? await getUserFromToken(token) : null

  if (!user) {
    throw createError({ statusCode: 401, statusMessage: 'Nicht authentifiziert' })
  }

  const body = await readBody(event)
  const response = body?.credential
  if (!response) {
    throw createError({ statusCode: 400, statusMessage: 'Credential fehlt' })
  }

  const expectedChallenge = getRegistrationChallenge(user.id)
  if (!expectedChallenge) {
    throw createError({ statusCode: 400, statusMessage: 'Registrierungs-Session abgelaufen. Bitte erneut versuchen.' })
  }

  const { origin, rpId, requireUV } = getWebAuthnConfig()

  let verification
  try {
    verification = await verifyRegistrationResponse({
      response,
      expectedChallenge,
      expectedOrigin: origin,
      expectedRPID: rpId,
      requireUserVerification: requireUV
    })
  } finally {
    clearRegistrationChallenge(user.id)
  }

  const { verified, registrationInfo } = verification
  if (!verified || !registrationInfo) {
    await writeAuditLog('auth.passkey.registration.failed', { userId: user.id })
    throw createError({ statusCode: 400, statusMessage: 'Passkey-Registrierung fehlgeschlagen' })
  }

  const {
    credentialID,
    credentialPublicKey,
    counter,
    credentialDeviceType,
    credentialBackedUp
  } = registrationInfo

  const credentialId = toBase64Url(credentialID)
  const publicKey = toBase64Url(credentialPublicKey)

  const users = await readUsers()
  const idx = users.findIndex(u => u.id === user.id)
  if (idx === -1) {
    throw createError({ statusCode: 404, statusMessage: 'Benutzer nicht gefunden' })
  }

  const u = users[idx]
  if (!Array.isArray(u.passkeys)) u.passkeys = []

  // Duplikate verhindern
  if (u.passkeys.some(pk => pk.credentialId === credentialId)) {
    return { success: true, message: 'Passkey ist bereits registriert.' }
  }

  u.passkeys.push({
    id: `${Date.now()}`,
    credentialId,
    publicKey,
    counter: Number(counter) || 0,
    transports: Array.isArray(response.transports) ? response.transports : undefined,
    deviceType: credentialDeviceType,
    backedUp: !!credentialBackedUp,
    createdAt: new Date().toISOString(),
    lastUsedAt: null,
    name: body?.name ? String(body.name).slice(0, 80) : 'Passkey'
  })

  users[idx] = u
  await writeUsers(users)

  await writeAuditLog('auth.passkey.registered', { userId: user.id })
  return { success: true, message: 'Passkey hinzugefügt.' }
})


