<?php

declare(strict_types=1);

use App\Framework\Design\Service\ComponentDetector;
use App\Framework\Design\ValueObjects\CssClass;

describe('ComponentDetector', function () {

    beforeEach(function () {
        $this->detector = new ComponentDetector();
    });

    it('detects BEM components correctly', function () {
        $cssClasses = [
            new CssClass('card'),
            new CssClass('card__header'),
            new CssClass('card__body'),
            new CssClass('card__footer'),
            new CssClass('card--featured'),
            new CssClass('card__header--large'),
            new CssClass('button'),
            new CssClass('button--primary'),
        ];

        $components = $this->detector->detectBemComponents($cssClasses);

        expect($components)->toHaveCount(2); // card and button

        $cardComponent = $components[0];
        expect($cardComponent['block'])->toBe('card');
        expect($cardComponent['elements'])->toContain('header');
        expect($cardComponent['elements'])->toContain('body');
        expect($cardComponent['elements'])->toContain('footer');
        expect($cardComponent['modifiers'])->toContain('featured');
        expect($cardComponent['element_modifiers'])->toHaveKey('header');
        expect($cardComponent['element_modifiers']['header'])->toContain('large');
    });

    it('identifies utility class patterns', function () {
        $cssClasses = [
            new CssClass('text-center'),
            new CssClass('text-left'),
            new CssClass('text-right'),
            new CssClass('p-4'),
            new CssClass('p-8'),
            new CssClass('m-2'),
            new CssClass('bg-blue-500'),
            new CssClass('bg-red-300'),
            new CssClass('hover:bg-blue-600'),
            new CssClass('card'), // Not a utility
        ];

        $utilityPatterns = $this->detector->detectUtilityPatterns($cssClasses);

        expect($utilityPatterns)->toHaveKey('text-alignment');
        expect($utilityPatterns)->toHaveKey('padding');
        expect($utilityPatterns)->toHaveKey('margin');
        expect($utilityPatterns)->toHaveKey('background-color');
        expect($utilityPatterns)->toHaveKey('hover-states');

        expect($utilityPatterns['text-alignment'])->toHaveCount(3);
        expect($utilityPatterns['padding'])->toHaveCount(2);
        expect($utilityPatterns['background-color'])->toHaveCount(2);
        expect($utilityPatterns['hover-states'])->toHaveCount(1);
    });

    it('detects component structure patterns', function () {
        $cssClasses = [
            // Layout components
            new CssClass('container'),
            new CssClass('row'),
            new CssClass('col'),
            new CssClass('col-md-6'),

            // Form components
            new CssClass('form'),
            new CssClass('form-group'),
            new CssClass('form-control'),
            new CssClass('form-label'),

            // Navigation components
            new CssClass('nav'),
            new CssClass('nav-item'),
            new CssClass('nav-link'),
        ];

        $patterns = $this->detector->detectStructurePatterns($cssClasses);

        expect($patterns)->toHaveKey('layout');
        expect($patterns)->toHaveKey('form');
        expect($patterns)->toHaveKey('navigation');

        expect($patterns['layout']['components'])->toContain('container');
        expect($patterns['layout']['components'])->toContain('row');
        expect($patterns['form']['components'])->toContain('form');
        expect($patterns['form']['components'])->toContain('form-group');
        expect($patterns['navigation']['components'])->toContain('nav');
    });

    it('analyzes responsive design patterns', function () {
        $cssClasses = [
            new CssClass('hidden-xs'),
            new CssClass('visible-md'),
            new CssClass('col-sm-12'),
            new CssClass('col-md-6'),
            new CssClass('col-lg-4'),
            new CssClass('text-sm-center'),
            new CssClass('text-md-left'),
        ];

        $responsive = $this->detector->analyzeResponsivePatterns($cssClasses);

        expect($responsive['breakpoints'])->toContain('xs');
        expect($responsive['breakpoints'])->toContain('sm');
        expect($responsive['breakpoints'])->toContain('md');
        expect($responsive['breakpoints'])->toContain('lg');

        expect($responsive['patterns']['visibility'])->toHaveCount(2);
        expect($responsive['patterns']['grid'])->toHaveCount(3);
        expect($responsive['patterns']['typography'])->toHaveCount(2);
    });

    it('identifies component complexity levels', function () {
        $simpleComponent = [
            new CssClass('button'),
            new CssClass('button--primary'),
        ];

        $complexComponent = [
            new CssClass('card'),
            new CssClass('card__header'),
            new CssClass('card__title'),
            new CssClass('card__subtitle'),
            new CssClass('card__body'),
            new CssClass('card__content'),
            new CssClass('card__actions'),
            new CssClass('card__footer'),
            new CssClass('card--featured'),
            new CssClass('card--compact'),
            new CssClass('card__header--large'),
            new CssClass('card__actions--centered'),
        ];

        $simpleComplexity = $this->detector->analyzeComponentComplexity($simpleComponent);
        $complexComplexity = $this->detector->analyzeComponentComplexity($complexComponent);

        expect($simpleComplexity['level'])->toBe('simple');
        expect($simpleComplexity['score'])->toBeLessThan(3);

        expect($complexComplexity['level'])->toBe('complex');
        expect($complexComplexity['score'])->toBeGreaterThan(8);
        expect($complexComplexity['recommendations'])->toContain('Consider splitting into smaller components');
    });

    it('detects atomic design patterns', function () {
        $cssClasses = [
            // Atoms
            new CssClass('btn'),
            new CssClass('input'),
            new CssClass('label'),
            new CssClass('icon'),

            // Molecules
            new CssClass('search-form'),
            new CssClass('form-group'),
            new CssClass('nav-item'),

            // Organisms
            new CssClass('header'),
            new CssClass('sidebar'),
            new CssClass('footer'),
            new CssClass('product-grid'),
        ];

        $atomicAnalysis = $this->detector->analyzeAtomicDesignPatterns($cssClasses);

        expect($atomicAnalysis['atoms'])->toHaveCount(4);
        expect($atomicAnalysis['molecules'])->toHaveCount(3);
        expect($atomicAnalysis['organisms'])->toHaveCount(4);

        expect($atomicAnalysis['atoms'])->toContain('btn');
        expect($atomicAnalysis['molecules'])->toContain('search-form');
        expect($atomicAnalysis['organisms'])->toContain('header');
    });

    it('validates component naming conventions', function () {
        $cssClasses = [
            new CssClass('button'),              // Good: semantic
            new CssClass('btn'),                 // Good: abbreviation
            new CssClass('redButton'),           // Bad: camelCase
            new CssClass('button_primary'),      // Bad: underscore instead of dash
            new CssClass('Button'),              // Bad: PascalCase
            new CssClass('my-custom-btn-2'),     // Good: kebab-case
        ];

        $validation = $this->detector->validateNamingConventions($cssClasses);

        expect($validation['valid'])->toHaveCount(3);
        expect($validation['invalid'])->toHaveCount(3);

        $invalidClasses = array_map(fn ($v) => $v['class'], $validation['invalid']);
        expect($invalidClasses)->toContain('redButton');
        expect($invalidClasses)->toContain('button_primary');
        expect($invalidClasses)->toContain('Button');
    });

    it('detects component relationships', function () {
        $cssClasses = [
            new CssClass('modal'),
            new CssClass('modal__backdrop'),
            new CssClass('modal__dialog'),
            new CssClass('modal__header'),
            new CssClass('modal__title'),
            new CssClass('modal__close'),
            new CssClass('modal__body'),
            new CssClass('modal__footer'),
            new CssClass('modal__actions'),
        ];

        $relationships = $this->detector->detectComponentRelationships($cssClasses);

        expect($relationships)->toHaveKey('modal');

        $modalRelationships = $relationships['modal'];
        expect($modalRelationships['children'])->toContain('backdrop');
        expect($modalRelationships['children'])->toContain('dialog');
        expect($modalRelationships['children'])->toContain('header');
        expect($modalRelationships['depth'])->toBe(2); // modal -> header -> title
        expect($modalRelationships['complexity_score'])->toBeGreaterThan(5);
    });

    it('suggests component improvements', function () {
        $cssClasses = [
            // Inconsistent button pattern
            new CssClass('button'),
            new CssClass('btn'),                 // Inconsistent naming
            new CssClass('submit-btn'),          // Another variation

            // Missing BEM structure
            new CssClass('card-header'),         // Should be card__header
            new CssClass('card-body'),           // Should be card__body

            // Overly specific
            new CssClass('red-submit-button-large'),
        ];

        $improvements = $this->detector->suggestImprovements($cssClasses);

        expect($improvements['naming_inconsistencies'])->not->toBeEmpty();
        expect($improvements['bem_violations'])->not->toBeEmpty();
        expect($improvements['overly_specific'])->not->toBeEmpty();

        expect($improvements['suggestions'])->toContain('Standardize button naming (choose: button, btn)');
        expect($improvements['suggestions'])->toContain('Convert card-header to card__header for BEM compliance');
    });

    it('analyzes component reusability', function () {
        $cssClasses = [
            new CssClass('btn'),
            new CssClass('btn--primary'),
            new CssClass('btn--secondary'),
            new CssClass('btn--large'),
            new CssClass('btn--small'),
            new CssClass('very-specific-page-button'), // Low reusability
        ];

        $reusability = $this->detector->analyzeComponentReusability($cssClasses);

        $btnReusability = $reusability['btn'];
        expect($btnReusability['score'])->toBeGreaterThan(0.8);
        expect($btnReusability['variants'])->toBe(4);
        expect($btnReusability['reusability_level'])->toBe('high');

        $specificReusability = $reusability['very-specific-page-button'];
        expect($specificReusability['score'])->toBeLessThan(0.3);
        expect($specificReusability['reusability_level'])->toBe('low');
    });
});
