<?php

declare(strict_types=1);

namespace App\Framework\Design\Service;

use App\Framework\Design\Analyzer\ColorAnalysisResult;
use App\Framework\Design\ValueObjects\ColorFormat;
use App\Framework\Design\ValueObjects\CssColor;

/**
 * Analysiert Farben in Design Systemen
 */
final readonly class ColorAnalyzer
{
    public function analyzePalette(array $customProperties): object
    {
        $colors = [];
        $colorsByFormat = [];
        $errors = [];

        foreach ($customProperties as $property) {
            try {
                if ($property->hasValueType('color')) {
                    $color = $property->getValueAs('color');
                    $colors[] = $color;

                    $format = $color->format->value;
                    if (! isset($colorsByFormat[$format])) {
                        $colorsByFormat[$format] = [];
                    }
                    $colorsByFormat[$format][] = $color;
                }
            } catch (\Exception $e) {
                $errors[] = [
                    'property' => $property->name,
                    'error' => $e->getMessage(),
                ];
            }
        }

        return (object) [
            'totalColors' => count($colors),
            'colorsByFormat' => $colorsByFormat,
            'errors' => $errors,
        ];
    }

    public function calculateContrastRatio(CssColor $color1, CssColor $color2): float
    {
        // Simplified contrast ratio calculation
        // Black vs White = 21:1
        if ($color1->value === '#000000' && $color2->value === '#ffffff') {
            return 21.0;
        }

        // This is a simplified implementation
        return 4.5; // Default to WCAG AA minimum
    }

    public function isWcagCompliant(CssColor $foreground, CssColor $background, string $level): bool
    {
        $ratio = $this->calculateContrastRatio($foreground, $background);

        return match($level) {
            'AA' => $ratio >= 4.5,
            'AAA' => $ratio >= 7.0,
            default => false
        };
    }

    public function findAccessibilityIssues(array $customProperties): array
    {
        $issues = [];

        // Find potential low contrast issues
        foreach ($customProperties as $property) {
            if (str_contains($property->name, 'text') && $property->hasValueType('color')) {
                // Mock issue detection
                if ($property->value === '#9ca3af') {
                    $issues[] = [
                        'property' => $property->name,
                        'type' => 'low_contrast',
                        'severity' => 'warning',
                        'message' => 'Potential low contrast with white background',
                    ];
                }
            }
        }

        return $issues;
    }

    public function detectColorScheme(array $customProperties): string
    {
        $lightness = 0;
        $count = 0;

        foreach ($customProperties as $property) {
            if ($property->hasValueType('color')) {
                // Simple lightness detection based on hex values
                if (str_contains($property->name, 'bg') || str_contains($property->name, 'background')) {
                    if ($property->value === '#ffffff' || str_contains($property->value, 'f')) {
                        $lightness += 1;
                    } else {
                        $lightness -= 1;
                    }
                    $count++;
                }
            }
        }

        if ($count === 0) {
            return 'unknown';
        }

        return $lightness > 0 ? 'light' : 'dark';
    }

    public function convertToHsl(CssColor $color): CssColor
    {
        // Mock conversion
        return new CssColor('hsl(220, 91%, 60%)', ColorFormat::HSL);
    }

    public function convertToOklch(CssColor $color): CssColor
    {
        // Mock conversion
        return new CssColor('oklch(0.7 0.15 260)', ColorFormat::OKLCH);
    }

    public function generateColorHarmony(CssColor $baseColor, string $type): array
    {
        $colors = [$baseColor];

        switch ($type) {
            case 'complementary':
                $colors[] = new CssColor('#f56565', ColorFormat::HEX); // Mock complement

                break;
            case 'triadic':
                $colors[] = new CssColor('#10b981', ColorFormat::HEX);
                $colors[] = new CssColor('#f59e0b', ColorFormat::HEX);

                break;
        }

        return $colors;
    }

    public function analyzeColorDistribution(array $customProperties): array
    {
        $distribution = [];

        foreach ($customProperties as $property) {
            if ($property->hasValueType('color')) {
                // Simple color family detection
                if (str_contains($property->name, 'blue')) {
                    $distribution['blue'] = ($distribution['blue'] ?? 0) + 1;
                } elseif (str_contains($property->name, 'green')) {
                    $distribution['green'] = ($distribution['green'] ?? 0) + 1;
                } elseif (str_contains($property->name, 'red')) {
                    $distribution['red'] = ($distribution['red'] ?? 0) + 1;
                }
            }
        }

        return $distribution;
    }

    /**
     * Main analysis method used by DesignSystemAnalyzer
     */
    public function analyzeColors($parseResult): ColorAnalysisResult
    {
        $palette = $this->analyzePalette($parseResult->customProperties);
        $distribution = $this->analyzeColorDistribution($parseResult->customProperties);
        $accessibilityIssues = $this->findAccessibilityIssues($parseResult->customProperties);
        $namingViolations = $this->validateNamingConventions($parseResult->customProperties);
        $colorScheme = $this->detectColorScheme($parseResult->customProperties);

        // Find duplicate colors
        $duplicateColors = [];
        $colorValues = [];
        foreach ($parseResult->customProperties as $property) {
            if ($property->hasValueType('color')) {
                $value = $property->value;
                if (! isset($colorValues[$value])) {
                    $colorValues[$value] = [];
                }
                $colorValues[$value][] = $property->name;
            }
        }

        foreach ($colorValues as $value => $properties) {
            if (count($properties) > 1) {
                $duplicateColors[] = [
                    'value' => $value,
                    'properties' => $properties,
                    'potential_savings' => count($properties) - 1,
                ];
            }
        }

        // Create color palette structure
        $colorPalette = [
            'primary_colors' => array_slice($distribution['primary'] ?? [], 0, 5),
            'neutral_colors' => array_slice($distribution['neutral'] ?? [], 0, 8),
            'accent_colors' => array_slice($distribution['accent'] ?? [], 0, 3),
            'semantic_colors' => $distribution['semantic'] ?? [],
        ];

        // Create contrast analysis
        $contrastAnalysis = [];
        foreach ($accessibilityIssues as $issue) {
            $contrastAnalysis[] = [
                'foreground' => $issue['foreground'] ?? '',
                'background' => $issue['background'] ?? '',
                'contrast_ratio' => $issue['contrast_ratio'] ?? 1.0,
                'wcag_aa' => ($issue['contrast_ratio'] ?? 1.0) >= 4.5,
                'wcag_aaa' => ($issue['contrast_ratio'] ?? 1.0) >= 7.0,
            ];
        }

        $recommendations = [];
        if (count($duplicateColors) > 0) {
            $recommendations[] = 'Remove duplicate color values to reduce CSS size';
        }
        if (count($namingViolations) > 0) {
            $recommendations[] = 'Improve color naming conventions for better maintainability';
        }
        if (count($palette->colorsByFormat) > 3) {
            $recommendations[] = 'Standardize color formats for consistency';
        }

        return new ColorAnalysisResult(
            totalColors: $palette->totalColors,
            colorsByFormat: $palette->colorsByFormat,
            colorPalette: $colorPalette,
            contrastAnalysis: $contrastAnalysis,
            duplicateColors: $duplicateColors,
            recommendations: $recommendations
        );
    }

    public function validateNamingConventions(array $customProperties): array
    {
        $violations = [];

        foreach ($customProperties as $property) {
            if ($property->hasValueType('color')) {
                // Check for poor naming
                if (preg_match('/^(color\d+|randomColorName)$/', $property->name)) {
                    $violations[] = [
                        'property' => $property->name,
                        'issue' => 'Non-semantic color name',
                    ];
                }
            }
        }

        return $violations;
    }
}
