/**
 * Custom Login Endpoint mit Audit-Logging
 *
 * POST /api/auth/login
 *
 * Dieser Endpoint wrappet den nativen Payload-Login und loggt fehlgeschlagene
 * Login-Versuche im Audit-Log. Erfolgreiche Logins werden durch den
 * afterLogin-Hook in der Users-Collection geloggt.
 *
 * Security:
 * - Rate-Limiting: 5 Versuche pro 15 Minuten pro IP (Anti-Brute-Force)
 * - IP-Blocklist-Prüfung
 * - Audit-Logging für fehlgeschlagene Logins
 *
 * Body:
 * - email: string (erforderlich)
 * - password: string (erforderlich)
 */

import { getPayload } from 'payload'
import configPromise from '@payload-config'
import { NextRequest, NextResponse } from 'next/server'
import { logLoginFailed, logRateLimit } from '@/lib/audit/audit-service'
import {
  authLimiter,
  rateLimitHeaders,
  getClientIpFromRequest,
  isIpBlocked,
  validateCsrf,
} from '@/lib/security'

/**
 * Extrahiert Client-Informationen aus dem Request für Audit-Logging
 */
function getClientInfo(req: NextRequest): { ipAddress: string; userAgent: string } {
  const forwarded = req.headers.get('x-forwarded-for')
  const realIp = req.headers.get('x-real-ip')
  const ipAddress =
    (forwarded ? forwarded.split(',')[0]?.trim() : undefined) || realIp || 'unknown'

  const userAgent = req.headers.get('user-agent') || 'unknown'

  return { ipAddress, userAgent }
}

export async function POST(req: NextRequest): Promise<NextResponse> {
  try {
    // IP-Blocklist prüfen
    const clientIp = getClientIpFromRequest(req)
    if (isIpBlocked(clientIp)) {
      return NextResponse.json(
        { success: false, error: 'Access denied' },
        { status: 403 },
      )
    }

    // CSRF-Schutz für Browser-basierte Requests
    const csrfResult = validateCsrf(req)
    if (!csrfResult.valid) {
      return NextResponse.json(
        { success: false, error: 'CSRF validation failed' },
        { status: 403 },
      )
    }

    // Rate-Limiting prüfen (Anti-Brute-Force)
    const rateLimit = await authLimiter.check(clientIp)
    if (!rateLimit.allowed) {
      const payload = await getPayload({ config: configPromise })
      await logRateLimit(payload, '/api/auth/login', undefined, undefined)

      return NextResponse.json(
        {
          success: false,
          error: 'Too many login attempts. Please try again later.',
        },
        {
          status: 429,
          headers: rateLimitHeaders(rateLimit, 5),
        },
      )
    }

    const payload = await getPayload({ config: configPromise })
    const body = await req.json()

    const { email, password } = body

    // Validierung
    if (!email || !password) {
      return NextResponse.json(
        { error: 'E-Mail und Passwort sind erforderlich' },
        { status: 400 },
      )
    }

    try {
      // Versuche Login über Payload
      const result = await payload.login({
        collection: 'users',
        data: {
          email,
          password,
        },
      })

      // Erfolgreicher Login - afterLogin Hook hat bereits geloggt
      // Setze Cookie für die Session
      const response = NextResponse.json({
        success: true,
        user: {
          id: result.user.id,
          email: result.user.email,
        },
        message: 'Login erfolgreich',
      })

      // Set the token cookie
      if (result.token) {
        response.cookies.set('payload-token', result.token, {
          httpOnly: true,
          secure: process.env.NODE_ENV === 'production',
          sameSite: 'lax',
          path: '/',
          // Token expiration (default 2 hours)
          maxAge: result.exp ? result.exp - Math.floor(Date.now() / 1000) : 7200,
        })
      }

      return response
    } catch (loginError) {
      // Login fehlgeschlagen - Audit-Log erstellen mit vollem Context
      const errorMessage =
        loginError instanceof Error ? loginError.message : 'Unbekannter Fehler'

      // Bestimme den Grund für das Fehlschlagen
      let reason = 'Unbekannter Fehler'
      if (errorMessage.includes('not found') || errorMessage.includes('incorrect')) {
        reason = 'Ungültige Anmeldedaten'
      } else if (errorMessage.includes('locked')) {
        reason = 'Konto gesperrt'
      } else if (errorMessage.includes('disabled')) {
        reason = 'Konto deaktiviert'
      } else if (errorMessage.includes('verify')) {
        reason = 'E-Mail nicht verifiziert'
      } else {
        reason = errorMessage
      }

      // Client-Info für Audit-Log extrahieren
      const clientInfo = getClientInfo(req)

      // Audit-Log für fehlgeschlagenen Login mit vollem Client-Context
      await logLoginFailed(payload, email, reason, clientInfo)

      console.log(
        `[Audit:Auth] Login failed for ${email}: ${reason} (IP: ${clientInfo.ipAddress})`,
      )

      return NextResponse.json(
        {
          success: false,
          error: 'Anmeldung fehlgeschlagen',
          // Keine detaillierten Infos aus Sicherheitsgründen
        },
        { status: 401 },
      )
    }
  } catch (error) {
    console.error('[API:Auth] Login error:', error)
    return NextResponse.json(
      { error: 'Interner Serverfehler' },
      { status: 500 },
    )
  }
}

/**
 * GET /api/auth/login
 *
 * Gibt API-Dokumentation zurück.
 */
export async function GET(): Promise<NextResponse> {
  return NextResponse.json({
    endpoint: '/api/auth/login',
    method: 'POST',
    description: 'Login endpoint with audit logging for failed attempts',
    body: {
      email: 'string (required)',
      password: 'string (required)',
    },
    response: {
      success: {
        success: true,
        user: { id: 'number', email: 'string' },
        message: 'string',
      },
      error: {
        success: false,
        error: 'string',
      },
    },
    note: 'Successful logins are logged via afterLogin hook. Failed attempts are logged here.',
  })
}
