import crypto from 'crypto'
import { generateRegistrationOptions } from '@simplewebauthn/server'
import { readUsers } from '../../utils/auth.js'
import { getWebAuthnConfig } from '../../utils/webauthn-config.js'
import { setPreRegistration } from '../../utils/webauthn-challenges.js'
import { writeAuditLog } from '../../utils/audit-log.js'

function isValidEmail(email) {
  return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(String(email || ''))
}

export default defineEventHandler(async (event) => {
  const requestStart = Date.now()
  const requestOrigin = getHeader(event, 'origin')
  const userAgent = getHeader(event, 'user-agent')
  const nodeEnv = process.env.NODE_ENV || 'development'
  
  // Debug-Ausgaben immer ausgeben (nicht nur in dev)
  console.log('')
  console.log('='.repeat(80))
  console.log('[DEBUG] 📋 ===== REGISTRATION OPTIONS REQUEST RECEIVED =====')
  console.log('='.repeat(80))
  console.log('[DEBUG] Request Details:', {
    origin: requestOrigin || 'none',
    userAgent: userAgent?.substring(0, 150) || 'none',
    method: getMethod(event),
    timestamp: new Date().toISOString(),
    nodeEnv: nodeEnv,
    pid: process.pid,
    ip: getHeader(event, 'x-forwarded-for') || getHeader(event, 'x-real-ip') || 'unknown',
    note: 'Dieser Request kommt vom Desktop-Browser, wenn der QR-Code generiert wird'
  })
  console.log('[DEBUG] User-Agent Analysis:', {
    isMobile: /Mobile|Android|iPhone|iPad/i.test(userAgent || ''),
    isDesktop: !/Mobile|Android|iPhone|iPad/i.test(userAgent || ''),
    browser: userAgent?.substring(0, 100)
  })
  console.log('='.repeat(80))
  console.log('')

  const body = await readBody(event)
  const name = String(body?.name || '').trim()
  const email = String(body?.email || '').trim().toLowerCase()
  const phone = String(body?.phone || '').trim()

  console.log('[DEBUG] Request body parsed', {
    hasName: !!name,
    hasEmail: !!email,
    hasPhone: !!phone,
    email: email.substring(0, 10) + '...'
  })

  if (!name || !email) {
    console.error('[DEBUG] Validation failed: missing name or email')
    throw createError({ statusCode: 400, message: 'Name und E-Mail sind erforderlich' })
  }
  if (!isValidEmail(email)) {
    console.error('[DEBUG] Validation failed: invalid email format')
    throw createError({ statusCode: 400, message: 'Ungültige E-Mail-Adresse' })
  }

  const users = await readUsers()
  if (users.some(u => String(u.email || '').toLowerCase() === email)) {
    throw createError({ statusCode: 409, message: 'Ein Benutzer mit dieser E-Mail-Adresse existiert bereits' })
  }

  const { rpId, rpName, origin: webauthnOrigin } = getWebAuthnConfig()
  
  console.log('[DEBUG] WebAuthn config', {
    rpId,
    rpName,
    webauthnOrigin,
    requestOrigin,
    webauthnOriginEnv: process.env.WEBAUTHN_ORIGIN,
    baseUrlEnv: process.env.NUXT_PUBLIC_BASE_URL
  })
  
  // WICHTIG: Sicherstellen, dass die Origin KEINEN Port hat
  if (webauthnOrigin.includes(':3100')) {
    console.error('[DEBUG] ERROR: webauthnOrigin contains port 3100! This will cause verification to fail.')
    console.error('[DEBUG] Fix: Set WEBAUTHN_ORIGIN=https://harheimertc.tsschulz.de (without port) in .env')
  }

  const userId = crypto.randomUUID()
  const registrationId = crypto.randomBytes(16).toString('hex')
  
  console.log('[DEBUG] Generated IDs', {
    userId,
    registrationId
  })

  console.log('[DEBUG] Generating registration options...')
  const optionsStart = Date.now()
  
  const options = await generateRegistrationOptions({
    rpName,
    rpID: rpId,
    userID: new TextEncoder().encode(String(userId)),
    userName: email,
    userDisplayName: name,
    attestationType: 'none',
    authenticatorSelection: {
      residentKey: 'preferred',
      userVerification: 'preferred',
      requireResidentKey: false,
      // WICHTIG: authenticatorAttachment bestimmt, welche Authenticatoren verwendet werden können
      // - 'platform': Nur lokale Authenticatoren (Windows Hello, TouchID, Browser-eigene Passkey-Speicherung)
      // - 'cross-platform': Nur externe Authenticatoren (USB-Schlüssel, Smartphone via Cross-Device)
      // - NICHT setzen: Browser entscheidet automatisch (kann lokale ODER Cross-Device verwenden)
      // 
      // Für Browser-eigene Passkey-Speicherung: 'platform' verwenden
      // Dies ermöglicht:
      //   - Browser-eigene Passkey-Speicherung (Chrome Password Manager, Firefox Password Manager, etc.)
      //   - Windows Hello (biometrisch oder PIN)
      //   - TouchID auf Mac
      //   - KEIN Cross-Device (kein Smartphone nötig)
      authenticatorAttachment: 'platform' // Lokale Authenticatoren (Browser-eigene Passkey-Speicherung)
    },
    // Timeout erhöhen für Cross-Device (Standard: 60s, hier: 5 Minuten)
    timeout: 300000
    // HINWEIS: FIDO Cross-Device verwendet Tunnel-Server (z.B. cable.ua5v.com von Google)
    // Der Browser verwaltet den Tunnel automatisch - der Server muss nichts konfigurieren
    // Für Cross-Device funktioniert es so:
    // 1. Desktop-Browser generiert QR-Code mit öffentlichem Schlüssel (FIDO-URI)
    // 2. Desktop-Browser registriert sich beim Tunnel-Server (cable.ua5v.com)
    // 3. Smartphone scannt QR-Code
    // 4. Smartphone verbindet sich über Tunnel-Server mit Desktop-Browser
    // 5. Desktop-Browser leitet Credential-Response an den Server weiter
    // Voraussetzungen:
    // - Beide Geräte müssen Internetverbindung haben
    // - Tunnel-Server müssen erreichbar sein (cable.ua5v.com, cable.auth.com)
    // - Bluetooth kann für physische Nähe-Bestätigung verwendet werden (abhängig vom Browser/Gerät)
  })
  
  const optionsDuration = Date.now() - optionsStart
  console.log('[DEBUG] Registration options generated', { optionsDurationMs: optionsDuration,
    hasChallenge: !!options.challenge,
    challengeLength: options.challenge?.length,
    rpId: options.rp?.id,
    rpName: options.rp?.name,
    userId: options.user?.id ? 'present' : 'missing',
    userName: options.user?.name,
    userDisplayName: options.user?.displayName,
    timeout: options.timeout,
    pubKeyCredParamsCount: options.pubKeyCredParams?.length,
    authenticatorSelection: options.authenticatorSelection,
    excludeCredentialsCount: options.excludeCredentials?.length || 0
  })

  setPreRegistration(registrationId, {
    challenge: options.challenge,
    userId,
    name,
    email,
    phone
  })
  
  console.log('[DEBUG] Pre-registration stored', {
    registrationId,
    challengeStored: !!options.challenge
  })

  await writeAuditLog('auth.passkey.prereg.options', { email })

  // CORS-Header für Cross-Device Authentication
  // WICHTIG: Für Cross-Device muss CORS korrekt konfiguriert sein
  // OPTIONS-Requests werden von .options.js behandelt
  const allowedOrigin = requestOrigin || webauthnOrigin
  
  if (allowedOrigin) {
    setHeader(event, 'Access-Control-Allow-Origin', allowedOrigin)
    setHeader(event, 'Access-Control-Allow-Credentials', 'true')
    setHeader(event, 'Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
    setHeader(event, 'Access-Control-Allow-Headers', 'Content-Type, Authorization, Origin, X-Requested-With')
    setHeader(event, 'Access-Control-Max-Age', '86400') // 24 Stunden Cache für Preflight
    console.log('[DEBUG] CORS headers set for POST', { 
      origin: allowedOrigin,
      requestOrigin,
      webauthnOrigin
    })
  }

  // Options direkt zurückgeben (wie in passkeys/registration-options.post.js)
  // @simplewebauthn/server gibt bereits korrekt formatierte Options zurück
  const totalDuration = Date.now() - requestStart
  
  // Debug: Prüfe die vollständige Options-Struktur
  console.log('[DEBUG] Returning options', { totalDurationMs: totalDuration,
    registrationId,
    optionsKeys: Object.keys(options),
    challengeLength: options.challenge?.length,
    challengeType: typeof options.challenge,
    rpId: options.rp?.id,
    rpName: options.rp?.name,
    userIdType: typeof options.user?.id,
    userName: options.user?.name,
    userDisplayName: options.user?.displayName,
    timeout: options.timeout,
    timeoutType: typeof options.timeout,
    pubKeyCredParamsCount: options.pubKeyCredParams?.length,
    authenticatorSelection: options.authenticatorSelection,
    hasExtensions: !!options.extensions,
    hasHints: !!options.hints,
    excludeCredentialsCount: options.excludeCredentials?.length || 0
  })
  
  // WICHTIG: Prüfe, ob die Options für Cross-Device korrekt sind
  // Für Cross-Device muss die Challenge ein String sein (Base64URL)
  if (typeof options.challenge !== 'string') {
    console.error('[DEBUG] ERROR: Challenge is not a string!', typeof options.challenge, options.challenge)
  }
  
  // Prüfe, ob user.id ein Uint8Array ist (wird zu Base64URL konvertiert)
  if (options.user?.id instanceof Uint8Array) {
    console.log('[DEBUG] user.id is Uint8Array (will be converted to Base64URL by browser)')
  } else {
    console.log('[DEBUG] user.id type:', typeof options.user?.id, 'value:', options.user?.id?.substring?.(0, 20))
  }

  // WICHTIG: Options direkt zurückgeben, keine manuelle Serialisierung
  // Die Options von @simplewebauthn/server sind bereits korrekt formatiert
  // Nuxt/Nitro serialisiert automatisch zu JSON
  return { success: true, registrationId, options }
})

