<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * HTTP error codes
 *
 * Covers HTTP protocol errors, client/server errors, and network issues
 */
enum HttpErrorCode: string implements ErrorCode
{
    case BAD_REQUEST = 'HTTP001';
    case NOT_FOUND = 'HTTP002';
    case METHOD_NOT_ALLOWED = 'HTTP003';
    case RATE_LIMIT_EXCEEDED = 'HTTP004';
    case INTERNAL_SERVER_ERROR = 'HTTP005';

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

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

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

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

            self::RATE_LIMIT_EXCEEDED => ErrorSeverity::ERROR,

            self::BAD_REQUEST,
            self::NOT_FOUND,
            self::METHOD_NOT_ALLOWED => ErrorSeverity::WARNING,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::BAD_REQUEST => 'Request is malformed or invalid',
            self::NOT_FOUND => 'Requested resource not found',
            self::METHOD_NOT_ALLOWED => 'HTTP method not allowed for this resource',
            self::RATE_LIMIT_EXCEEDED => 'API rate limit exceeded',
            self::INTERNAL_SERVER_ERROR => 'Internal server error occurred',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::BAD_REQUEST => 'Check request format and parameters',
            self::NOT_FOUND => 'Verify resource URL and existence',
            self::METHOD_NOT_ALLOWED => 'Use correct HTTP method for this endpoint',
            self::RATE_LIMIT_EXCEEDED => 'Wait and retry after rate limit window',
            self::INTERNAL_SERVER_ERROR => 'Contact support or retry later',
        };
    }

    public function isRecoverable(): bool
    {
        return match($this) {
            self::INTERNAL_SERVER_ERROR => false,
            default => true,
        };
    }

    public function getRetryAfterSeconds(): ?int
    {
        return match($this) {
            self::RATE_LIMIT_EXCEEDED => 60,
            default => null,
        };
    }
}
