<?php
declare(strict_types=1);

namespace ROITheme\Shared\Domain\Exceptions;

/**
 * InvalidComponentException - Excepción de Dominio para componentes inválidos
 *
 * RESPONSABILIDAD: Representar errores de validación de reglas de negocio de componentes
 *
 * CUÁNDO LANZAR:
 * - Nombre de componente inválido (formato, longitud)
 * - Configuración inválida (CTA URL sin CTA text, colores mal formateados)
 * - Visibility inválida (combinaciones no permitidas)
 * - Content inválido (URLs mal formateadas, textos vacíos cuando requeridos)
 * - Cualquier violación de invariantes del dominio
 *
 * USO:
 * ```php
 * if (empty($name)) {
 *     throw new InvalidComponentException('Component name cannot be empty');
 * }
 * ```
 *
 * @package ROITheme\Shared\Domain\Exceptions
 */
class InvalidComponentException extends \DomainException
{
    /**
     * Constructor
     *
     * @param string $message Mensaje de error
     * @param int $code Código de error (opcional)
     * @param \Throwable|null $previous Excepción anterior (opcional)
     */
    public function __construct(
        string $message,
        int $code = 0,
        ?\Throwable $previous = null
    ) {
        parent::__construct($message, $code, $previous);
    }

    /**
     * Crear excepción para nombre inválido
     *
     * @param string $name
     * @param string $reason
     * @return self
     */
    public static function invalidName(string $name, string $reason): self
    {
        return new self(
            sprintf('Invalid component name "%s": %s', $name, $reason)
        );
    }

    /**
     * Crear excepción para configuración inválida
     *
     * @param string $componentName
     * @param string $reason
     * @return self
     */
    public static function invalidConfiguration(string $componentName, string $reason): self
    {
        return new self(
            sprintf('Invalid configuration for component "%s": %s', $componentName, $reason)
        );
    }

    /**
     * Crear excepción para CTA inválido
     *
     * @param string $componentName
     * @return self
     */
    public static function ctaUrlRequiresText(string $componentName): self
    {
        return new self(
            sprintf('Component "%s" has CTA URL but missing CTA text', $componentName)
        );
    }

    /**
     * Crear excepción para color inválido
     *
     * @param string $colorKey
     * @param string $value
     * @return self
     */
    public static function invalidColor(string $colorKey, string $value): self
    {
        return new self(
            sprintf('Invalid color format for "%s": "%s". Expected hexadecimal (e.g., #000000)', $colorKey, $value)
        );
    }
}
