<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * Dependency Injection error codes
 *
 * Covers DI container operations, binding resolution, and lifecycle management
 */
enum DiErrorCode: string implements ErrorCode
{
    case BINDING_NOT_FOUND = 'DI001';
    case CIRCULAR_DEPENDENCY = 'DI002';
    case RESOLUTION_FAILED = 'DI003';
    case INVALID_BINDING = 'DI004';
    case SINGLETON_CONFLICT = 'DI005';

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

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

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

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

            self::BINDING_NOT_FOUND,
            self::INVALID_BINDING,
            self::SINGLETON_CONFLICT => ErrorSeverity::ERROR,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::BINDING_NOT_FOUND => 'DI binding not found for requested type',
            self::CIRCULAR_DEPENDENCY => 'Circular dependency detected',
            self::RESOLUTION_FAILED => 'Dependency resolution failed',
            self::INVALID_BINDING => 'Invalid binding configuration',
            self::SINGLETON_CONFLICT => 'Singleton instance conflict',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::BINDING_NOT_FOUND => 'Register binding in DI container',
            self::CIRCULAR_DEPENDENCY => 'Refactor dependencies to break circular reference',
            self::RESOLUTION_FAILED => 'Check dependency constructors and bindings',
            self::INVALID_BINDING => 'Fix binding configuration or implementation',
            self::SINGLETON_CONFLICT => 'Review singleton lifecycle management',
        };
    }

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

    public function getRetryAfterSeconds(): ?int
    {
        return null;
    }
}
