<?php

declare(strict_types=1);

namespace App\Framework\CircuitBreaker;

use App\Framework\Exception\ErrorCode;
use App\Framework\Exception\ExceptionContext;
use App\Framework\Exception\FrameworkException;

/**
 * Exception thrown when Circuit Breaker is in OPEN state
 */
final class CircuitBreakerException extends FrameworkException
{
    public function __construct(
        public readonly string $service,
        public readonly CircuitState $state,
        public readonly int $failureCount,
        public readonly int $retryAfterSeconds,
        ?\Throwable $previous = null
    ) {
        $message = "Circuit breaker for service '{$service}' is {$state->value}. Service unavailable after {$failureCount} failures.";

        $context = new ExceptionContext(
            operation: 'circuit_breaker_check',
            component: 'CircuitBreaker',
            data: [
                'service' => $service,
                'state' => $state->value,
                'failure_count' => $failureCount,
                'retry_after_seconds' => $retryAfterSeconds,
            ],
            metadata: [
                'requires_alert' => true,
                'recoverable' => true,
                'error_code' => ErrorCode::SERVICE_CIRCUIT_OPEN->value,
                'http_status' => 503,
                'additional_headers' => [
                    'Retry-After' => (string) $retryAfterSeconds,
                ],
            ]
        );

        parent::__construct(
            message: $message,
            context: $context,
            code: 503,
            previous: $previous,
            errorCode: ErrorCode::SERVICE_CIRCUIT_OPEN,
            retryAfter: $retryAfterSeconds
        );
    }
}
