<?php

declare(strict_types=1);

namespace App\Framework\Design\Analyzer;

/**
 * Ergebnis der Convention-Prüfung
 */
final readonly class ConventionCheckResult
{
    public function __construct(
        public int $overallScore,
        public array $categoryScores,
        public array $violations,
        public array $recommendations,
        public string $conformanceLevel
    ) {
    }

    /**
     * Gruppiert Violations nach Schweregrad
     * @return array<string, array<int, array<string, mixed>>>
     */
    public function getViolationsBySeverity(): array
    {
        $grouped = [
            'high' => [],
            'medium' => [],
            'low' => [],
        ];

        foreach ($this->violations as $violation) {
            $severity = $violation['severity'] ?? 'low';
            $grouped[$severity][] = $violation;
        }

        return $grouped;
    }

    /**
     * Gibt die schlimmsten Problembereiche zurück
     * @return array<string, int|float>
     */
    public function getWorstAreas(): array
    {
        $sortedScores = $this->categoryScores;
        asort($sortedScores);

        return array_slice($sortedScores, 0, 3, true);
    }

    /**
     * Gibt die besten Bereiche zurück
     * @return array<string, int|float>
     */
    public function getBestAreas(): array
    {
        $sortedScores = $this->categoryScores;
        arsort($sortedScores);

        return array_slice($sortedScores, 0, 3, true);
    }

    /**
     * Gibt priorisierte Action Items zurück
     * @return array<int, array<string, string>>
     */
    public function getPrioritizedActions(): array
    {
        $actions = [];
        $violationsBySeverity = $this->getViolationsBySeverity();

        // High-Priority Violations zuerst
        foreach ($violationsBySeverity['high'] as $violation) {
            $actions[] = [
                'priority' => 'high',
                'category' => $violation['type'],
                'action' => $violation['suggestion'],
                'impact' => 'accessibility_maintainability',
            ];
        }

        // Medium-Priority basierend auf schlechtesten Scores
        $worstAreas = $this->getWorstAreas();
        foreach ($worstAreas as $area => $score) {
            if ($score < 70) {
                $actions[] = [
                    'priority' => 'medium',
                    'category' => $area,
                    'action' => $this->getAreaImprovementAction($area),
                    'impact' => 'code_quality',
                ];
            }
        }

        return $actions;
    }

    /**
     * Berechnet Verbesserungs-Potenzial
     * @return array<string, array<string, int|float>>
     */
    public function getImprovementPotential(): array
    {
        $potential = [];

        foreach ($this->categoryScores as $category => $score) {
            $maxImprovement = 100 - $score;
            $effort = $this->getEstimatedEffort($category, $score);

            $potential[$category] = [
                'current_score' => $score,
                'max_improvement' => $maxImprovement,
                'estimated_effort' => $effort,
                'roi_score' => $maxImprovement / max(1, $effort), // Return on Investment
            ];
        }

        // Sortiere nach ROI
        uasort($potential, fn ($a, $b) => $b['roi_score'] <=> $a['roi_score']);

        return $potential;
    }

    /**
     * Konvertiert zu Array für Export
     * @return array<string, mixed>
     */
    public function toArray(): array
    {
        return [
            'overall_score' => $this->overallScore,
            'conformance_level' => $this->conformanceLevel,
            'category_scores' => $this->categoryScores,
            'violations' => $this->violations,
            'violations_by_severity' => $this->getViolationsBySeverity(),
            'recommendations' => $this->recommendations,
            'worst_areas' => $this->getWorstAreas(),
            'best_areas' => $this->getBestAreas(),
            'prioritized_actions' => $this->getPrioritizedActions(),
            'improvement_potential' => $this->getImprovementPotential(),
        ];
    }

    /**
     * Gibt bereichsspezifische Verbesserungs-Actions
     */
    private function getAreaImprovementAction(string $area): string
    {
        return match($area) {
            'naming' => 'Standardize naming conventions across all CSS classes',
            'specificity' => 'Refactor high-specificity selectors and reduce !important usage',
            'organization' => 'Reorganize CSS properties within rules for better readability',
            'custom_properties' => 'Review and improve custom property naming and organization',
            'accessibility' => 'Add missing focus styles and improve keyboard navigation support',
            default => "Improve {$area} conventions and standards"
        };
    }

    /**
     * Schätzt Aufwand für Verbesserungen
     */
    private function getEstimatedEffort(string $category, int|float $score): int
    {
        $baseEffort = match($category) {
            'naming' => 3, // Moderate effort - mostly renaming
            'specificity' => 4, // Higher effort - requires structural changes
            'organization' => 2, // Lower effort - mostly reordering
            'custom_properties' => 2, // Lower effort - renaming and reorganization
            'accessibility' => 3, // Moderate effort - adding new styles
            default => 3
        };

        // Adjust based on how bad the score is
        $severityMultiplier = match(true) {
            $score >= 80 => 0.5,
            $score >= 60 => 1.0,
            $score >= 40 => 1.5,
            default => 2.0
        };

        return (int) ceil($baseEffort * $severityMultiplier);
    }
}
