export const positiveNumericFieldHandler = (value: string, valueSetter: (value: string) => void, decimals?: number) => {
  value = value.replace(",", ".");
  const numericValue = Number(value);
  if (!Number.isNaN(numericValue) && numericValue >= 0) {
    if (numericValue !== 0 && numericValue >= 1) {
      value = value.replace(/^0+/, "");
    }

    const dotIndex = value.indexOf(".");
    if (dotIndex > -1) {
      const integer = value.slice(0, dotIndex).replace(/^(0){1,}/, "");
      let fractional = value.slice(dotIndex + 1);

      if (decimals !== undefined) {
        fractional = fractional.slice(0, decimals);
      }

      value = `${integer.length > 0 ? integer : "0"}.${fractional}`;
    }

    valueSetter(value);
  }
};

export const createFormattedNumberInputHandler =
  (prevValue: string, handler: (value: string) => void) =>
  ({ target }: React.ChangeEvent<HTMLInputElement>) => {
    let pureValue = target.value.replace(/ /g, "");
    let valueParts = formatNumber(pureValue).split(" ");

    let caretDiff = formatNumber(pureValue).length - formatNumber(prevValue).length;

    let caret =
      (target.selectionStart || 0) >= (target.selectionEnd || 0) ? target.selectionStart : target.selectionEnd;

    if (caretDiff === 0 && target.value.length < formatNumber(prevValue).length && caret !== 0) {
      caretDiff -= valueParts[0].length > 1 ? 1 : 2;

      pureValue = pureValue.slice(0, (caret || 1) - 1) + pureValue.slice(caret || 1);
    }

    handler(pureValue);

    window.requestAnimationFrame(() => {
      const newPositionDelta = caretDiff > 0 ? caretDiff - 1 : caretDiff + 1;

      target.selectionStart = caret ? caret + Math.sign(newPositionDelta) : caret;
      target.selectionEnd = caret ? caret + Math.sign(newPositionDelta) : caret;
    });
  };

export const formatNumber = (value: string) => {
  const hasSign = value[0] === "-";

  const [integer = "", double] = value.substring(hasSign ? 1 : 0).split(".");

  let number = Array.from(integer)
    .reverse()
    .map((value, index) => (index > 0 && index % 3 === 0 ? value + " " : value))
    .reverse()
    .join("");

  if (value.includes(".")) {
    number += "." + double;
  }

  if (hasSign) {
    number = "-" + number;
  }

  return number;
};
