<?php

declare(strict_types=1);

namespace App\Framework\Discovery\Events;

use App\Framework\Core\ValueObjects\Timestamp;
use App\Framework\Discovery\ValueObjects\MemoryStrategy;

/**
 * Event fired when memory strategy is changed during discovery
 */
final readonly class MemoryStrategyChangedEvent
{
    public function __construct(
        public MemoryStrategy $previousStrategy,
        public MemoryStrategy $newStrategy,
        public string $changeReason,
        public ?array $triggerMetrics,
        public ?string $context,
        public Timestamp $timestamp
    ) {
    }

    public function isEmergencyChange(): bool
    {
        return str_contains(strtolower($this->changeReason), 'emergency') ||
               str_contains(strtolower($this->changeReason), 'critical');
    }

    public function isStrategyDowngrade(): bool
    {
        $strategyLevels = [
            MemoryStrategy::STREAMING->value => 1,
            MemoryStrategy::CONSERVATIVE->value => 2,
            MemoryStrategy::BATCH->value => 3,
            MemoryStrategy::ADAPTIVE->value => 4,
            MemoryStrategy::AGGRESSIVE->value => 5,
        ];

        $previousLevel = $strategyLevels[$this->previousStrategy->value] ?? 0;
        $newLevel = $strategyLevels[$this->newStrategy->value] ?? 0;

        return $newLevel < $previousLevel;
    }

    public function getImpactDescription(): string
    {
        if ($this->isStrategyDowngrade()) {
            return 'Performance may decrease but memory usage will be more conservative';
        } else {
            return 'Performance may improve but memory usage will be higher';
        }
    }

    public function toArray(): array
    {
        return [
            'previous_strategy' => $this->previousStrategy->value,
            'previous_strategy_description' => $this->previousStrategy->getDescription(),
            'new_strategy' => $this->newStrategy->value,
            'new_strategy_description' => $this->newStrategy->getDescription(),
            'change_reason' => $this->changeReason,
            'trigger_metrics' => $this->triggerMetrics,
            'context' => $this->context,
            'is_emergency_change' => $this->isEmergencyChange(),
            'is_strategy_downgrade' => $this->isStrategyDowngrade(),
            'impact_description' => $this->getImpactDescription(),
            'timestamp' => $this->timestamp->toFloat(),
        ];
    }
}
