<?php

declare(strict_types=1);

namespace App\Framework\ErrorBoundaries\Events;

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

/**
 * Event fired when boundary execution fails
 */
final readonly class BoundaryExecutionFailed implements BoundaryEventInterface
{
    public readonly string $eventType;

    public readonly Timestamp $occurredAt;

    public readonly string $severity;

    public function __construct(
        public string $boundaryName,
        public Throwable $exception,
        public Duration $executionTime,
        public bool $willRetry = false,
        public ?string $message = null,
        public array $context = [],
    ) {
        $this->eventType = 'boundary.execution.failed';
        $this->occurredAt = Timestamp::now();
        $this->severity = $willRetry ? 'warning' : 'error';
    }

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

    public function shouldAlert(): bool
    {
        return ! $this->willRetry; // Alert on final failures, not retries
    }

    public function toArray(): array
    {
        return [
            'event_id' => $this->getEventId(),
            'event_type' => $this->eventType,
            'boundary_name' => $this->boundaryName,
            'exception_class' => $this->exception::class,
            'exception_message' => $this->exception->getMessage(),
            'exception_file' => $this->exception->getFile(),
            'exception_line' => $this->exception->getLine(),
            'execution_time_ms' => $this->executionTime->toMilliseconds(),
            'execution_time_human' => $this->executionTime->toHumanReadable(),
            'will_retry' => $this->willRetry,
            'message' => $this->message,
            'context' => $this->context,
            'occurred_at' => $this->occurredAt->toIsoString(),
            'severity' => $this->severity,
            'should_alert' => $this->shouldAlert(),
        ];
    }
}
