<?php

declare(strict_types=1);

namespace App\Framework\Design\ValueObjects;

/**
 * Repräsentiert eine CSS-Klasse
 */
final readonly class CssClass
{
    public function __construct(
        public string $name
    ) {
    }

    public static function fromSelector(string $selector): self
    {
        // Remove the leading dot from class selector
        $className = ltrim($selector, '.');

        return new self($className);
    }

    public function isBemBlock(): bool
    {
        // BEM Block: doesn't contain __ or --
        return ! str_contains($this->name, '__') && ! str_contains($this->name, '--');
    }

    public function isBemElement(): bool
    {
        // BEM Element: contains __ but not --
        return str_contains($this->name, '__') && ! str_contains($this->name, '--');
    }

    public function isBemModifier(): bool
    {
        // BEM Modifier: contains -- (and possibly __)
        return str_contains($this->name, '--');
    }

    public function isUtilityClass(): bool
    {
        // Common utility class patterns
        $utilityPatterns = [
            '/^(text|bg|p|m|pt|pb|pl|pr|mt|mb|ml|mr|w|h|flex|grid|hidden|block|inline)-/',
            '/^(sm|md|lg|xl):|:/',
            '/^(hover|focus|active|disabled):/',
        ];

        foreach ($utilityPatterns as $pattern) {
            if (preg_match($pattern, $this->name)) {
                return true;
            }
        }

        return false;
    }

    public function getBemBlock(): ?string
    {
        if ($this->isBemBlock()) {
            return $this->name;
        }

        // Extract block from element or modifier
        if (str_contains($this->name, '__')) {
            return explode('__', $this->name)[0];
        }

        if (str_contains($this->name, '--')) {
            return explode('--', $this->name)[0];
        }

        return null;
    }

    public function getBemElement(): ?string
    {
        if (! $this->isBemElement()) {
            return null;
        }

        $parts = explode('__', $this->name);
        if (count($parts) >= 2) {
            $element = $parts[1];
            // Remove modifier if present
            if (str_contains($element, '--')) {
                $element = explode('--', $element)[0];
            }

            return $element;
        }

        return null;
    }

    public function getBemModifier(): ?string
    {
        if (! $this->isBemModifier()) {
            return null;
        }

        $parts = explode('--', $this->name);
        if (count($parts) >= 2) {
            return $parts[1];
        }

        return null;
    }

    public function getUtilityCategory(): ?string
    {
        $categoryPatterns = [
            'spacing' => '/^[mp][trblxy]?-\d+$/',
            'sizing' => '/^[wh]-\d+$/',
            'typography' => '/^text-(xs|sm|base|lg|xl|\d+xl|center|left|right)$/',
            'color' => '/^(text|bg|border)-(red|blue|green|gray|yellow|purple|pink|indigo)-\d+$/',
            'display' => '/^(block|inline|flex|grid|hidden)$/',
            'flexbox' => '/^(justify|items|self)-(start|end|center|between|around)$/',
        ];

        foreach ($categoryPatterns as $category => $pattern) {
            if (preg_match($pattern, $this->name)) {
                return $category;
            }
        }

        return null;
    }

    public function getComponentType(): ?string
    {
        $componentPatterns = [
            'button' => ['btn', 'button'],
            'card' => ['card'],
            'modal' => ['modal', 'dialog'],
            'form' => ['form', 'input', 'select', 'textarea'],
            'navigation' => ['nav', 'navbar', 'menu'],
            'table' => ['table', 'thead', 'tbody', 'tr', 'td', 'th'],
            'alert' => ['alert', 'message', 'notification'],
            'badge' => ['badge', 'tag', 'chip'],
            'dropdown' => ['dropdown', 'select'],
            'tabs' => ['tab', 'tabs'],
            'accordion' => ['accordion', 'collapse'],
            'breadcrumb' => ['breadcrumb'],
            'pagination' => ['pagination', 'pager'],
        ];

        foreach ($componentPatterns as $componentType => $patterns) {
            foreach ($patterns as $pattern) {
                if (str_starts_with($this->name, $pattern) || str_contains($this->name, $pattern)) {
                    return $componentType;
                }
            }
        }

        return null;
    }

    public function getNamingConvention(): string
    {
        if ($this->isBemBlock() || $this->isBemElement() || $this->isBemModifier()) {
            return 'bem';
        }

        if (preg_match('/^[a-z][a-zA-Z0-9]*$/', $this->name)) {
            return 'camelCase';
        }

        if (preg_match('/^[a-z][a-z0-9-]*$/', $this->name)) {
            return 'kebab-case';
        }

        if (preg_match('/^[a-z][a-z0-9_]*$/', $this->name)) {
            return 'snake_case';
        }

        return 'other';
    }

    public function toString(): string
    {
        return $this->name;
    }

    public static function fromString(string $className): self
    {
        return new self(trim($className, '. '));
    }
}
