Source: app/validation/formikValidation.js

import { number } from 'yup';
import marketConfig from '../config/market/market.configdefinitions';
import MembershipCard from '../data/enum/MembershipCard';
import GroupSearchType from '../data/enum/GroupSearchType';
import {
  EXTRACT_BOTH_PARTS_OF_UK_POSTCODE_REGEX,
  FIRST_POSTCODE_PART,
  MATCH_WHITESPACE,
} from '../data/regexPatterns';
// import { regexTester, bmiLowRule, bmiDangerousRule, usernameMinLength } from './validationUtils';
import WeightHeightRanges from '../data/enum/WeightHeightRanges';

/*
 * These function are to be used together with yups .test
 */

/**
 * Check if a member is entering a valid card number
 *
 * @returns rule name, rule error message locale and rule function
 * @example groupCard: Yup.string().test(membershipCardValid),
 */
export const membershipCardValid = {
  name: 'membershipCardValid',
  message: 'validation.errors.cardNumber.range',
  test: value => {
    const removedSpacesValue = value && value.replace(MATCH_WHITESPACE, '');
    if (removedSpacesValue === '' || removedSpacesValue === undefined) return true;
    return (
      `${removedSpacesValue}`.length === MembershipCard.CARD_MIN_LENGTH ||
      `${removedSpacesValue}`.length === MembershipCard.CARD_MAX_LENGTH
    );
  },
};

/**
 * Check if a member is entering a valid postcode
 *
 * @returns rule name, rule error message locale and rule function
 * @example postcode: Yup.string().test(postcodeValid)
 */
export const postcodeValid = {
  name: 'postcodeValid',
  message: 'validation.errors.postcode.formatError',
  test: value => {
    if (value === '' || value === undefined || marketConfig.dropDownBasedGroupSearch) return true;
    const match = value.trim().match(EXTRACT_BOTH_PARTS_OF_UK_POSTCODE_REGEX);
    return match && match.length === 3;
  },
};

/**
 * Check if a value matches a search type (e.g. a postcode or place)
 * Return the relevant enum
 * @returns string
 */

export const detectGroupSearchType = value => {
  if (value && value.length > 2) {
    return FIRST_POSTCODE_PART.test(value) ? GroupSearchType.POSTCODE : GroupSearchType.PLACE;
  }
  return GroupSearchType.UNKNOWN;
};

export const weightLowerRange = {
  name: 'weightLowerRange',
  message: 'validation.errors.initialWeight.tooLow',
  test: value => {
    if (value) {
      return value > WeightHeightRanges.WEIGHT_LOWER_LIMIT;
    }
    return true;
  },
};

export const weightUpperRange = {
  name: 'weightUpperRange',
  message: 'validation.errors.initialWeight.tooHigh',
  test: value => {
    if (value) {
      return value < WeightHeightRanges.WEIGHT_UPPER_LIMIT;
    }
    return true;
  },
};

function emptyStringToNull(value, originalValue) {
  if (typeof originalValue === 'string' && originalValue === '') {
    return null;
  }
  return value;
}

// Make expandable
export const weightInputValidationSchema = {
  stones: number(),
  fullPounds: number()
    .max(13, 'validation.errors.lbs.maxExceeded')
    .transform(emptyStringToNull)
    .nullable(),
  kilos: number()
    .transform(emptyStringToNull)
    .nullable(),
  grams: number()
    .max(99)
    .transform(emptyStringToNull)
    .nullable(),
};