<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * Service error codes
 *
 * Covers service layer failures, business logic errors, and service communication
 */
enum ServiceErrorCode: string implements ErrorCode
{
    case SERVICE_UNAVAILABLE = 'SVC001';
    case OPERATION_FAILED = 'SVC002';
    case TIMEOUT = 'SVC003';
    case CIRCUIT_BREAKER_OPEN = 'SVC004';

    public function getValue(): string
    {
        return $this->value;
    }

    public function getCategory(): string
    {
        return 'SVC';
    }

    public function getNumericCode(): int
    {
        return (int) substr($this->value, -3);
    }

    public function getSeverity(): ErrorSeverity
    {
        return match($this) {
            self::SERVICE_UNAVAILABLE => ErrorSeverity::CRITICAL,

            self::OPERATION_FAILED,
            self::TIMEOUT,
            self::CIRCUIT_BREAKER_OPEN => ErrorSeverity::ERROR,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::SERVICE_UNAVAILABLE => 'Service is unavailable',
            self::OPERATION_FAILED => 'Service operation failed',
            self::TIMEOUT => 'Service operation timed out',
            self::CIRCUIT_BREAKER_OPEN => 'Circuit breaker is open for this service',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::SERVICE_UNAVAILABLE => 'Check service health and retry later',
            self::OPERATION_FAILED => 'Review operation parameters and retry',
            self::TIMEOUT => 'Increase timeout or optimize operation',
            self::CIRCUIT_BREAKER_OPEN => 'Wait for circuit breaker reset or use fallback',
        };
    }

    public function isRecoverable(): bool
    {
        return true;
    }

    public function getRetryAfterSeconds(): ?int
    {
        return match($this) {
            self::SERVICE_UNAVAILABLE => 60,
            self::TIMEOUT => 30,
            self::CIRCUIT_BREAKER_OPEN => 120,
            default => null,
        };
    }
}
