<?php

declare(strict_types=1);

use App\Framework\Design\Service\ColorAnalyzer;
use App\Framework\Design\ValueObjects\ColorFormat;
use App\Framework\Design\ValueObjects\CssColor;
use App\Framework\Design\ValueObjects\CustomProperty;

describe('ColorAnalyzer', function () {

    beforeEach(function () {
        $this->analyzer = new ColorAnalyzer();
    });

    it('analyzes color palette from custom properties', function () {
        $customProperties = [
            new CustomProperty('primary-color', '#3b82f6'),
            new CustomProperty('secondary-color', 'oklch(0.7 0.15 260)'),
            new CustomProperty('text-color', '#1f2937'),
            new CustomProperty('bg-color', '#ffffff'),
            new CustomProperty('accent-color', 'hsl(200, 100%, 50%)'),
        ];

        $analysis = $this->analyzer->analyzePalette($customProperties);

        expect($analysis->totalColors)->toBe(5);
        expect($analysis->colorsByFormat)->toHaveKey(ColorFormat::HEX->value);
        expect($analysis->colorsByFormat)->toHaveKey(ColorFormat::OKLCH->value);
        expect($analysis->colorsByFormat)->toHaveKey(ColorFormat::HSL->value);

        expect($analysis->colorsByFormat[ColorFormat::HEX->value])->toHaveCount(3);
        expect($analysis->colorsByFormat[ColorFormat::OKLCH->value])->toHaveCount(1);
        expect($analysis->colorsByFormat[ColorFormat::HSL->value])->toHaveCount(1);
    });

    it('calculates contrast ratios correctly', function () {
        $color1 = new CssColor('#000000', ColorFormat::HEX); // Black
        $color2 = new CssColor('#ffffff', ColorFormat::HEX); // White

        $contrastRatio = $this->analyzer->calculateContrastRatio($color1, $color2);

        expect($contrastRatio)->toBeCloseTo(21.0, 1); // Perfect contrast
    });

    it('checks WCAG AA compliance', function () {
        $darkBlue = new CssColor('#1f2937', ColorFormat::HEX);
        $white = new CssColor('#ffffff', ColorFormat::HEX);

        $isCompliant = $this->analyzer->isWcagCompliant($darkBlue, $white, 'AA');

        expect($isCompliant)->toBeTrue();
    });

    it('checks WCAG AAA compliance', function () {
        $lightGray = new CssColor('#9ca3af', ColorFormat::HEX);
        $white = new CssColor('#ffffff', ColorFormat::HEX);

        $isCompliant = $this->analyzer->isWcagCompliant($lightGray, $white, 'AAA');

        expect($isCompliant)->toBeFalse(); // Light gray on white fails AAA
    });

    it('identifies accessibility issues', function () {
        $customProperties = [
            new CustomProperty('text-color', '#9ca3af'),     // Light gray
            new CustomProperty('bg-color', '#ffffff'),        // White
            new CustomProperty('link-color', '#60a5fa'),      // Light blue
        ];

        $issues = $this->analyzer->findAccessibilityIssues($customProperties);

        expect($issues)->not->toBeEmpty();
        expect($issues[0]['severity'])->toBe('warning');
        expect($issues[0]['type'])->toBe('low_contrast');
    });

    it('detects color scheme type', function () {
        // Light theme colors
        $lightProperties = [
            new CustomProperty('bg-color', '#ffffff'),
            new CustomProperty('text-color', '#1f2937'),
            new CustomProperty('border-color', '#e5e7eb'),
        ];

        $scheme = $this->analyzer->detectColorScheme($lightProperties);

        expect($scheme)->toBe('light');

        // Dark theme colors
        $darkProperties = [
            new CustomProperty('bg-color', '#1f2937'),
            new CustomProperty('text-color', '#f9fafb'),
            new CustomProperty('border-color', '#374151'),
        ];

        $scheme = $this->analyzer->detectColorScheme($darkProperties);

        expect($scheme)->toBe('dark');
    });

    it('converts colors between formats', function () {
        $hexColor = new CssColor('#3b82f6', ColorFormat::HEX);

        $hslColor = $this->analyzer->convertToHsl($hexColor);
        $oklchColor = $this->analyzer->convertToOklch($hexColor);

        expect($hslColor->format)->toBe(ColorFormat::HSL);
        expect($oklchColor->format)->toBe(ColorFormat::OKLCH);
        expect($hslColor->value)->toContain('hsl(');
        expect($oklchColor->value)->toContain('oklch(');
    });

    it('generates color harmony suggestions', function () {
        $baseColor = new CssColor('#3b82f6', ColorFormat::HEX);

        $harmony = $this->analyzer->generateColorHarmony($baseColor, 'complementary');

        expect($harmony)->toHaveCount(2); // Base + complement
        expect($harmony[0])->toEqual($baseColor);
        expect($harmony[1])->not->toEqual($baseColor);

        $triadic = $this->analyzer->generateColorHarmony($baseColor, 'triadic');
        expect($triadic)->toHaveCount(3); // Base + two triadic colors
    });

    it('analyzes color distribution', function () {
        $customProperties = [
            new CustomProperty('primary-blue', '#3b82f6'),
            new CustomProperty('primary-blue-light', '#60a5fa'),
            new CustomProperty('primary-blue-dark', '#1d4ed8'),
            new CustomProperty('secondary-green', '#10b981'),
            new CustomProperty('accent-red', '#ef4444'),
        ];

        $distribution = $this->analyzer->analyzeColorDistribution($customProperties);

        expect($distribution['blue'])->toBe(3);
        expect($distribution['green'])->toBe(1);
        expect($distribution['red'])->toBe(1);
    });

    it('validates color naming conventions', function () {
        $customProperties = [
            new CustomProperty('primary-color', '#3b82f6'),      // Good
            new CustomProperty('color1', '#60a5fa'),             // Bad
            new CustomProperty('blue-500', '#1d4ed8'),           // Good (design system)
            new CustomProperty('randomColorName', '#10b981'),    // Bad
        ];

        $violations = $this->analyzer->validateNamingConventions($customProperties);

        expect($violations)->toHaveCount(2);
        expect($violations[0]['property'])->toBe('color1');
        expect($violations[1]['property'])->toBe('randomColorName');
    });

    it('handles invalid color values gracefully', function () {
        $customProperties = [
            new CustomProperty('invalid-color', 'not-a-color'),
            new CustomProperty('another-invalid', 'rgba(999, 999, 999, 2)'),
        ];

        $analysis = $this->analyzer->analyzePalette($customProperties);

        expect($analysis->totalColors)->toBe(0);
        expect($analysis->errors)->toHaveCount(2);
    });
});
