/**
 * Email Failure Alert Hook
 *
 * Überwacht EmailLogs auf wiederholte Fehler und löst Alerts aus.
 * Integriert mit dem Alert-Service für Multi-Channel-Benachrichtigungen.
 */

import type { CollectionAfterChangeHook } from 'payload'
import { alertEmailFailed } from '../lib/alerting/alert-service'
import { logEmailFailed } from '../lib/audit/audit-service'

// In-Memory Counter für failed E-Mails pro Tenant (innerhalb von 1 Stunde)
const failedEmailCounter: Map<number, { count: number; lastReset: number }> = new Map()
const RESET_INTERVAL = 60 * 60 * 1000 // 1 Stunde

/**
 * Inkrementiert den Zähler für fehlgeschlagene E-Mails
 */
function incrementFailedCount(tenantId: number): number {
  const now = Date.now()
  const entry = failedEmailCounter.get(tenantId)

  if (!entry || now - entry.lastReset > RESET_INTERVAL) {
    failedEmailCounter.set(tenantId, { count: 1, lastReset: now })
    return 1
  }

  entry.count++
  return entry.count
}

interface EmailLogDoc {
  id: number
  tenant: { id: number; name?: string } | number
  to: string
  subject: string
  status: 'pending' | 'sent' | 'failed'
  error?: string
}

/**
 * Hook: Reagiert auf neue EmailLog-Einträge mit Status "failed"
 */
export const emailFailureAlertHook: CollectionAfterChangeHook = async ({
  doc,
  previousDoc,
  operation,
  req,
}) => {
  const emailDoc = doc as EmailLogDoc

  // Nur bei Status-Änderung zu "failed" oder neuen failed-Einträgen
  const isNewFailed = operation === 'create' && emailDoc.status === 'failed'
  const isChangedToFailed =
    operation === 'update' && emailDoc.status === 'failed' && previousDoc?.status !== 'failed'

  if (!isNewFailed && !isChangedToFailed) {
    return doc
  }

  const { payload } = req

  // Tenant-ID und Name ermitteln
  const tenantId = typeof emailDoc.tenant === 'object' ? emailDoc.tenant.id : emailDoc.tenant

  let tenantName = 'Unbekannt'
  if (typeof emailDoc.tenant === 'object' && emailDoc.tenant.name) {
    tenantName = emailDoc.tenant.name
  } else {
    // Tenant-Name nachladen
    try {
      const tenant = await payload.findByID({
        collection: 'tenants',
        id: tenantId,
      })
      tenantName = tenant?.name || `Tenant ${tenantId}`
    } catch {
      tenantName = `Tenant ${tenantId}`
    }
  }

  // Fehler-Zähler erhöhen
  const failedCount = incrementFailedCount(tenantId)

  // Audit-Log erstellen
  await logEmailFailed(
    payload,
    tenantId,
    emailDoc.to,
    emailDoc.subject,
    emailDoc.error || 'Unbekannter Fehler',
  )

  // Alert senden (bei jedem Fehler, aber mit unterschiedlichem Level basierend auf failedCount)
  await alertEmailFailed(
    payload,
    tenantId,
    tenantName,
    emailDoc.to,
    emailDoc.subject,
    emailDoc.error || 'Unbekannter Fehler',
    failedCount,
  )

  console.log(
    `[EmailFailureAlert] Tenant ${tenantId} (${tenantName}): ${failedCount} fehlgeschlagene E-Mails in der letzten Stunde`,
  )

  return doc
}
