<?php

declare(strict_types=1);

use App\Framework\Design\Parser\ClassNameParser;
use App\Framework\Design\Parser\CssParser;
use App\Framework\Design\Parser\CustomPropertyParser;
use App\Framework\Design\Service\ColorAnalyzer;
use App\Framework\Design\Service\ComponentDetector;
use App\Framework\Design\Service\ConventionChecker;
use App\Framework\Design\Service\DesignSystemAnalyzer;
use App\Framework\Design\Service\TokenAnalyzer;

describe('DesignSystemAnalyzer', function () {

    beforeEach(function () {
        $this->customPropertyParser = new CustomPropertyParser();
        $this->classNameParser = new ClassNameParser();
        $this->cssParser = new CssParser($this->customPropertyParser, $this->classNameParser);
        $this->colorAnalyzer = new ColorAnalyzer();
        $this->tokenAnalyzer = new TokenAnalyzer();
        $this->componentDetector = new ComponentDetector();
        $this->conventionChecker = new ConventionChecker();

        $this->analyzer = new DesignSystemAnalyzer(
            $this->cssParser,
            $this->colorAnalyzer,
            $this->tokenAnalyzer,
            $this->componentDetector,
            $this->conventionChecker
        );
    });

    it('analyzes complete design system from CSS files', function () {
        $cssFiles = [
            '/test/tokens.css' => '
                :root {
                    --color-primary-500: #3b82f6;
                    --color-secondary-500: #6b7280;
                    --spacing-md: 1rem;
                    --font-size-base: 16px;
                    --border-radius-md: 0.375rem;
                }
            ',
            '/test/components.css' => '
                .button {
                    padding: var(--spacing-md);
                    border-radius: var(--border-radius-md);
                    background-color: var(--color-primary-500);
                }
                
                .button--secondary {
                    background-color: var(--color-secondary-500);
                }
                
                .card {
                    border-radius: var(--border-radius-md);
                    padding: calc(var(--spacing-md) * 2);
                }
                
                .card__header {
                    margin-bottom: var(--spacing-md);
                }
            ',
        ];

        $analysis = $this->analyzer->analyze($cssFiles);

        expect($analysis->designTokens)->not->toBeEmpty();
        expect($analysis->components)->not->toBeEmpty();
        expect($analysis->colorPalette)->not->toBeEmpty();
        expect($analysis->maturityScore)->toBeGreaterThan(0);
        expect($analysis->recommendations)->not->toBeEmpty();

        // Check token analysis
        expect($analysis->tokenAnalysis['categories'])->toHaveKey('color');
        expect($analysis->tokenAnalysis['categories'])->toHaveKey('spacing');
        expect($analysis->tokenAnalysis['categories'])->toHaveKey('typography');

        // Check component analysis
        expect($analysis->componentAnalysis['bem_components'])->toHaveCount(2); // button, card
        expect($analysis->componentAnalysis['bem_components'][0]['block'])->toBe('button');
        expect($analysis->componentAnalysis['bem_components'][1]['block'])->toBe('card');

        // Check color analysis
        expect($analysis->colorAnalysis['total_colors'])->toBe(2);
        expect($analysis->colorAnalysis['color_scheme'])->toBeIn(['light', 'dark', 'mixed']);
    });

    it('calculates design system maturity score', function () {
        // Mature design system
        $matureSystem = [
            '/test/tokens.css' => '
                :root {
                    /* Comprehensive color scale */
                    --color-primary-100: #dbeafe;
                    --color-primary-500: #3b82f6;
                    --color-primary-900: #1e3a8a;
                    
                    /* Consistent spacing scale */
                    --spacing-xs: 0.25rem;
                    --spacing-sm: 0.5rem;
                    --spacing-md: 1rem;
                    --spacing-lg: 1.5rem;
                    --spacing-xl: 2rem;
                    
                    /* Typography scale */
                    --font-size-sm: 0.875rem;
                    --font-size-base: 1rem;
                    --font-size-lg: 1.125rem;
                    --font-size-xl: 1.25rem;
                }
            ',
            '/test/components.css' => '
                .btn { /* BEM naming */ }
                .btn--primary { }
                .btn--secondary { }
                .btn__icon { }
                
                .card { }
                .card__header { }
                .card__body { }
                .card__footer { }
                
                .form { }
                .form__group { }
                .form__label { }
                .form__input { }
            ',
        ];

        $matureAnalysis = $this->analyzer->analyze($matureSystem);

        // Basic design system
        $basicSystem = [
            '/test/basic.css' => '
                :root {
                    --main-color: red;
                    --bg-color: white;
                }
                
                .redButton { color: red; }
                .blueDiv { background: blue; }
            ',
        ];

        $basicAnalysis = $this->analyzer->analyze($basicSystem);

        expect($matureAnalysis->maturityScore)->toBeGreaterThan($basicAnalysis->maturityScore);
        expect($matureAnalysis->maturityLevel)->toBeIn(['Developing', 'Established', 'Mature']);
        expect($basicAnalysis->maturityLevel)->toBeIn(['Basic', 'Emerging']);
    });

    it('identifies design system gaps and improvements', function () {
        $incompleteSystem = [
            '/test/gaps.css' => '
                :root {
                    --primary: #3b82f6;  /* Missing scale */
                    --big-space: 2rem;   /* Inconsistent naming */
                    --tiny: 2px;         /* Non-standard value */
                }
                
                .redButton { color: red; }    /* Presentational naming */
                .bigBox { size: large; }      /* Presentational naming */
                .card_header { }              /* Wrong BEM separator */
                .NAVIGATION { }               /* Wrong case */
            ',
        ];

        $analysis = $this->analyzer->analyze($incompleteSystem);

        expect($analysis->gaps)->not->toBeEmpty();
        expect($analysis->recommendations)->not->toBeEmpty();

        // Check for specific gap types
        $gapTypes = array_column($analysis->gaps, 'type');
        expect($gapTypes)->toContain('incomplete_color_scale');
        expect($gapTypes)->toContain('inconsistent_naming');
        expect($gapTypes)->toContain('non_standard_values');

        // Check recommendations
        $recommendationTexts = array_column($analysis->recommendations, 'text');
        expect($recommendationTexts)->toContainStrings([
            'naming convention',
            'color scale',
            'BEM',
        ]);
    });

    it('analyzes design system consistency', function () {
        $consistentSystem = [
            '/test/consistent.css' => '
                :root {
                    --color-primary-500: #3b82f6;
                    --color-secondary-500: #6b7280;
                    --spacing-sm: 0.5rem;
                    --spacing-md: 1rem;
                }
                
                .button { }
                .button--primary { }
                .button--secondary { }
                
                .card { }
                .card__header { }
                .card__body { }
            ',
        ];

        $inconsistentSystem = [
            '/test/inconsistent.css' => '
                :root {
                    --primaryColor: #3b82f6;    /* camelCase */
                    --secondary_color: #6b7280;  /* snake_case */
                    --SPACING_SM: 0.5rem;       /* UPPER_CASE */
                }
                
                .btn { }           /* Inconsistent with button */
                .button { }        /* Mixed naming */
                .card_header { }   /* Wrong separator */
                .CardBody { }      /* PascalCase */
            ',
        ];

        $consistentAnalysis = $this->analyzer->analyze($consistentSystem);
        $inconsistentAnalysis = $this->analyzer->analyze($inconsistentSystem);

        expect($consistentAnalysis->consistencyScore)->toBeGreaterThan($inconsistentAnalysis->consistencyScore);
        expect($consistentAnalysis->consistencyScore)->toBeGreaterThan(0.8);
        expect($inconsistentAnalysis->consistencyScore)->toBeLessThan(0.5);

        expect($inconsistentAnalysis->conventionViolations)->not->toBeEmpty();
    });

    it('generates comprehensive design system report', function () {
        $system = [
            '/test/comprehensive.css' => '
                :root {
                    --color-primary-500: #3b82f6;
                    --color-secondary-500: #6b7280;
                    --spacing-md: 1rem;
                    --font-size-base: 16px;
                    --border-radius-md: 0.375rem;
                }
                
                .button {
                    padding: var(--spacing-md);
                    font-size: var(--font-size-base);
                    border-radius: var(--border-radius-md);
                    background-color: var(--color-primary-500);
                }
                
                .button--secondary {
                    background-color: var(--color-secondary-500);
                }
                
                .card {
                    border-radius: var(--border-radius-md);
                    padding: var(--spacing-md);
                }
            ',
        ];

        $analysis = $this->analyzer->analyze($system);

        // Verify all sections are present
        expect($analysis->overview)->toHaveKeys(['total_tokens', 'total_components', 'maturity_level']);
        expect($analysis->tokenAnalysis)->toHaveKeys(['categories', 'naming_patterns', 'usage_analysis']);
        expect($analysis->componentAnalysis)->toHaveKeys(['bem_components', 'utility_patterns', 'complexity_analysis']);
        expect($analysis->colorAnalysis)->toHaveKeys(['total_colors', 'color_scheme', 'accessibility_issues']);
        expect($analysis->conventionAnalysis)->toHaveKeys(['bem_compliance', 'naming_consistency', 'violations']);

        // Verify metrics
        expect($analysis->metrics)->toHaveKeys(['maturity_score', 'consistency_score', 'token_coverage']);
        expect($analysis->metrics['maturity_score'])->toBeBetween(0, 1);
        expect($analysis->metrics['consistency_score'])->toBeBetween(0, 1);

        // Verify recommendations
        expect($analysis->recommendations)->toBeArray();
        expect($analysis->recommendations)->not->toBeEmpty();

        // Verify gaps analysis
        expect($analysis->gaps)->toBeArray();
    });

    it('handles empty or invalid CSS gracefully', function () {
        $emptySystem = [
            '/test/empty.css' => '',
        ];

        $emptyAnalysis = $this->analyzer->analyze($emptySystem);

        expect($emptyAnalysis->overview['total_tokens'])->toBe(0);
        expect($emptyAnalysis->overview['total_components'])->toBe(0);
        expect($emptyAnalysis->maturityLevel)->toBe('Basic');
        expect($emptyAnalysis->recommendations)->toContain('Start by defining design tokens');

        $invalidSystem = [
            '/test/invalid.css' => 'invalid css content {',
        ];

        $invalidAnalysis = $this->analyzer->analyze($invalidSystem);

        expect($invalidAnalysis->errors)->not->toBeEmpty();
        expect($invalidAnalysis->overview['total_tokens'])->toBe(0);
    });

    it('tracks design system evolution over time', function () {
        $version1 = [
            '/test/v1.css' => '
                :root {
                    --primary: #3b82f6;
                    --secondary: #6b7280;
                }
                .btn { }
                .btn--primary { }
            ',
        ];

        $version2 = [
            '/test/v2.css' => '
                :root {
                    --color-primary-500: #3b82f6;
                    --color-secondary-500: #6b7280;
                    --spacing-md: 1rem;
                }
                .button { }
                .button--primary { }
                .button__icon { }
            ',
        ];

        $v1Analysis = $this->analyzer->analyze($version1);
        $v2Analysis = $this->analyzer->analyze($version2);

        expect($v2Analysis->maturityScore)->toBeGreaterThan($v1Analysis->maturityScore);
        expect($v2Analysis->overview['total_tokens'])->toBeGreaterThan($v1Analysis->overview['total_tokens']);

        $evolution = $this->analyzer->compareVersions($v1Analysis, $v2Analysis);

        expect($evolution['improvements'])->not->toBeEmpty();
        expect($evolution['regressions'])->toBeArray();
        expect($evolution['new_features'])->toContain('Enhanced token naming');
        expect($evolution['new_features'])->toContain('Added spacing tokens');
    });
});
