<?php

declare(strict_types=1);

namespace App\Framework\ErrorHandling;

use App\Framework\Exception\SecurityException;
use App\Framework\Exception\ErrorHandlerContext;

/**
 * Manager für Security-Alerts - Integration zu externen Alert-Systemen
 */
final readonly class SecurityAlertManager
{
    public function __construct(
        private array $alertChannels = []
    ) {}

    /**
     * Sendet Alert über alle konfigurierten Kanäle
     */
    public function sendAlert(
        SecurityException $exception,
        ErrorHandlerContext $context
    ): void {
        $alertData = $this->createAlertPayload($exception, $context);

        foreach ($this->alertChannels as $channel) {
            try {
                $channel->sendAlert($alertData);
            } catch (\Throwable $e) {
                // Alert-Fehler nicht propagieren, nur loggen
                error_log("Alert channel failed: " . $e->getMessage());
            }
        }
    }

    /**
     * Erstellt standardisierte Alert-Payload
     */
    private function createAlertPayload(
        SecurityException $exception,
        ErrorHandlerContext $context
    ): array {
        $securityEvent = $exception->getSecurityEvent();

        return [
            'type' => 'security_alert',
            'severity' => $this->mapSeverity($exception->getSecurityLevel()),
            'event_id' => $securityEvent->getEventIdentifier(),
            'title' => 'Security Event: ' . $securityEvent->getCategory(),
            'description' => $securityEvent->getDescription(),
            'details' => [
                'category' => $securityEvent->getCategory(),
                'level' => $exception->getSecurityLevel()->value,
                'client_ip' => $context->request->clientIp,
                'user_agent' => $context->request->userAgent,
                'request_uri' => $context->request->requestUri,
                'timestamp' => date('c'),
                'request_id' => $context->request->requestId
            ],
            'event_data' => $securityEvent->toArray(),
            'context' => $context->forLogging()
        ];
    }

    /**
     * Mappt Security-Level auf Alert-Severity
     */
    private function mapSeverity(\App\Framework\Exception\SecurityLogLevel $level): string
    {
        return match($level) {
            \App\Framework\Exception\SecurityLogLevel::FATAL => 'critical',
            \App\Framework\Exception\SecurityLogLevel::ERROR => 'high',
            \App\Framework\Exception\SecurityLogLevel::WARN => 'medium',
            \App\Framework\Exception\SecurityLogLevel::INFO => 'low',
            \App\Framework\Exception\SecurityLogLevel::DEBUG => 'info',
        };
    }

    /**
     * Factory mit Standard-Alert-Kanälen
     */
    public static function createWithChannels(array $channels): self
    {
        return new self($channels);
    }
}
