<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * Console error codes
 *
 * Covers console command execution, argument parsing, and CLI operations
 */
enum ConsoleErrorCode: string implements ErrorCode
{
    case COMMAND_NOT_FOUND = 'CON001';
    case INVALID_ARGUMENT = 'CON002';
    case EXECUTION_FAILED = 'CON003';
    case MISSING_REQUIRED_ARGUMENT = 'CON004';
    case INVALID_OPTION = 'CON005';
    case COMMAND_TIMEOUT = 'CON006';
    case PERMISSION_DENIED = 'CON007';
    case OUTPUT_WRITE_FAILED = 'CON008';
    case INVALID_COMMAND_STRUCTURE = 'CON009';

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

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

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

    public function getSeverity(): ErrorSeverity
    {
        return match($this) {
            self::EXECUTION_FAILED,
            self::PERMISSION_DENIED,
            self::INVALID_COMMAND_STRUCTURE => ErrorSeverity::ERROR,

            self::COMMAND_NOT_FOUND,
            self::INVALID_ARGUMENT,
            self::MISSING_REQUIRED_ARGUMENT,
            self::INVALID_OPTION,
            self::COMMAND_TIMEOUT,
            self::OUTPUT_WRITE_FAILED => ErrorSeverity::WARNING,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::COMMAND_NOT_FOUND => 'Console command not found',
            self::INVALID_ARGUMENT => 'Invalid command argument provided',
            self::EXECUTION_FAILED => 'Command execution failed',
            self::MISSING_REQUIRED_ARGUMENT => 'Required command argument is missing',
            self::INVALID_OPTION => 'Invalid command option provided',
            self::COMMAND_TIMEOUT => 'Command execution timed out',
            self::PERMISSION_DENIED => 'Insufficient permissions to execute command',
            self::OUTPUT_WRITE_FAILED => 'Failed to write command output',
            self::INVALID_COMMAND_STRUCTURE => 'Command has invalid structure or configuration',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::COMMAND_NOT_FOUND => 'Check command name and available commands list',
            self::INVALID_ARGUMENT => 'Provide valid argument according to command help',
            self::EXECUTION_FAILED => 'Check command logs and fix underlying issue',
            self::MISSING_REQUIRED_ARGUMENT => 'Provide all required arguments',
            self::INVALID_OPTION => 'Use valid options according to command help',
            self::COMMAND_TIMEOUT => 'Increase timeout or optimize command execution',
            self::PERMISSION_DENIED => 'Run command with appropriate permissions',
            self::OUTPUT_WRITE_FAILED => 'Check output stream and file permissions',
            self::INVALID_COMMAND_STRUCTURE => 'Verify command class structure and attribute configuration',
        };
    }

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

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