// application/shared/normalizers.ts
// Normalizadores y adaptadores DTO -> Maybe/VO

import { Maybe, Result, isNullishOrEmpty } from "@repo/rdx-utils";

/** any | null | undefined -> Maybe<T> usando fábrica VO */
export function maybeFromNullableVO<T>(
  input: any,
  voFactory: (raw: any) => Result<T>
): Result<Maybe<T>> {
  if (isNullishOrEmpty(input)) return Result.ok(Maybe.none<T>());
  const vo = voFactory(input);
  return vo.isSuccess ? Result.ok(Maybe.some(vo.data)) : Result.fail(vo.error);
}

/** string | null | undefined -> Maybe<string> (trim, vacío => None) */
export function maybeFromNullableString(input?: string | null): Maybe<string> {
  if (isNullishOrEmpty(input)) return Maybe.none<string>();
  const t = (input as string).trim();
  return t ? Maybe.some(t) : Maybe.none<string>();
}

/** Maybe<T> -> null para transporte */
export function toNullable<T, R>(m: Maybe<T>, map: (t: T) => R): R | null {
  if (!m || m.isNone()) return null;
  return map(m.unwrap() as T);
}

export function toNullable2<T>(m: Maybe<T>, map?: (t: T) => unknown): unknown | null {
  if (!m || m.isNone()) return null;
  const v = m.unwrap() as T;
  return map ? String(map(v)) : String(v);
}

/** Maybe<T> -> "" para transporte */
export function toEmptyString<T>(m: Maybe<T>, map?: (t: T) => string): string {
  if (!m || m.isNone()) return "";
  const v = m.unwrap() as T;
  return map ? map(v) : String(v);
}
