<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

use App\Framework\Exception\ErrorCode;

/**
 * Search error codes
 *
 * Covers search engine operations, indexing, and query processing
 */
enum SearchErrorCode: string implements ErrorCode
{
    case INDEX_NOT_FOUND = 'SEARCH001';
    case QUERY_FAILED = 'SEARCH002';
    case INDEXING_FAILED = 'SEARCH003';
    case ENGINE_UNAVAILABLE = 'SEARCH004';
    case INVALID_QUERY_SYNTAX = 'SEARCH005';

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

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

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

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

            self::QUERY_FAILED,
            self::INDEXING_FAILED => ErrorSeverity::ERROR,

            self::INDEX_NOT_FOUND,
            self::INVALID_QUERY_SYNTAX => ErrorSeverity::WARNING,
        };
    }

    public function getDescription(): string
    {
        return match($this) {
            self::INDEX_NOT_FOUND => 'Search index not found',
            self::QUERY_FAILED => 'Search query execution failed',
            self::INDEXING_FAILED => 'Document indexing failed',
            self::ENGINE_UNAVAILABLE => 'Search engine is unavailable',
            self::INVALID_QUERY_SYNTAX => 'Search query syntax is invalid',
        };
    }

    public function getRecoveryHint(): string
    {
        return match($this) {
            self::INDEX_NOT_FOUND => 'Create or rebuild search index',
            self::QUERY_FAILED => 'Review query syntax and retry',
            self::INDEXING_FAILED => 'Check document format and retry indexing',
            self::ENGINE_UNAVAILABLE => 'Check search engine status and configuration',
            self::INVALID_QUERY_SYNTAX => 'Correct query syntax according to documentation',
        };
    }

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

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