/**
 * Funciones para manipular valores monetarios numéricos.
 */

export const formatCurrency = (
  amount: number,
  scale: number = 2,
  currency = "EUR",
  locale = "es-ES"
) => {
  return new Intl.NumberFormat(locale, {
    style: "currency",
    currency,
    maximumFractionDigits: scale,
    minimumFractionDigits: Number.isInteger(amount) ? 0 : scale,
    useGrouping: true,
  }).format(amount);
};

/**
 * Elimina símbolos de moneda y caracteres no numéricos.
 * @param s Texto de entrada, e.g. "€ 1.234,56"
 * @returns Solo dígitos, signos y separadores.
 * @example stripCurrencySymbols("€ -1.234,56") // "-1.234,56"
 */
export const stripCurrencySymbols = (s: string): string =>
  s
    .replace(/[^\d.,\-]/g, "")
    .replace(/\s+/g, " ")
    .trim();

/**
 * Parsea un número localizado a float (soporta "," y ".").
 * @param raw Texto con número localizado.
 * @returns número o null si no se puede parsear.
 * @example parseLocaleNumber("1.234,56") // 1234.56
 */
export const parseLocaleNumber = (raw: string): number | null => {
  if (!raw) return null;
  const s = stripCurrencySymbols(raw);
  if (!s) return null;
  const lastComma = s.lastIndexOf(",");
  const lastDot = s.lastIndexOf(".");
  let normalized = s;
  if (lastComma > -1 && lastDot > -1) {
    if (lastComma > lastDot) normalized = s.replace(/\./g, "").replace(",", ".");
    else normalized = s.replace(/,/g, "");
  } else if (lastComma > -1) normalized = s.replace(/\s/g, "").replace(",", ".");
  else normalized = s.replace(/\s/g, "");
  const n = Number(normalized);
  return Number.isFinite(n) ? n : null;
};

/**
 * Redondea a una escala decimal determinada.
 * @param n número base
 * @param scale cantidad de decimales
 * @returns número redondeado
 * @example roundToScale(1.2345, 2) // 1.23
 */
export const roundToScale = (n: number, scale = 2): number => {
  const f = 10 ** scale;
  return Math.round(n * f) / f;
};

/**
 * Suma o resta con step (para inputs numéricos).
 * @example stepNumber(1.2, 0.1) // 1.3
 */
export const stepNumber = (base: number, step = 0.01, scale = 2): number =>
  roundToScale(base + step, scale);
