import { readUsers, writeUsers, verifyPassword, generateToken, createSession, migrateUserRoles } from '../../utils/auth.js'
import { assertRateLimit, getClientIp, registerRateLimitFailure, registerRateLimitSuccess } from '../../utils/rate-limit.js'
import { getAuthCookieOptions } from '../../utils/cookies.js'
import { writeAuditLog } from '../../utils/audit-log.js'

export default defineEventHandler(async (event) => {
  try {
    const body = await readBody(event)
    const { email, password } = body

    if (!email || !password) {
      throw createError({
        statusCode: 400,
        message: 'E-Mail und Passwort sind erforderlich'
      })
    }

    const ip = getClientIp(event)
    const emailKey = String(email || '').trim().toLowerCase()

    // Rate Limiting (IP + Account)
    assertRateLimit(event, {
      name: 'auth:login:ip',
      keyParts: [ip],
      windowMs: 10 * 60 * 1000,
      maxAttempts: 30,
      lockoutMs: 15 * 60 * 1000
    })
    assertRateLimit(event, {
      name: 'auth:login:account',
      keyParts: [emailKey],
      windowMs: 10 * 60 * 1000,
      maxAttempts: 10,
      lockoutMs: 30 * 60 * 1000
    })

    // Find user
    const users = await readUsers()
    const user = users.find(u => u.email.toLowerCase() === email.toLowerCase())

    if (!user) {
      await registerRateLimitFailure(event, { name: 'auth:login:ip', keyParts: [ip] })
      await registerRateLimitFailure(event, { name: 'auth:login:account', keyParts: [emailKey] })
      await writeAuditLog('auth.login.failed', { ip, email: emailKey, reason: 'user_not_found' })
      throw createError({
        statusCode: 401,
        message: 'Ungültige Anmeldedaten'
      })
    }

    // Check if user is active
    if (user.active === false) {
      throw createError({
        statusCode: 403,
        message: 'Ihr Konto wurde noch nicht freigeschaltet. Bitte warten Sie auf die Bestätigung des Vorstands.'
      })
    }

    // Verify password
    const isValid = await verifyPassword(password, user.password)
    if (!isValid) {
      await registerRateLimitFailure(event, { name: 'auth:login:ip', keyParts: [ip] })
      await registerRateLimitFailure(event, { name: 'auth:login:account', keyParts: [emailKey] })
      await writeAuditLog('auth.login.failed', { ip, email: emailKey, userId: user.id, reason: 'bad_password' })
      throw createError({
        statusCode: 401,
        message: 'Ungültige Anmeldedaten'
      })
    }

    // Erfolg: Limiter zurücksetzen
    registerRateLimitSuccess(event, { name: 'auth:login:ip', keyParts: [ip] })
    registerRateLimitSuccess(event, { name: 'auth:login:account', keyParts: [emailKey] })

    // Generate token
    const token = generateToken(user)

    // Create session
    await createSession(user.id, token)

    await writeAuditLog('auth.login.success', { ip, email: emailKey, userId: user.id })

    // Update last login
    user.lastLogin = new Date().toISOString()
    const updatedUsers = users.map(u => u.id === user.id ? user : u)
    await writeUsers(updatedUsers)

    // Set cookie
    setCookie(event, 'auth_token', token, {
      ...getAuthCookieOptions()
    })

    // Migriere Rollen falls nötig
    const migratedUser = migrateUserRoles({ ...user })
    const roles = Array.isArray(migratedUser.roles) ? migratedUser.roles : (migratedUser.role ? [migratedUser.role] : ['mitglied'])
    
    // Return user data (without password) and token for API usage
    return {
      success: true,
      token: token, // Token auch im Body für externe API-Clients
      user: {
        id: user.id,
        email: user.email,
        name: user.name,
        roles: roles
      },
      // Rückwärtskompatibilität: erste Rolle als role
      role: roles[0] || 'mitglied'
    }
  } catch (error) {
    console.error('Login-Fehler:', error)
    throw error
  }
})

