<?php

declare(strict_types=1);

namespace App\Framework\CircuitBreaker\Events;

use App\Framework\CircuitBreaker\CircuitBreakerMetrics;
use App\Framework\CircuitBreaker\CircuitState;
use App\Framework\Core\ValueObjects\Timestamp;

/**
 * Event fired when a circuit breaker transitions to HALF_OPEN state
 */
final readonly class CircuitBreakerHalfOpened implements CircuitBreakerEvent
{
    public string $eventType;

    public string $severity;

    public CircuitState $newState;

    public Timestamp $occurredAt;

    public function __construct(
        public string $service,
        public string $namespace,
        public CircuitState $previousState,
        public CircuitBreakerMetrics $metrics,
        public ?string $reason = null,
        ?Timestamp $occurredAt = null,
    ) {
        $this->eventType = 'circuit_breaker_half_opened';
        $this->severity = 'info';
        $this->newState = CircuitState::HALF_OPEN;
        $this->occurredAt = $occurredAt ?? Timestamp::now();
    }

    public function getDescription(): string
    {
        $uptime = $this->metrics->getUptimeDuration()?->toHumanReadable() ?? 'unknown';
        $reason = $this->reason ? " (Reason: {$this->reason})" : '';

        return "Circuit breaker for '{$this->service}' transitioned to HALF_OPEN after {$uptime} recovery time{$reason}";
    }

    public function toArray(): array
    {
        return [
            'event_type' => $this->eventType,
            'service' => $this->service,
            'namespace' => $this->namespace,
            'previous_state' => $this->previousState->value,
            'new_state' => $this->newState->value,
            'reason' => $this->reason,
            'occurred_at' => $this->occurredAt->toIsoString(),
            'severity' => $this->severity,
            'description' => $this->getDescription(),
            'metrics' => $this->metrics->toArray(),
        ];
    }
}
