import React, { useState, ReactElement } from "react";
import { RegisterOptions, useFormContext } from "react-hook-form";
import { isNullOrWhiteSpace } from "../../util/stringUtil";
import InputWrapper from "./inputParts/inputWrapper";
import InternalInput from "./inputParts/internalInput";
import IMask from "imask";

export type NumberInputProps = {
  name: string;
  disabled?: boolean;
  circa?: boolean;
  circaText?: string;
  shouldCircaDisable?: boolean;
  circaName?: string;
  wrapperClassName?: string;
  inputClassName?: string;
  label: string;
  registerOptions?: RegisterOptions;
  onlyIntegers?: boolean;
  paragraph?: string | ReactElement;
  noBorder?: boolean;
  manipulateValues?: boolean;
};

export default function NumberInput({
  name,
  disabled,
  wrapperClassName,
  inputClassName,
  label,
  registerOptions,
  paragraph,
  onlyIntegers = false,
  noBorder = false,
  manipulateValues = true,
}: NumberInputProps) {
  const { getValues } = useFormContext();
  const [isActive, setIsActive] = useState(
    !isNullOrWhiteSpace(getValues(name) && !disabled)
  );
  const [inputState, setInputState] = useState<
    "default" | "active" | "error" | "disabled"
  >("default");
  const [hasFocus, setHasFocus] = useState(false);

  const numberMasker = IMask.createMask({
    mask: Number,
    scale: 2, // digits after comma
    signed: false, // no negative
    thousandsSeparator: ".",
    padFractionalZeros: true, // pads zeros at end to the length of scale
    normalizeZeros: true, // appends or removes zeros at ends
    radix: ",", // fractional delimiter
    mapToRadix: [","], // symbols to process as radix
    max: 2147483647,
  });

  const resolveNumber = (value: string): string => {
    numberMasker.resolve(value);
    let maskedValue = numberMasker.value;

    if (onlyIntegers) {
      maskedValue = maskedValue.split(",")[0];
    }

    if (maskedValue === "") {
      return "";
    }
    return maskedValue;
  };

  return (
    <>
      {paragraph && (
        <div className={`${disabled && "text-neutral-medium-light"} mb-1`}>
          {paragraph}
        </div>
      )}
      <InputWrapper
        isActive={isActive}
        inputState={inputState}
        setInputState={setInputState}
        hasFocus={hasFocus}
        wrapperClassName={wrapperClassName}
        disabled={disabled}
        hasDropdown={true}
        name={name}
        noBorder={noBorder}
      >
        <InternalInput
          registerOptions={{
            ...registerOptions,
            onBlur: manipulateValues
              ? (event) =>
                  (event.target.value = resolveNumber(event.target.value))
              : undefined,
            setValueAs: manipulateValues
              ? (value: string) => resolveNumber(value)
              : undefined,
          }}
          inputClassName={inputClassName}
          inputState={inputState}
          id={name}
          name={name}
          label={label}
          disabled={disabled}
          type="text"
          setHasFocus={setHasFocus}
          isActive={isActive}
          setIsActive={setIsActive}
        />
      </InputWrapper>
    </>
  );
}
