/**
 * Email-Logs Export Endpoint
 *
 * GET /api/email-logs/export
 *
 * Exportiert Email-Logs als CSV oder JSON.
 * Nur für Super Admins und Tenant-Admins (für ihre eigenen Tenants).
 *
 * Query-Parameter:
 * - format: 'csv' | 'json' (default: 'json')
 * - tenantId: number (optional, für Filterung)
 * - status: 'pending' | 'sent' | 'failed' (optional)
 * - from: ISO date string (optional)
 * - to: ISO date string (optional)
 * - limit: number (default: 1000, max: 10000)
 */

import { getPayload } from 'payload'
import configPromise from '@payload-config'
import { NextRequest, NextResponse } from 'next/server'
import { logAccessDenied } from '@/lib/audit/audit-service'

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

interface EmailLogEntry {
  id: number
  to: string
  from: string
  subject: string
  status: string
  source: string
  messageId?: string
  error?: string
  createdAt: string
  tenant?: { id: number; name?: string } | number
}

function getUserTenantIds(user: UserWithTenants): number[] {
  return (user.tenants || []).map((t) => (typeof t.tenant === 'object' ? t.tenant.id : t.tenant))
}

function escapeCsvField(field: string | undefined | null): string {
  if (field === undefined || field === null) return ''
  const str = String(field)
  if (str.includes(',') || str.includes('"') || str.includes('\n')) {
    return `"${str.replace(/"/g, '""')}"`
  }
  return str
}

function convertToCSV(logs: EmailLogEntry[]): string {
  const headers = [
    'ID',
    'Datum',
    'Empfänger',
    'Absender',
    'Betreff',
    'Status',
    'Quelle',
    'Message-ID',
    'Fehler',
    'Tenant-ID',
  ]

  const rows = logs.map((log) => {
    const tenantId = typeof log.tenant === 'object' ? log.tenant?.id : log.tenant
    return [
      log.id,
      log.createdAt,
      log.to,
      log.from,
      log.subject,
      log.status,
      log.source,
      log.messageId || '',
      log.error || '',
      tenantId || '',
    ]
      .map((field) => escapeCsvField(String(field)))
      .join(',')
  })

  return [headers.join(','), ...rows].join('\n')
}

export async function GET(req: NextRequest): Promise<NextResponse> {
  try {
    const payload = await getPayload({ config: configPromise })

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

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

    const typedUser = user as unknown as UserWithTenants

    // Query-Parameter parsen
    const searchParams = req.nextUrl.searchParams
    const format = searchParams.get('format') || 'json'
    const tenantIdParam = searchParams.get('tenantId')
    const status = searchParams.get('status')
    const fromDate = searchParams.get('from')
    const toDate = searchParams.get('to')
    const limitParam = searchParams.get('limit')

    // Limit validieren
    let limit = parseInt(limitParam || '1000', 10)
    if (isNaN(limit) || limit < 1) limit = 1000
    if (limit > 10000) limit = 10000

    // Tenant-Zugriff prüfen
    const userTenantIds = getUserTenantIds(typedUser)
    let tenantFilter: number[] | undefined

    if (typedUser.isSuperAdmin) {
      // Super Admin kann alle oder gefiltert abrufen
      if (tenantIdParam) {
        tenantFilter = [parseInt(tenantIdParam, 10)]
      }
    } else {
      // Normale User können nur ihre Tenants sehen
      if (tenantIdParam) {
        const requestedTenant = parseInt(tenantIdParam, 10)
        if (!userTenantIds.includes(requestedTenant)) {
          // Audit: Zugriffsverweigerung loggen
          await logAccessDenied(
            payload,
            `/api/email-logs/export (tenantId: ${requestedTenant})`,
            typedUser.id,
            typedUser.email,
          )
          return NextResponse.json({ error: 'Kein Zugriff auf diesen Tenant' }, { status: 403 })
        }
        tenantFilter = [requestedTenant]
      } else {
        tenantFilter = userTenantIds
      }
    }

    // Query erstellen
    const where: Record<string, unknown> = {}

    if (tenantFilter) {
      where.tenant = { in: tenantFilter }
    }

    if (status && ['pending', 'sent', 'failed'].includes(status)) {
      where.status = { equals: status }
    }

    if (fromDate) {
      where.createdAt = {
        ...(where.createdAt as object),
        greater_than_equal: new Date(fromDate).toISOString(),
      }
    }

    if (toDate) {
      where.createdAt = {
        ...(where.createdAt as object),
        less_than_equal: new Date(toDate).toISOString(),
      }
    }

    type FindArgs = Parameters<typeof payload.find>[0]
    const result = await payload.find({
      collection: 'email-logs',
      where: where as FindArgs['where'],
      limit,
      sort: '-createdAt',
      depth: 1,
    })

    const logs = result.docs as EmailLogEntry[]

    // Format-spezifische Response
    if (format === 'csv') {
      const csv = convertToCSV(logs)
      return new NextResponse(csv, {
        status: 200,
        headers: {
          'Content-Type': 'text/csv; charset=utf-8',
          'Content-Disposition': `attachment; filename="email-logs-${new Date().toISOString().split('T')[0]}.csv"`,
        },
      })
    }

    // JSON Response
    return NextResponse.json({
      success: true,
      total: result.totalDocs,
      exported: logs.length,
      logs: logs.map((log) => ({
        id: log.id,
        to: log.to,
        from: log.from,
        subject: log.subject,
        status: log.status,
        source: log.source,
        messageId: log.messageId,
        error: log.error,
        createdAt: log.createdAt,
        tenantId: typeof log.tenant === 'object' ? log.tenant?.id : log.tenant,
      })),
    })
  } catch (error) {
    console.error('[EmailLogs:Export] Error:', error)
    return NextResponse.json({ error: 'Interner Serverfehler' }, { status: 500 })
  }
}
