"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.buildRecordFieldOptionLists = exports.deleteOptionList = exports.addOptionLists = void 0;

var _get = _interopRequireDefault(require("lodash/get"));

var _warning = _interopRequireDefault(require("warning"));

var _reducers = require("../reducers");

var _dataTypes = require("../constants/dataTypes");

var _formatHelpers = require("../helpers/formatHelpers");

var _configHelpers = require("../helpers/configHelpers");

var _actionCodes = require("../constants/actionCodes");

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

const addOptionLists = optionLists => {
  const mergedOptionLists = {};
  Object.keys(optionLists).forEach(optionListName => {
    const {
      values,
      messages
    } = optionLists[optionListName];
    mergedOptionLists[optionListName] = values.map(value => {
      const merged = {
        value
      };
      const message = messages && messages[value];

      if (message) {
        merged.message = message;
      }

      return merged;
    });
  });
  return {
    type: _actionCodes.ADD_OPTION_LISTS,
    payload: mergedOptionLists
  };
};

exports.addOptionLists = addOptionLists;

const deleteOptionList = name => ({
  type: _actionCodes.DELETE_OPTION_LIST,
  payload: name
});

exports.deleteOptionList = deleteOptionList;

const collectLeafFields = (options, path, fieldDescriptor, level, includeStructDateFields) => {
  process.env.NODE_ENV !== "production" ? (0, _warning.default)(typeof fieldDescriptor === 'object', "The value of the field descriptor at ".concat(path.join('/'), " is not an object. Did you forget a ").concat(_configHelpers.configKey, " key?")) : void 0;

  if (typeof fieldDescriptor !== 'object') {
    return;
  }

  if (path[0] === 'rel:relations-common-list' || path[0] === 'ns2:contacts_common') {
    // Skip this part.
    return;
  }

  const config = fieldDescriptor[_configHelpers.configKey];
  const dataType = (0, _get.default)(config, 'dataType');
  const childFieldNames = Object.keys(fieldDescriptor).filter(key => key !== _configHelpers.configKey);
  const isLeaf = childFieldNames.length === 0;

  if ((isLeaf || dataType === _dataTypes.DATA_TYPE_STRUCTURED_DATE) && level > 0) {
    // Add this field to the result list.
    const option = {
      value: path.join('/')
    };
    const extensionParentConfig = (0, _get.default)(config, 'extensionParentConfig');
    const messages = (0, _get.default)(config, 'messages');

    if (messages) {
      if (level > 1) {
        if (extensionParentConfig && extensionParentConfig.dataType === _dataTypes.DATA_TYPE_STRUCTURED_DATE) {
          // Construct the full label for a field inside a structured date.
          // If the level is 2, the structured date group (this field's parent) is at the top
          // level, so use the groupName message instead of the fullName.
          const messageName = level === 2 ? 'groupName' : 'fullName';
          option.fieldConfig = config;

          option.labelFormatter = (intl, opt) => (0, _formatHelpers.formatExtensionFieldName)(intl, opt.fieldConfig, messageName);
        } else {
          // Prefer the fullName message.
          option.message = messages.fullName;
        }
      } else {
        // This is a top-level field in a group. Prefer the groupName message.
        option.message = messages.groupName;
      }

      if (!option.labelFormatter && !option.message) {
        option.message = messages.name || messages.fullName;
      }
    }

    options.push(option);
  }

  if (!isLeaf && (dataType !== _dataTypes.DATA_TYPE_STRUCTURED_DATE || includeStructDateFields)) {
    childFieldNames.forEach(childFieldName => {
      collectLeafFields(options, [...path, childFieldName], fieldDescriptor[childFieldName], level + 1, includeStructDateFields);
    });
  }
};

const collectGroupFields = (options, path, fieldDescriptor, level) => {
  process.env.NODE_ENV !== "production" ? (0, _warning.default)(typeof fieldDescriptor === 'object', "The value of the field descriptor at ".concat(path.join('/'), " is not an object. Did you forget a ").concat(_configHelpers.configKey, " key?")) : void 0;

  if (typeof fieldDescriptor !== 'object') {
    return;
  }

  const config = fieldDescriptor[_configHelpers.configKey];
  const childFieldNames = Object.keys(fieldDescriptor).filter(key => key !== _configHelpers.configKey);
  const isGroup = // Omit first-level groups, which are the document parts.
  path.length > 1 && // Omit containers for repeating scalars, which will have just one child.
  childFieldNames.length > 1;

  if (isGroup && level > 0) {
    const option = {
      value: path.join('/')
    }; // Add this group to the result list.

    const messages = (0, _get.default)(config, 'messages');

    if (messages) {
      if (level > 1) {
        // Prefer the fullName message.
        option.message = messages.fullName;
      } else {
        // This is a top-level group in a group. Prefer the groupName message.
        option.message = messages.groupName;
      }

      if (!option.message) {
        option.message = messages.name || messages.fullName;
      }
    }

    options.push(option);
  } // Collect the child groups.


  childFieldNames.forEach(childFieldName => {
    collectGroupFields(options, [...path, childFieldName], fieldDescriptor[childFieldName], level + 1);
  });
};

const getRecordFieldOptions = (fields, rootPath, includeStructDateFields) => {
  const path = rootPath ? rootPath.split('/') : [];
  const rootFieldDescriptor = (0, _get.default)(fields, ['document', ...path]);
  const options = [];

  if (rootFieldDescriptor) {
    collectLeafFields(options, path, rootFieldDescriptor, 0, includeStructDateFields);
  }

  return options;
};

const getRecordGroupOptions = (fields, rootPath) => {
  const path = rootPath ? rootPath.split('/') : [];
  const rootFieldDescriptor = (0, _get.default)(fields, ['document', ...path]);
  const options = [];

  if (rootFieldDescriptor) {
    collectGroupFields(options, path, rootFieldDescriptor, 0);
  }

  return options;
};

const buildRecordFieldOptionLists = function buildRecordFieldOptionLists(config, recordType, rootPath) {
  let includeStructDateFields = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
  return (dispatch, getState) => {
    const fieldOptionListName = (0, _configHelpers.getRecordFieldOptionListName)(recordType, rootPath);
    const fieldOptionList = (0, _reducers.getOptionList)(getState(), fieldOptionListName);
    const groupOptionListName = (0, _configHelpers.getRecordGroupOptionListName)(recordType, rootPath);
    const groupOptionList = (0, _reducers.getOptionList)(getState(), groupOptionListName);

    if (fieldOptionList && groupOptionList) {
      // The option lists already exist.
      return undefined;
    }

    const fields = (0, _get.default)(config, ['recordTypes', recordType, 'fields']);
    const lists = {};

    if (!fieldOptionList) {
      lists[fieldOptionListName] = getRecordFieldOptions(fields, rootPath, includeStructDateFields);
    }

    if (!groupOptionList) {
      lists[groupOptionListName] = getRecordGroupOptions(fields, rootPath);
    }

    return dispatch({
      type: _actionCodes.ADD_OPTION_LISTS,
      payload: lists
    });
  };
};

exports.buildRecordFieldOptionLists = buildRecordFieldOptionLists;