// @flow
import type {
  TextInputType,
  MaskedTextInputOptions,
  CurrencyCode,
} from './text-input.proptypes';

const NO_MASK: MaskedTextInputOptions = { delimiter: '' };
const DATE_MASK: MaskedTextInputOptions = {
  date: true,
  datePattern: ['d', 'm', 'Y'],
  delimiter: ' / ',
};

const CURRENCY_MASK: MaskedTextInputOptions = {
  numeral: true,
  rawValueTrimPrefix: true,
  noImmediatePrefix: true,
};

const GROUPED_CODE_MASK: MaskedTextInputOptions = {
  blocks: [4, 4, 4, 4],
  uppercase: true,
};

const NUMBER_MASK: MaskedTextInputOptions = {
  numeral: true,
  numericOnly: true,
};

const TYPE_TO_MASK_MAP = {
  date: DATE_MASK,
  email: NO_MASK,
  number: NUMBER_MASK,
  text: NO_MASK,
  password: NO_MASK,
  currency: CURRENCY_MASK,
  grouped_code: GROUPED_CODE_MASK,
  custom: null,
  search: NO_MASK,
};

// Maps our custom type values to the right value for the DOM input type attribute.
type DOMType = 'text' | 'password' | 'number' | 'email' | 'search';
export const getDomType = (
  type: TextInputType,
  revealText: boolean,
): DOMType => {
  if (type == null) {
    return 'text';
  }

  const map = {
    password: revealText ? 'text' : 'password',
    // Disable Firefox's built-in date picker for parity with Chrome, Safari.
    // Firefox also puts a non-changeable placeholder when you use type date
    // which interferes with the floating label styling.
    date: 'text',
    email: 'email',
    number: 'text',
    search: 'search',
    text: 'text',
    custom: 'text',
    currency: 'text',
    grouped_code: 'text',
  };

  return map[type] ?? 'text';
};

// Maps our custom type values to an appropriate CleaveJS mask.
export const getMaskOptions = (
  type: TextInputType,
  currencyCode?: CurrencyCode,
  decimalPlaces?: number,
  customMaskOptions?: MaskedTextInputOptions,
): MaskedTextInputOptions => {
  if (type != null && type !== 'custom' && customMaskOptions != null) {
    // eslint-disable-next-line no-console
    console.warn(
      `TextInput: ignoring attempt to use customMaskOptions with type=${type}. You must set type="custom" for this.`,
    );
  }

  if (type !== 'currency' && currencyCode) {
    // eslint-disable-next-line no-console
    console.warn(
      `TextInput: ignoring attempt to use currencyCode=${currencyCode} with type=${type}. This prop only applies to type="currency".`,
    );
  }

  if (type !== 'currency' && type !== 'number' && decimalPlaces != null) {
    // eslint-disable-next-line no-console
    console.warn(
      `TextInput: ignoring attempt to use decimalPlaces=${decimalPlaces} with type=${type}. This prop only applies to type="currency" and type="number".`,
    );
  }

  const mask = TYPE_TO_MASK_MAP[type] ?? customMaskOptions ?? NO_MASK;

  if (type === 'currency') {
    mask.prefix = currencyCode === 'GBP' ? '£' : '$';
    mask.numeralDecimalScale = decimalPlaces ?? 2;
  }

  if (type === 'number' && decimalPlaces != null) {
    mask.numeralDecimalScale = decimalPlaces;
  }

  return mask;
};
