<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * Entity error codes
 *
 * Covers entity operations, persistence, and lifecycle management
 */
enum EntityErrorCode: string implements ErrorCode
{
    case ENTITY_NOT_FOUND = 'ENT001';
    case ENTITY_ALREADY_EXISTS = 'ENT002';
    case PERSISTENCE_FAILED = 'ENT003';
    case INVALID_ENTITY_STATE = 'ENT004';
    case VERSION_CONFLICT = 'ENT005';
    case DETACHED_ENTITY = 'ENT006';

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

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

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

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

            self::ENTITY_ALREADY_EXISTS,
            self::INVALID_ENTITY_STATE,
            self::VERSION_CONFLICT => ErrorSeverity::ERROR,

            self::ENTITY_NOT_FOUND,
            self::DETACHED_ENTITY => ErrorSeverity::WARNING,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::ENTITY_NOT_FOUND => 'Entity not found',
            self::ENTITY_ALREADY_EXISTS => 'Entity already exists',
            self::PERSISTENCE_FAILED => 'Entity persistence operation failed',
            self::INVALID_ENTITY_STATE => 'Entity is in invalid state',
            self::VERSION_CONFLICT => 'Entity version conflict detected',
            self::DETACHED_ENTITY => 'Operation on detached entity',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::ENTITY_NOT_FOUND => 'Verify entity identifier and existence',
            self::ENTITY_ALREADY_EXISTS => 'Use update operation or different identifier',
            self::PERSISTENCE_FAILED => 'Check database connection and constraints',
            self::INVALID_ENTITY_STATE => 'Validate entity state before operation',
            self::VERSION_CONFLICT => 'Reload entity and retry operation',
            self::DETACHED_ENTITY => 'Reattach entity to persistence context',
        };
    }

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

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