<?php

declare(strict_types=1);

namespace App\Framework\ErrorBoundaries\Events;

use App\Framework\Core\ValueObjects\Duration;
use App\Framework\Core\ValueObjects\Timestamp;

/**
 * Event fired when boundary operation times out
 */
final readonly class BoundaryTimeoutOccurred implements BoundaryEventInterface
{
    public readonly string $eventType;

    public readonly Timestamp $occurredAt;

    public readonly string $severity;

    public function __construct(
        public string $boundaryName,
        public Duration $timeoutThreshold,
        public Duration $actualExecutionTime,
        public bool $fallbackExecuted = false,
        public ?string $message = null,
        public array $context = [],
    ) {
        $this->eventType = 'boundary.timeout.occurred';
        $this->occurredAt = Timestamp::now();
        $this->severity = 'warning';
    }

    public function getEventId(): string
    {
        return "boundary_timeout_{$this->boundaryName}_{$this->occurredAt->toFloat()}";
    }

    public function shouldAlert(): bool
    {
        return true; // Timeouts indicate performance issues
    }

    public function toArray(): array
    {
        return [
            'event_id' => $this->getEventId(),
            'event_type' => $this->eventType,
            'boundary_name' => $this->boundaryName,
            'timeout_threshold_ms' => $this->timeoutThreshold->toMilliseconds(),
            'timeout_threshold_human' => $this->timeoutThreshold->toHumanReadable(),
            'actual_execution_time_ms' => $this->actualExecutionTime->toMilliseconds(),
            'actual_execution_time_human' => $this->actualExecutionTime->toHumanReadable(),
            'exceeded_by_ms' => $this->actualExecutionTime->diff($this->timeoutThreshold)->toMilliseconds(),
            'fallback_executed' => $this->fallbackExecuted,
            'message' => $this->message,
            'context' => $this->context,
            'occurred_at' => $this->occurredAt->toIsoString(),
            'severity' => $this->severity,
            'should_alert' => $this->shouldAlert(),
        ];
    }
}
