import { NextRequest, NextResponse } from 'next/server'
import { getPayload } from 'payload'
import configPromise from '@payload-config'
import { sendTestEmail } from '@/lib/email/tenant-email-service'
import {
  validateCsrf,
  createSafeLogger,
  emailLimiter,
  rateLimitHeaders,
  validateIpAccess,
} from '@/lib/security'

const RATE_LIMIT_MAX = 10
const logger = createSafeLogger('API:TestEmail')

interface UserWithTenants {
  id: number
  email?: string
  isSuperAdmin?: boolean
  tenants?: Array<{
    tenant: { id: number } | number
  }>
}

/**
 * Prüft ob User Zugriff auf den angegebenen Tenant hat
 * Normalisiert tenant-Objekte korrekt (können { id: number } oder number sein)
 */
function userHasAccessToTenant(user: UserWithTenants, tenantId: number): boolean {
  // Super Admins haben Zugriff auf alle Tenants
  if (user.isSuperAdmin) {
    return true
  }

  // Prüfe ob User dem Tenant zugeordnet ist
  if (!user.tenants || user.tenants.length === 0) {
    return false
  }

  return user.tenants.some((t) => {
    // Normalisiere: tenant kann ein Objekt { id: number } oder direkt eine number sein
    const userTenantId = typeof t.tenant === 'object' && t.tenant !== null
      ? t.tenant.id
      : t.tenant
    return userTenantId === tenantId
  })
}

/**
 * POST /api/test-email
 *
 * Sendet eine Test-E-Mail um die SMTP-Konfiguration eines Tenants zu verifizieren.
 *
 * Request Body:
 * - tenantId: number | string - ID des Tenants
 * - recipientEmail: string - E-Mail-Adresse des Empfängers
 *
 * Security:
 * - IP-Allowlist (optional via SEND_EMAIL_ALLOWED_IPS env)
 * - CSRF-Schutz (Double Submit Cookie)
 * - Authentifizierung erforderlich
 * - Tenant-Zugriffskontrolle
 * - Rate-Limiting (10/min pro User)
 */
export async function POST(req: NextRequest) {
  try {
    // IP-Allowlist prüfen (falls konfiguriert) - gleiche Regeln wie /api/send-email
    const ipCheck = validateIpAccess(req, 'sendEmail')
    if (!ipCheck.allowed) {
      logger.warn(`IP blocked: ${ipCheck.ip}`, { reason: ipCheck.reason })
      return NextResponse.json(
        { success: false, error: 'Access denied' },
        { status: 403 },
      )
    }

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

    const payload = await getPayload({ config: configPromise })

    // User aus Session prüfen
    const { user } = await payload.auth({ headers: req.headers })

    if (!user) {
      return NextResponse.json(
        { success: false, error: 'Nicht authentifiziert' },
        { status: 401 },
      )
    }

    const typedUser = user as UserWithTenants

    // Rate Limiting prüfen
    const rateLimit = await emailLimiter.check(String(typedUser.id))
    if (!rateLimit.allowed) {
      logger.warn('Rate limit exceeded', { userId: typedUser.id })
      return NextResponse.json(
        {
          success: false,
          error: 'Rate limit exceeded',
          message: `Maximum ${RATE_LIMIT_MAX} Test-E-Mails pro Minute. Versuchen Sie es in ${rateLimit.retryAfter || 60} Sekunden erneut.`,
        },
        {
          status: 429,
          headers: rateLimitHeaders(rateLimit, RATE_LIMIT_MAX),
        },
      )
    }

    // Request Body parsen
    const body = await req.json()
    const { tenantId, recipientEmail } = body

    if (!tenantId) {
      return NextResponse.json(
        { success: false, error: 'tenantId erforderlich' },
        { status: 400 },
      )
    }

    const numericTenantId = Number(tenantId)
    if (isNaN(numericTenantId)) {
      return NextResponse.json(
        { success: false, error: 'tenantId muss eine Zahl sein' },
        { status: 400 },
      )
    }

    if (!recipientEmail) {
      return NextResponse.json(
        { success: false, error: 'recipientEmail erforderlich' },
        { status: 400 },
      )
    }

    // E-Mail-Format validieren
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    if (!emailRegex.test(recipientEmail)) {
      return NextResponse.json(
        { success: false, error: 'Ungültiges E-Mail-Format' },
        { status: 400 },
      )
    }

    // Zugriffskontrolle: User muss Zugriff auf den Tenant haben
    if (!userHasAccessToTenant(typedUser, numericTenantId)) {
      logger.warn('Access denied to tenant', {
        userId: typedUser.id,
        tenantId: numericTenantId,
      })
      return NextResponse.json(
        { success: false, error: 'Kein Zugriff auf diesen Tenant' },
        { status: 403 },
      )
    }

    // Tenant prüfen - existiert er?
    const tenant = await payload.findByID({
      collection: 'tenants',
      id: numericTenantId,
      depth: 0,
    })

    if (!tenant) {
      return NextResponse.json(
        { success: false, error: 'Tenant nicht gefunden' },
        { status: 404 },
      )
    }

    // Rate Limit Headers
    const rlHeaders = rateLimitHeaders(rateLimit, RATE_LIMIT_MAX)

    // Test-E-Mail senden
    const result = await sendTestEmail(payload, numericTenantId, recipientEmail)

    if (result.success) {
      logger.info('Test email sent successfully', {
        tenantId: numericTenantId,
        recipient: recipientEmail,
        messageId: result.messageId,
      })
      return NextResponse.json(
        {
          success: true,
          message: `Test-E-Mail erfolgreich an ${recipientEmail} gesendet`,
          messageId: result.messageId,
          logId: result.logId,
        },
        { headers: rlHeaders },
      )
    } else {
      logger.error('Test email failed', {
        tenantId: numericTenantId,
        error: result.error,
      })
      return NextResponse.json(
        {
          success: false,
          error: result.error || 'Fehler beim Senden der Test-E-Mail',
        },
        { status: 500, headers: rlHeaders },
      )
    }
  } catch (error) {
    logger.error('test-email error', error)
    return NextResponse.json(
      {
        success: false,
        error: error instanceof Error ? error.message : 'Interner Server-Fehler',
      },
      { status: 500 },
    )
  }
}
