<?php

declare(strict_types=1);

use App\Framework\Exception\Core\ErrorSeverity;

describe('ErrorSeverity', function () {
    describe('Retention Policies', function () {
        it('provides retention days for critical errors', function () {
            expect(ErrorSeverity::CRITICAL->getRetentionDays())->toBe(365); // 1 year for critical errors
        });

        it('provides retention days for error level', function () {
            expect(ErrorSeverity::ERROR->getRetentionDays())->toBe(90);
        });

        it('provides retention days for warnings', function () {
            expect(ErrorSeverity::WARNING->getRetentionDays())->toBe(30);
        });

        it('provides retention days for notice level', function () {
            expect(ErrorSeverity::NOTICE->getRetentionDays())->toBe(14); // 2 weeks for notices
        });

        it('provides retention days for info', function () {
            expect(ErrorSeverity::INFO->getRetentionDays())->toBe(7); // 1 week for info
        });

        it('provides retention days for debug', function () {
            expect(ErrorSeverity::DEBUG->getRetentionDays())->toBe(1); // 1 day for debug
        });

        it('retention days decrease with severity', function () {
            $critical = ErrorSeverity::CRITICAL->getRetentionDays();
            $error = ErrorSeverity::ERROR->getRetentionDays();
            $warning = ErrorSeverity::WARNING->getRetentionDays();
            $notice = ErrorSeverity::NOTICE->getRetentionDays();
            $info = ErrorSeverity::INFO->getRetentionDays();
            $debug = ErrorSeverity::DEBUG->getRetentionDays();

            expect($critical)->toBeGreaterThan($error);
            expect($error)->toBeGreaterThan($warning);
            expect($warning)->toBeGreaterThan($notice);
            expect($notice)->toBeGreaterThan($info);
            expect($info)->toBeGreaterThan($debug);
        });
    });

    describe('Alert Configuration', function () {
        it('critical errors should trigger alerts', function () {
            expect(ErrorSeverity::CRITICAL->shouldAlert())->toBeTrue();
        });

        it('error level should trigger alerts', function () {
            expect(ErrorSeverity::ERROR->shouldAlert())->toBeTrue();
        });

        it('warnings should not trigger alerts', function () {
            expect(ErrorSeverity::WARNING->shouldAlert())->toBeFalse();
        });

        it('notice should not trigger alerts', function () {
            expect(ErrorSeverity::NOTICE->shouldAlert())->toBeFalse();
        });

        it('info should not trigger alerts', function () {
            expect(ErrorSeverity::INFO->shouldAlert())->toBeFalse();
        });

        it('debug should not trigger alerts', function () {
            expect(ErrorSeverity::DEBUG->shouldAlert())->toBeFalse();
        });
    });

    describe('Alert Priority', function () {
        it('critical has urgent priority', function () {
            expect(ErrorSeverity::CRITICAL->getAlertPriority())->toBe('URGENT');
        });

        it('error has high priority', function () {
            expect(ErrorSeverity::ERROR->getAlertPriority())->toBe('HIGH');
        });

        it('warning has medium priority', function () {
            expect(ErrorSeverity::WARNING->getAlertPriority())->toBe('MEDIUM');
        });

        it('notice has low priority', function () {
            expect(ErrorSeverity::NOTICE->getAlertPriority())->toBe('LOW');
        });

        it('info has no alert priority', function () {
            expect(ErrorSeverity::INFO->getAlertPriority())->toBeNull();
        });

        it('debug has no alert priority', function () {
            expect(ErrorSeverity::DEBUG->getAlertPriority())->toBeNull();
        });
    });

    describe('Response Time SLA', function () {
        it('critical requires 15 minute response', function () {
            expect(ErrorSeverity::CRITICAL->getRecommendedResponseTime())->toBe(15);
        });

        it('error requires 1 hour response', function () {
            expect(ErrorSeverity::ERROR->getRecommendedResponseTime())->toBe(60);
        });

        it('warning requires 4 hour response', function () {
            expect(ErrorSeverity::WARNING->getRecommendedResponseTime())->toBe(240);
        });

        it('notice has no response time requirement', function () {
            expect(ErrorSeverity::NOTICE->getRecommendedResponseTime())->toBeNull();
        });

        it('info has no response time requirement', function () {
            expect(ErrorSeverity::INFO->getRecommendedResponseTime())->toBeNull();
        });

        it('debug has no response time requirement', function () {
            expect(ErrorSeverity::DEBUG->getRecommendedResponseTime())->toBeNull();
        });
    });

    describe('UI Display', function () {
        it('provides consistent color coding', function () {
            expect(ErrorSeverity::CRITICAL->getColor())->toBe('#DC2626'); // Red-600
            expect(ErrorSeverity::ERROR->getColor())->toBe('#F59E0B'); // Amber-500
            expect(ErrorSeverity::WARNING->getColor())->toBe('#FBBF24'); // Yellow-400
            expect(ErrorSeverity::NOTICE->getColor())->toBe('#10B981'); // Green-500
            expect(ErrorSeverity::INFO->getColor())->toBe('#3B82F6'); // Blue-500
            expect(ErrorSeverity::DEBUG->getColor())->toBe('#6B7280'); // Gray-500
        });

        it('provides icon names for display', function () {
            expect(ErrorSeverity::CRITICAL->getIcon())->toBe('exclamation-triangle');
            expect(ErrorSeverity::ERROR->getIcon())->toBe('exclamation-circle');
            expect(ErrorSeverity::WARNING->getIcon())->toBe('exclamation');
            expect(ErrorSeverity::NOTICE->getIcon())->toBe('bell');
            expect(ErrorSeverity::INFO->getIcon())->toBe('information-circle');
            expect(ErrorSeverity::DEBUG->getIcon())->toBe('bug');
        });
    });

    describe('Comparison', function () {
        it('compares severity levels', function () {
            expect(ErrorSeverity::CRITICAL->isHigherThan(ErrorSeverity::ERROR))->toBeTrue();
            expect(ErrorSeverity::ERROR->isHigherThan(ErrorSeverity::WARNING))->toBeTrue();
            expect(ErrorSeverity::WARNING->isHigherThan(ErrorSeverity::NOTICE))->toBeTrue();
            expect(ErrorSeverity::NOTICE->isHigherThan(ErrorSeverity::INFO))->toBeTrue();
            expect(ErrorSeverity::INFO->isHigherThan(ErrorSeverity::DEBUG))->toBeTrue();
        });

        it('compares equal severities', function () {
            expect(ErrorSeverity::ERROR->isHigherThan(ErrorSeverity::ERROR))->toBeFalse();
            expect(ErrorSeverity::WARNING->isHigherThan(ErrorSeverity::WARNING))->toBeFalse();
        });

        it('reverse comparison works', function () {
            expect(ErrorSeverity::DEBUG->isHigherThan(ErrorSeverity::CRITICAL))->toBeFalse();
            expect(ErrorSeverity::INFO->isHigherThan(ErrorSeverity::ERROR))->toBeFalse();
        });
    });

    describe('Log Level Mapping', function () {
        it('maps to PSR-3 log levels', function () {
            expect(ErrorSeverity::CRITICAL->toLogLevel())->toBe('critical');
            expect(ErrorSeverity::ERROR->toLogLevel())->toBe('error');
            expect(ErrorSeverity::WARNING->toLogLevel())->toBe('warning');
            expect(ErrorSeverity::NOTICE->toLogLevel())->toBe('notice');
            expect(ErrorSeverity::INFO->toLogLevel())->toBe('info');
            expect(ErrorSeverity::DEBUG->toLogLevel())->toBe('debug');
        });
    });

    describe('Integration Scenarios', function () {
        it('supports log retention cleanup strategy', function () {
            $severities = [
                ErrorSeverity::CRITICAL,
                ErrorSeverity::ERROR,
                ErrorSeverity::WARNING,
                ErrorSeverity::NOTICE,
                ErrorSeverity::INFO,
                ErrorSeverity::DEBUG
            ];

            foreach ($severities as $severity) {
                $retentionDays = $severity->getRetentionDays();
                expect($retentionDays)->toBeGreaterThan(0);
            }
        });

        it('supports alerting configuration', function () {
            $alertableSeverities = [
                ErrorSeverity::CRITICAL,
                ErrorSeverity::ERROR
            ];

            foreach ($alertableSeverities as $severity) {
                expect($severity->shouldAlert())->toBeTrue();
                expect($severity->getAlertPriority())->not->toBeNull();
                expect($severity->getRecommendedResponseTime())->not->toBeNull();
            }
        });

        it('supports UI error display', function () {
            $allSeverities = [
                ErrorSeverity::CRITICAL,
                ErrorSeverity::ERROR,
                ErrorSeverity::WARNING,
                ErrorSeverity::NOTICE,
                ErrorSeverity::INFO,
                ErrorSeverity::DEBUG
            ];

            foreach ($allSeverities as $severity) {
                expect($severity->getColor())->toBeString();
                expect($severity->getIcon())->toBeString();
                expect($severity->toLogLevel())->toBeString();
            }
        });
    });
});
