<?php
declare(strict_types=1);

namespace ROITheme\Admin\CustomCSSManager\Domain\ValueObjects;

use ROITheme\Shared\Domain\Exceptions\ValidationException;

/**
 * Value Object para código CSS validado
 */
final class CSSCode
{
    private const MAX_SIZE_CRITICAL = 14336;  // 14KB para CSS crítico
    private const MAX_SIZE_DEFERRED = 102400; // 100KB para CSS diferido

    private function __construct(
        private readonly string $value
    ) {}

    public static function fromString(string $css): self
    {
        $sanitized = self::sanitize($css);
        self::validate($sanitized);
        return new self($sanitized);
    }

    private static function sanitize(string $css): string
    {
        // Eliminar etiquetas <style>
        $css = preg_replace('/<\/?style[^>]*>/i', '', $css);

        // Eliminar comentarios HTML
        $css = preg_replace('/<!--.*?-->/s', '', $css);

        return trim($css);
    }

    private static function validate(string $css): void
    {
        // Detectar código potencialmente peligroso
        $dangerous = ['javascript:', 'expression(', '@import', 'behavior:'];
        foreach ($dangerous as $pattern) {
            if (stripos($css, $pattern) !== false) {
                throw new ValidationException("CSS contiene patrón no permitido: {$pattern}");
            }
        }
    }

    public function validateForLoadType(LoadType $loadType): void
    {
        $maxSize = $loadType->isCritical()
            ? self::MAX_SIZE_CRITICAL
            : self::MAX_SIZE_DEFERRED;

        if (strlen($this->value) > $maxSize) {
            throw new ValidationException(
                sprintf('CSS excede el tamaño máximo de %d bytes para tipo %s',
                    $maxSize,
                    $loadType->value()
                )
            );
        }
    }

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

    public function isEmpty(): bool
    {
        return empty($this->value);
    }
}
