<?php
declare(strict_types=1);

namespace ROITheme\Shared\Application\UseCases\GetComponent;

/**
 * GetComponentResponse - DTO de salida para obtener componente
 *
 * RESPONSABILIDAD: Encapsular resultado de obtener un componente
 *
 * PATRÓN: Success/Failure
 * - Éxito: success=true, data contiene el componente
 * - Fallo: success=false, error contiene mensaje de error
 *
 * USO:
 * ```php
 * $response = GetComponentResponse::success($componentData);
 * if ($response->isSuccess()) {
 *     $data = $response->getData();
 * }
 * ```
 *
 * @package ROITheme\Shared\Application\UseCases\GetComponent
 */
final readonly class GetComponentResponse
{
    /**
     * Constructor privado - usar factory methods
     *
     * @param bool $success Indica si la operación fue exitosa
     * @param mixed $data Datos del componente (solo si success=true)
     * @param string|null $error Mensaje de error (solo si success=false)
     */
    private function __construct(
        private bool $success,
        private mixed $data,
        private ?string $error
    ) {}

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

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

    /**
     * Obtener mensaje de error
     *
     * Solo válido si isSuccess() === false
     *
     * @return string|null
     */
    public function getError(): ?string
    {
        return $this->error;
    }

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

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

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