"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.parseThenRestateHeight = exports.parseHeightInCm = exports.parseHeight = exports.parsedHeightToString = exports.inchesToString = exports.parseInches = void 0;

var _metricConversion = require("./metric-conversion");

var _function = require("./function");

const ONLY_NUMBERS_RE = /^\d+$/;
const ONLY_FEET_RE = /^\s*(\d{1,2})[\s_-]*[f'’]\D*$/i;
const ONLY_INCHES_RE = /^\s*(\d{1,3})\D*$/;
const FEET_INCHES_RE = /^([1-9])\D*(0|1|2|3|4|5|6|7|8|9|10|11)\D*$/;
const HAS_METER_UNIT = /\d+[\s_-]*m/i;
const HAS_CM_UNIT = /\d+[\s_-]*c/i;
const SINGLE_DIGIT_WITH_DECIMAL_RE = /^\d?\.\d\d*$/;
const MAX_INCHES = 120; // 10 feet (http://www.guinnessworldrecords.com/world-records/tallest-man-ever)

const MAX_CM = (0, _metricConversion.inchesToCentimeters)(MAX_INCHES);

const parseInches = string => {
  if (ONLY_FEET_RE.test(string)) {
    return parseInt(string, 10) * 12;
  }

  const onlyInches = ONLY_INCHES_RE.exec(string);
  const multiple = FEET_INCHES_RE.exec(string);

  if (onlyInches) {
    return parseInt(onlyInches[1], 10);
  }

  if (multiple) {
    const feet = parseInt(multiple[1], 10);
    const inches = parseInt(multiple[2], 10);
    return feet * 12 + inches;
  }

  return null;
};

exports.parseInches = parseInches;

const inchesToString = inches => {
  const feet = Math.floor(inches / 12);
  const inch = inches - feet * 12;
  return "".concat(feet, "'").concat(inch, "\"");
};

exports.inchesToString = inchesToString;

const parsedHeightToString = heightObj => {
  if (!heightObj) {
    return '';
  }

  const {
    unit,
    value
  } = heightObj;

  if (unit === 'cm') {
    return "".concat(value, "cm");
  }

  return inchesToString(value);
};

exports.parsedHeightToString = parsedHeightToString;

const parseHeightRaw = string => {
  if (!string) {
    return null;
  }

  if (ONLY_NUMBERS_RE.test(string) && string.length > 2) {
    return {
      value: parseInt(string, 10),
      unit: 'cm'
    };
  }

  if (HAS_METER_UNIT.test(string) || SINGLE_DIGIT_WITH_DECIMAL_RE.test(string)) {
    return {
      value: Math.round(parseFloat(string) * 100),
      unit: 'cm'
    };
  }

  if (HAS_CM_UNIT.test(string)) {
    return {
      value: parseInt(string, 10),
      unit: 'cm'
    };
  }

  const inches = parseInches(string);

  if (inches) {
    return {
      value: inches,
      unit: 'in'
    };
  }

  return null;
}; // sanity check max/min values


const parseHeight = (0, _function.singleArgMemoize)(str => {
  const result = parseHeightRaw(str);

  if (!result) {
    return null;
  }

  const {
    value,
    unit
  } = result;

  if (unit === 'in' && value > MAX_INCHES) {
    return null;
  }

  if (unit === 'cm' && value > MAX_CM) {
    return null;
  }

  return result;
});
exports.parseHeight = parseHeight;

const parseHeightInCm = str => {
  const parsed = parseHeight(str);

  if (!parsed) {
    return null;
  }

  if (parsed.unit === 'cm') {
    return parsed.value;
  }

  return Math.round((0, _metricConversion.inchesToCentimeters)(parsed.value));
};

exports.parseHeightInCm = parseHeightInCm;
const parseThenRestateHeight = (0, _function.singleArgMemoize)(str => parsedHeightToString(parseHeight(str)));
exports.parseThenRestateHeight = parseThenRestateHeight;