<?php

declare(strict_types=1);

namespace App\Framework\Exception\Core;

/**
 * Error severity levels with retention policies and alert behavior
 *
 * Defines severity classification for exceptions with automatic retention
 * policies and alert triggering behavior.
 *
 * Severity Levels:
 * - CRITICAL: System failures, data corruption, security breaches (365 days retention)
 * - ERROR: Operation failures, validation errors, resource issues (90 days retention)
 * - WARNING: Potential issues, degraded performance (30 days retention)
 * - NOTICE: Notification of non-critical conditions (14 days retention)
 * - INFO: Informational events (7 days retention)
 * - DEBUG: Debugging information (1 day retention)
 */
enum ErrorSeverity: string
{
    case CRITICAL = 'critical';
    case ERROR = 'error';
    case WARNING = 'warning';
    case NOTICE = 'notice';
    case INFO = 'info';
    case DEBUG = 'debug';

    /**
     * Get retention period in days for this severity level
     *
     * Data retention based on severity:
     * - CRITICAL: 365 days (1 year) - Critical errors require long-term analysis
     * - ERROR: 90 days (3 months) - Standard error retention
     * - WARNING: 30 days (1 month) - Warning-level issues
     * - NOTICE: 14 days (2 weeks) - Notice-level events
     * - INFO: 7 days (1 week) - Informational events
     * - DEBUG: 1 day - Debug information only needed short-term
     */
    public function getRetentionDays(): int
    {
        return match ($this) {
            self::CRITICAL => 365,
            self::ERROR => 90,
            self::WARNING => 30,
            self::NOTICE => 14,
            self::INFO => 7,
            self::DEBUG => 1,
        };
    }

    /**
     * Check if this severity level should trigger alerts
     *
     * Only CRITICAL and ERROR severities trigger automatic alerts
     */
    public function shouldAlert(): bool
    {
        return match ($this) {
            self::CRITICAL, self::ERROR => true,
            default => false,
        };
    }

    /**
     * Get alert priority for this severity level
     *
     * Returns:
     * - URGENT: For CRITICAL errors (immediate attention required)
     * - HIGH: For ERROR level (attention required soon)
     * - MEDIUM: For WARNING level (review when convenient)
     * - LOW: For NOTICE level (review when convenient)
     * - null: For INFO and DEBUG (no alerting)
     */
    public function getAlertPriority(): ?string
    {
        return match ($this) {
            self::CRITICAL => 'URGENT',
            self::ERROR => 'HIGH',
            self::WARNING => 'MEDIUM',
            self::NOTICE => 'LOW',
            default => null,
        };
    }

    /**
     * Get numeric weight for severity comparison
     *
     * Higher weight = more severe
     * Useful for sorting and filtering by severity
     */
    public function getWeight(): int
    {
        return match ($this) {
            self::CRITICAL => 6,
            self::ERROR => 5,
            self::WARNING => 4,
            self::NOTICE => 3,
            self::INFO => 2,
            self::DEBUG => 1,
        };
    }

    /**
     * Check if this severity is more severe than another
     */
    public function isMoreSevereThan(self $other): bool
    {
        return $this->getWeight() > $other->getWeight();
    }

    /**
     * Check if this severity is less severe than another
     */
    public function isLessSevereThan(self $other): bool
    {
        return $this->getWeight() < $other->getWeight();
    }

    /**
     * Check if this severity requires immediate action
     */
    public function requiresImmediateAction(): bool
    {
        return $this === self::CRITICAL;
    }

    /**
     * Get human-readable description of severity level
     */
    public function getDescription(): string
    {
        return match ($this) {
            self::CRITICAL => 'Critical - System failure or security breach requiring immediate action',
            self::ERROR => 'Error - Operation failure requiring attention',
            self::WARNING => 'Warning - Potential issue or degraded performance',
            self::NOTICE => 'Notice - Notification of non-critical condition',
            self::INFO => 'Info - Informational event',
            self::DEBUG => 'Debug - Debugging information',
        };
    }

    /**
     * Get color code for UI representation
     */
    public function getColorCode(): string
    {
        return match ($this) {
            self::CRITICAL => '#DC2626', // Red-600
            self::ERROR => '#F59E0B',    // Amber-500
            self::WARNING => '#FBBF24',  // Yellow-400
            self::NOTICE => '#10B981',   // Green-500
            self::INFO => '#3B82F6',     // Blue-500
            self::DEBUG => '#6B7280',    // Gray-500
        };
    }

    /**
     * Get recommended response time for this severity
     *
     * Returns time in minutes
     */
    public function getRecommendedResponseTime(): ?int
    {
        return match ($this) {
            self::CRITICAL => 15,    // 15 minutes
            self::ERROR => 60,       // 1 hour
            self::WARNING => 240,    // 4 hours
            default => null,         // No SLA for NOTICE/INFO/DEBUG
        };
    }

    /**
     * Get UI color code (alias for getColorCode for test compatibility)
     */
    public function getColor(): string
    {
        return $this->getColorCode();
    }

    /**
     * Get icon name for UI display
     */
    public function getIcon(): string
    {
        return match ($this) {
            self::CRITICAL => 'exclamation-triangle',
            self::ERROR => 'exclamation-circle',
            self::WARNING => 'exclamation',
            self::NOTICE => 'bell',
            self::INFO => 'information-circle',
            self::DEBUG => 'bug',
        };
    }

    /**
     * Compare severity levels (alias for isMoreSevereThan for test compatibility)
     */
    public function isHigherThan(self $other): bool
    {
        return $this->isMoreSevereThan($other);
    }

    /**
     * Map to PSR-3 log level
     */
    public function toLogLevel(): string
    {
        return $this->value;
    }
}
