<?php

declare(strict_types=1);

namespace App\Framework\EventBus;

use App\Framework\Core\AttributeCompiler;

/**
 * Compiler für Event-Handler
 */
final readonly class EventHandlerCompiler implements AttributeCompiler
{
    /**
     * Gibt die Attributklasse zurück, die dieser Compiler verarbeitet
     */
    public function getAttributeClass(): string
    {
        return QueryHandler::class;
    }

    /**
     * Kompiliert die Event-Handler
     *
     * @param array $handlers Array mit Attributdaten aus dem Mapper
     * @return array Kompilierte Event-Handler
     */
    public function compile(array $handlers): array
    {
        $compiledHandlers = [];

        // Wenn keine Handler vorhanden sind, leeres Array zurückgeben
        if (empty($handlers)) {
            return $compiledHandlers;
        }

        foreach ($handlers as $handler) {
            $className = $handler['class'] ?? null;
            $methodName = $handler['method'] ?? null;
            $eventClass = $handler['event_class'] ?? null;
            $priority = $handler['attribute_data']['priority'] ?? 0;
            $stopPropagation = $handler['attribute_data']['stopPropagation'] ?? false;

            // Prüfe, ob alle erforderlichen Daten vorhanden sind
            if (! $className || ! $methodName || ! $eventClass) {
                continue;
            }

            // Füge den Handler zur Liste der Handler für diesen Event-Typ hinzu
            if (! isset($compiledHandlers[$eventClass])) {
                $compiledHandlers[$eventClass] = [];
            }

            $compiledHandlers[$eventClass][] = [
                'class' => $className,
                'method' => $methodName,
                'priority' => $priority,
                'stopPropagation' => $stopPropagation,
            ];
        }

        // Sortiere die Handler nach Priorität für jeden Event-Typ
        foreach ($compiledHandlers as $eventClass => $eventHandlers) {
            usort($compiledHandlers[$eventClass], function ($a, $b) {
                return $b['priority'] <=> $a['priority'];
            });
        }

        return $compiledHandlers;
    }
}
