<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * Event error codes
 *
 * Covers event dispatching, handler execution, and event bus operations
 */
enum EventErrorCode: string implements ErrorCode
{
    case HANDLER_NOT_FOUND = 'EVENT001';
    case DISPATCH_FAILED = 'EVENT002';
    case HANDLER_EXECUTION_FAILED = 'EVENT003';
    case INVALID_EVENT = 'EVENT004';
    case EVENT_BUS_UNAVAILABLE = 'EVENT005';

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

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

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

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

            self::DISPATCH_FAILED,
            self::HANDLER_EXECUTION_FAILED => ErrorSeverity::ERROR,

            self::HANDLER_NOT_FOUND,
            self::INVALID_EVENT => ErrorSeverity::WARNING,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::HANDLER_NOT_FOUND => 'Event handler not found',
            self::DISPATCH_FAILED => 'Event dispatch operation failed',
            self::HANDLER_EXECUTION_FAILED => 'Event handler execution failed',
            self::INVALID_EVENT => 'Invalid event object or structure',
            self::EVENT_BUS_UNAVAILABLE => 'Event bus is unavailable',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::HANDLER_NOT_FOUND => 'Register event handler or check event name',
            self::DISPATCH_FAILED => 'Check event bus connection and retry',
            self::HANDLER_EXECUTION_FAILED => 'Review handler logs and fix underlying issue',
            self::INVALID_EVENT => 'Validate event structure and required properties',
            self::EVENT_BUS_UNAVAILABLE => 'Check event bus service and configuration',
        };
    }

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

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