<?php

declare(strict_types=1);

namespace App\Framework\Design\ValueObjects;

/**
 * Repräsentiert eine CSS-Property mit Namen und Wert
 */
final readonly class CssProperty
{
    public function __construct(
        public string $name,
        public string $value
    ) {
    }

    /**
     * Kategorisiert die Property
     */
    public function getCategory(): CssPropertyCategory
    {
        $colorProperties = [
            'color', 'background-color', 'border-color', 'outline-color',
            'text-decoration-color', 'caret-color', 'column-rule-color',
        ];

        $spacingProperties = [
            'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left',
            'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left',
            'gap', 'row-gap', 'column-gap',
        ];

        $typographyProperties = [
            'font-family', 'font-size', 'font-weight', 'font-style',
            'line-height', 'letter-spacing', 'text-align', 'text-decoration',
            'text-transform', 'font-variant',
        ];

        $layoutProperties = [
            'display', 'position', 'top', 'right', 'bottom', 'left',
            'width', 'height', 'max-width', 'max-height', 'min-width', 'min-height',
            'flex', 'flex-direction', 'flex-wrap', 'justify-content', 'align-items',
            'grid', 'grid-template-columns', 'grid-template-rows',
        ];

        $borderProperties = [
            'border', 'border-top', 'border-right', 'border-bottom', 'border-left',
            'border-width', 'border-style', 'border-radius', 'outline',
        ];

        $animationProperties = [
            'transition', 'animation', 'transform', 'transition-duration',
            'transition-property', 'transition-timing-function', 'transition-delay',
        ];

        if (in_array($this->name, $colorProperties)) {
            return CssPropertyCategory::COLOR;
        }

        if (in_array($this->name, $spacingProperties)) {
            return CssPropertyCategory::SPACING;
        }

        if (in_array($this->name, $typographyProperties)) {
            return CssPropertyCategory::TYPOGRAPHY;
        }

        if (in_array($this->name, $layoutProperties)) {
            return CssPropertyCategory::LAYOUT;
        }

        if (in_array($this->name, $borderProperties)) {
            return CssPropertyCategory::BORDER;
        }

        if (in_array($this->name, $animationProperties)) {
            return CssPropertyCategory::ANIMATION;
        }

        return CssPropertyCategory::OTHER;
    }

    /**
     * Prüft ob die Property einen CSS Custom Property Wert verwendet
     */
    public function usesCustomProperty(): bool
    {
        return str_contains($this->value, 'var(--');
    }

    /**
     * Extrahiert Custom Property Namen aus dem Wert
     */
    public function getCustomPropertyReferences(): array
    {
        preg_match_all('/var\(--([^)]+)\)/', $this->value, $matches);

        return $matches[1] ?? [];
    }

    /**
     * Konvertiert zu CssColor wenn es eine Farbproperty ist
     */
    public function toColor(): ?CssColor
    {
        if ($this->getCategory() !== CssPropertyCategory::COLOR) {
            return null;
        }

        return CssColor::fromString($this->value);
    }

    /**
     * Extrahiert numerischen Wert und Einheit
     */
    public function parseNumericValue(): ?array
    {
        if (preg_match('/^(-?\d*\.?\d+)([a-zA-Z%]*)$/', $this->value, $matches)) {
            return [
                'value' => (float) $matches[1],
                'unit' => $matches[2] ?: null,
            ];
        }

        return null;
    }

    /**
     * Prüft ob die Property wichtig ist (!important)
     */
    public function isImportant(): bool
    {
        return str_contains($this->value, '!important');
    }

    /**
     * Gibt den Wert ohne !important zurück
     */
    public function getValueWithoutImportant(): string
    {
        return trim(str_replace('!important', '', $this->value));
    }

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