import { OnlyNumbers, NumberFormat } from '@devesharp/react-utils';

/**
 * NumberMask
 * @param _value
 * @param decimals
 * @constructor
 */
export const NumberMask = (_value: string | number, decimals = 2): string => {
   if (typeof _value === 'number') {
      _value = _value.toFixed(decimals).toString();
   }

   const value = _value || '';

   if (value === '') return value;

   let newValOnlyNumbers = OnlyNumbers(value);

   if (newValOnlyNumbers.length > 15) {
      newValOnlyNumbers = newValOnlyNumbers.substr(0, 15);
   }

   return NumberFormat(Number(newValOnlyNumbers) / 10 ** decimals, decimals).toString();
};

export const CEPMask = (_value: string): string => {
   const value = _value || '';

   if (value === '') return value;

   let newVal = OnlyNumbers(value);

   newVal = newVal.substring(0, 8);
   if (newVal.length > 5) {
      newVal = newVal.replace(/^(\d{0,5})(\d{0,3})/, '$1-$2');
   }

   return newVal;
};

export const CNPJMask = (_value: string): string => {
   const value = _value || '';

   if (value === '') return value;

   let newVal = OnlyNumbers(value);

   if (newVal.length === 0) {
      newVal = '';
   } else if (newVal.length < 3) {
      newVal = newVal.replace(/^(\d{0,2})/, '$1');
   } else if (newVal.length < 6) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,3})/, '$1.$2');
   } else if (newVal.length < 9) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,3})(\d{0,3})/, '$1.$2.$3');
   } else if (newVal.length < 13) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,3})(\d{0,3})(\d{0,4})/, '$1.$2.$3/$4');
   } else {
      newVal = newVal.substring(0, 14);
      newVal = newVal.replace(/^(\d{0,2})(\d{0,3})(\d{0,3})(\d{0,4})(\d{0,2})/, '$1.$2.$3/$4-$5');
   }

   return newVal;
};

export const CPFMask = (_value: string): string => {
   const value = _value || '';

   if (value === '') return value;

   let newVal = OnlyNumbers(value);

   if (newVal.length === 0) {
      newVal = '';
   } else if (newVal.length < 4) {
      newVal = newVal.replace(/^(\d{0,3})/, '$1');
   } else if (newVal.length < 7) {
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})/, '$1.$2');
   } else if (newVal.length < 10) {
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})(\d{0,3})/, '$1.$2.$3');
   } else {
      newVal = newVal.substring(0, 11);
      newVal = newVal.replace(/^(\d{0,3})(\d{0,3})(\d{0,3})(\d{0,2})/, '$1.$2.$3-$4');
   }

   return newVal;
};

export const RGMask = (_value: string): string => {
   const value = _value || '';

   if (value === '') return value;

   let newVal = OnlyNumbers(value);

   if (newVal.length === 0) {
      newVal = '';
   } else if (newVal.length < 3) {
      newVal = newVal.replace(/^(\d{0,2})/, '$1');
   } else if (newVal.length < 6) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,3})/, '$1.$2');
   } else if (newVal.length < 9) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,3})(\d{0,3})/, '$1.$2.$3');
   } else {
      newVal = newVal.substring(0, 9);
      newVal = newVal.replace(/^(\d{0,2})(\d{0,3})(\d{0,3})(\d{0,2})/, '$1.$2.$3-$4');
   }

   return newVal;
};

export const NoSpaceMask = (_value: string): string => {
   const value = _value || '';

   if (value === '') return value;

   const newVal = value.replace(/ /g, '');

   return newVal;
};

export const PhoneMask = (_value: string): string => {
   const value = _value || '';

   if (value === '') return value;

   let newVal = OnlyNumbers(value);

   if (newVal.length === 0) {
      newVal = '';
   } else if (newVal.length <= 3) {
      if (newVal.length === 3) {
         newVal = newVal.replace(/^(\d{0,2})(\d)/, '($1) $2');
      }
   } else if (newVal.length <= 6) {
      newVal = newVal.replace(/^(\d{0,2})(\d)/, '($1) $2');
   } else if (newVal.length <= 10) {
      newVal = newVal.replace(/^(\d{0,2})(\d{0,4})(\d{0,4})/, '($1) $2-$3');
   } else {
      newVal = newVal.substring(0, 11);
      newVal = newVal.replace(/^(\d{0,2})(\d{0,5})(\d{0,4})/, '($1) $2-$3');
   }

   return newVal;
};

export function maskValue(
   value = '',
   mask: 'CEP' | 'CNPJ' | 'CPF' | 'RG' | 'phone' | 'number' | 'no-spaces',
   options: {
      decimals?: number;
      withoutDotNumber?: number;
   } = {},
): string {
   if (mask == 'no-spaces') value = NoSpaceMask(value);
   if (mask == 'number')
      return !options?.withoutDotNumber
         ? NumberMask(value, options?.decimals)
         : NumberMask(value, options?.decimals).replace(/\./g, '');
   if (mask == 'CEP') return CEPMask(value);
   if (mask == 'CNPJ') return CNPJMask(value);
   if (mask == 'CPF') return CPFMask(value);
   if (mask == 'RG') return RGMask(value);
   if (mask == 'phone') return PhoneMask(value);

   return value;
}
