import { isNaN } from 'lodash';
import { forwardRef, useEffect, useState } from 'react';
// import { NumberFormat } from 'react-number-format';
import { NumericFormat } from 'react-number-format';

const formatNegativeValue = (value, negativeMask) => {
  if (!value || value === '0') return value;

  const numValue = parseFloat(value);
  if (numValue >= 0) return value;

  const formattedAbsValue = new Intl.NumberFormat('id-ID', {
    minimumFractionDigits: 0,
    maximumFractionDigits: 2,
  }).format(Math.abs(numValue));

  switch (negativeMask) {
    case 'prefix':
      return `-${formattedAbsValue}`;
    case 'suffix':
      return `${formattedAbsValue}-`;
    case 'both':
      return `(${formattedAbsValue})`;
    default:
      return `-${formattedAbsValue}`;
  }
};

export const getIntegerDigitCount = (value) => {
  if (!value) return 0;
  // Convert to string and remove all non-digit characters
  const cleanValue = value.toString().replace(/[^\d,.-]/g, '');
  // Split by decimal separator and get the integer part
  const integerPart = cleanValue.split(',')[0];
  // Remove negative sign if present and count remaining digits
  return integerPart.replace(/[-]/g, '').length;
};

const NumberFormatRupiahWithAllowedNegative = forwardRef(
  function NumberFormatRupiahWithAllowedNegative(props, ref) {
    const {
      onChange,
      allowNegativeValue = false,
      allowDecimalValue = false,
      negativeMask = 'prefix',
      value: controlledValue,
      maxValue,
      minValue,
      maxLength,
      minLength,
      ...other
    } = props;

    const [isNegative, setIsNegative] = useState(false);

    useEffect(() => {
      if (allowNegativeValue && controlledValue) {
        const numValue = parseFloat(controlledValue.toString().replace(/[^\d.-]/g, ''));
        setIsNegative(numValue < 0);
      }
    }, [controlledValue, allowNegativeValue]);

    const handleKeyPress = (e) => {
      if (!allowNegativeValue) return;

      const kode = e.charCode;
      if (kode === 45) {
        const newIsNegative = !isNegative;
        setIsNegative(newIsNegative);

        const currentValue = props.value || '0';
        const numValue = parseFloat(currentValue.toString().replace(/[^\d.-]/g, ''));

        if (numValue !== 0) {
          const newValue = newIsNegative ? -Math.abs(numValue) : Math.abs(numValue);

          if (
            (maxValue === undefined || newValue <= maxValue) &&
            (minValue === undefined || newValue >= minValue)
          ) {
            onChange({
              target: {
                name: props.name,
                value: newValue.toString(),
              },
            });
          } else {
            setIsNegative(!newIsNegative);
          }
        }
      }
    };

    return (
      <NumericFormat
        {...other}
        value={controlledValue}
        isNumericString
        onKeyPress={handleKeyPress}
        thousandSeparator="."
        decimalSeparator=","
        decimalScale={allowDecimalValue ? 2 : 0}
        getInputRef={ref}
        allowNegative={allowNegativeValue}
        isAllowed={(values) => {
          const { floatValue, value } = values;

          if (floatValue === undefined) return true;

          // Check maximum value
          if (Math.abs(floatValue) > 999999999999) {
            return false;
          }

          // Specific handling for decimal input
          if (value.includes(',') && value.split(',')[1] && value.split(',')[1].length > 2) {
            return false;
          }

          // Get integer digit count (excluding leading zeros and decimal places)
          const integerPart = value.split(',')[0].replace(/^0+/, '');
          const integerDigits = integerPart.length;

          // Length validations for non-zero integer part
          if (maxLength !== undefined && integerDigits > maxLength) {
            return false;
          }
          if (minLength !== undefined && integerDigits < minLength) {
            return false;
          }

          // Min/Max validations (only when float value is complete)
          if (floatValue !== undefined) {
            if (maxValue !== undefined && floatValue > maxValue) {
              return false;
            }
            if (minValue !== undefined && floatValue < minValue) {
              return false;
            }
          }

          return true;
        }}
        format={(value) => {
          if (!value) return value;

          const numValue = parseFloat(value.toString().replace(/[^\d.-]/g, ''));
          if (isNaN(numValue)) return value;

          const formatted = new Intl.NumberFormat('id-ID', {
            minimumFractionDigits: 0,
            maximumFractionDigits: 2,
          }).format(Math.abs(numValue));

          if (numValue < 0 || isNegative) {
            switch (negativeMask) {
              case 'prefix':
                return `-${formatted}`;
              case 'suffix':
                return `${formatted}-`;
              case 'both':
                return `(${formatted})`;
              default:
                return `-${formatted}`;
            }
          }

          return formatted;
        }}
        onValueChange={(values) => {
          let finalValue = values.value;

          if (allowNegativeValue && finalValue && finalValue !== '0') {
            const numValue = parseFloat(finalValue.replace(/[^\d.-]/g, ''));
            if (!isNaN(numValue)) {
              const shouldBeNegative = numValue < 0 || isNegative;
              const potentialValue = shouldBeNegative ? -Math.abs(numValue) : Math.abs(numValue);

              if (
                (maxValue === undefined || potentialValue <= maxValue) &&
                (minValue === undefined || potentialValue >= minValue)
              ) {
                setIsNegative(shouldBeNegative);
                finalValue = shouldBeNegative
                  ? `-${Math.abs(numValue)}`
                  : Math.abs(numValue).toString();
              } else {
                return;
              }
            }
          }

          onChange({
            target: {
              name: props.name,
              value: finalValue,
            },
          });
        }}
      />
    );
  }
);

export default NumberFormatRupiahWithAllowedNegative;
