<?php
declare(strict_types=1);

namespace ROITheme\Shared\Application\UseCases\SaveComponent;

/**
 * SaveComponentResponse - DTO de salida para guardar componente
 *
 * RESPONSABILIDAD: Encapsular el resultado del Use Case (�xito o fallo)
 *
 * PATR�N: Success/Failure
 * - �xito: success=true, data contiene el componente guardado
 * - Fallo: success=false, errors contiene array de errores
 *
 * CARACTER�STICAS:
 * - Inmutable
 * - Constructor privado (usar factory methods)
 * - Factory methods: success() y failure()
 *
 * USO:
 * ```php
 * // �xito
 * $response = SaveComponentResponse::success(['name' => 'top_bar', ...]);
 * if ($response->isSuccess()) {
 *     $data = $response->getData();
 * }
 *
 * // Fallo
 * $response = SaveComponentResponse::failure(['Error de validaci�n']);
 * if (!$response->isSuccess()) {
 *     $errors = $response->getErrors();
 * }
 * ```
 *
 * @package ROITheme\Shared\Application\UseCases\SaveComponent
 */
final readonly class SaveComponentResponse
{
    /**
     * Constructor privado - usar factory methods
     *
     * @param bool $success Indica si la operaci�n fue exitosa
     * @param mixed $data Datos del componente guardado (solo si success=true)
     * @param array|null $errors Array de errores (solo si success=false)
     */
    private function __construct(
        private bool $success,
        private mixed $data,
        private ?array $errors
    ) {}

    /**
     * Verificar si la operaci�n fue exitosa
     *
     * @return bool
     */
    public function isSuccess(): bool
    {
        return $this->success;
    }

    /**
     * Obtener datos del componente guardado
     *
     * Solo v�lido si isSuccess() === true
     *
     * @return mixed
     */
    public function getData(): mixed
    {
        return $this->data;
    }

    /**
     * Obtener errores
     *
     * Solo v�lido si isSuccess() === false
     *
     * @return array|null
     */
    public function getErrors(): ?array
    {
        return $this->errors;
    }

    /**
     * Factory method: Crear respuesta exitosa
     *
     * @param mixed $data Datos del componente guardado
     * @return self
     */
    public static function success(mixed $data): self
    {
        return new self(true, $data, null);
    }

    /**
     * Factory method: Crear respuesta de fallo
     *
     * @param array $errors Array de mensajes de error
     * @return self
     */
    public static function failure(array $errors): self
    {
        return new self(false, null, $errors);
    }

    /**
     * Convertir a array para serializaci�n (JSON, etc.)
     *
     * @return array
     */
    public function toArray(): array
    {
        return [
            'success' => $this->success,
            'data' => $this->data,
            'errors' => $this->errors
        ];
    }
}
