import { Result } from "@repo/rdx-utils";
import {
  DomainValidationError,
  ValidationErrorDetail,
  isDomainValidationError,
  isValidationErrorCollection,
} from "../errors";

/**
 * Extrae un valor de un Result si es válido.
 * Si es un fallo, agrega un ValidationErrorDetail al array proporcionado.
 * @param result - El resultado a evaluar.
 * @param path - La ruta del error para el detalle de validación.
 * @param errors - El array donde se agregarán los errores de validación.
 * @returns El valor extraído si el resultado es exitoso, o undefined si es un fallo.
 * @template T - El tipo de dato esperado en el resultado exitoso.
 * @throws {Error} Si el resultado es un fallo y no es una instancia de DomainValidationError.
 * @example
 * const result = Result.ok(42);
 * const value = extractOrPushError(result, 'some.path', []);
 * console.log(value); // 42
 * const errorResult = Result.fail(new Error('Something went wrong'));
 * const value = extractOrPushError(errorResult, 'some.path', []);
 * console.log(value); // undefined
 * // errors will contain [{ path: 'some.path', message: 'Something went wrong' }]
 * 
 * @see Result
 * @see DomainValidationError
 * @see ValidationErrorDetail

 */
export function extractOrPushError<T>(
  result: Result<T, Error>,
  path: string,
  errors: ValidationErrorDetail[]
): T | undefined {
  if (result.isFailure) {
    const error = result.error;

    if (isValidationErrorCollection(error)) {
      // Copiar todos los detalles, rellenando path si falta
      console.log(error);
      error.details?.forEach((detail) => {
        errors.push({
          ...detail,
          path: detail.path ?? path,
        });
      });
    } else if (isDomainValidationError(error)) {
      errors.push({
        path,
        message: error.detail,
        value: (error as any).cause, // mantener la causa original
      });
    } else {
      // Fallback genérico: Error desconocido tratado como validación simple
      errors.push({
        path,
        message: error.message ?? "Unknown error",
      });
    }

    return undefined;
  }

  return result.data;
}
