"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _immutable = _interopRequireDefault(require("immutable"));
var _get = _interopRequireDefault(require("lodash/get"));
var _classnames = _interopRequireDefault(require("classnames"));
var _warning = _interopRequireDefault(require("warning"));
var _recordDataHelpers = require("../../helpers/recordDataHelpers");
var _RecordForm = _interopRequireDefault(require("../../../styles/cspace-ui/RecordForm.css"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function renderTemplate(component, messages, handlers) {
  const overrideProps = {};
  const type = (0, _get.default)(component, 'type');
  if (type) {
    // FIXME: Do this without looking at propTypes, so that propTypes may be removed in the
    // production build.
    // eslint-disable-next-line react/forbid-foreign-prop-types
    const {
      propTypes
    } = type;
    if (propTypes) {
      Object.keys(handlers).forEach(handlerName => {
        if (propTypes[handlerName] && !component.props[handlerName]) {
          overrideProps[handlerName] = handlers[handlerName];
        }
      });
    }
    return /*#__PURE__*/_react.default.cloneElement(component, overrideProps, _react.default.Children.map(component.props.children, child => renderTemplate(child, messages, handlers)));
  }
  return component;
}
const propTypes = {
  config: _propTypes.default.shape({
    recordTypes: _propTypes.default.object
  }),
  recordTypeConfig: _propTypes.default.shape({
    defaultForm: _propTypes.default.string,
    fields: _propTypes.default.object,
    forms: _propTypes.default.object,
    messages: _propTypes.default.object
  }),
  recordType: _propTypes.default.string.isRequired,
  vocabulary: _propTypes.default.string,
  csid: _propTypes.default.string,
  data: _propTypes.default.instanceOf(_immutable.default.Map),
  formName: _propTypes.default.string,
  readOnly: _propTypes.default.bool,
  roleNames: _propTypes.default.instanceOf(_immutable.default.List),
  subrecordData: _propTypes.default.instanceOf(_immutable.default.Map),
  onAddInstance: _propTypes.default.func,
  onCommit: _propTypes.default.func,
  onMoveInstance: _propTypes.default.func,
  onRemoveInstance: _propTypes.default.func,
  onSortInstances: _propTypes.default.func
};
const defaultProps = {
  data: _immutable.default.Map()
};
const childContextTypes = {
  config: _propTypes.default.shape({
    recordTypes: _propTypes.default.object
  }),
  formName: _propTypes.default.string,
  recordData: _propTypes.default.instanceOf(_immutable.default.Map),
  recordType: _propTypes.default.string,
  recordTypeConfig: _propTypes.default.PropTypes.shape({
    fields: _propTypes.default.object
  }),
  roleNames: _propTypes.default.instanceOf(_immutable.default.List),
  subrecordData: _propTypes.default.instanceOf(_immutable.default.Map),
  vocabulary: _propTypes.default.string,
  csid: _propTypes.default.string,
  readOnly: _propTypes.default.bool
};
class RecordForm extends _react.PureComponent {
  getChildContext() {
    const {
      config,
      csid,
      data,
      formName,
      recordType,
      recordTypeConfig,
      roleNames,
      subrecordData,
      vocabulary,
      readOnly
    } = this.props;

    // Get the csid from the data. This may differ from the csid in props, for example if a
    // urn-style csid was entered in the address bar. We always want to supply the guid-style csid
    // in the context.

    const dataCsid = (0, _recordDataHelpers.getCsid)(data);
    return {
      config,
      formName,
      readOnly,
      recordType,
      recordTypeConfig,
      roleNames,
      subrecordData,
      vocabulary,
      csid: dataCsid || csid,
      recordData: data
    };
  }
  render() {
    const {
      config,
      csid,
      data,
      formName,
      readOnly,
      recordType,
      recordTypeConfig,
      onAddInstance,
      onCommit,
      onMoveInstance,
      onRemoveInstance,
      onSortInstances
    } = this.props;
    if (!recordTypeConfig) {
      return null;
    }
    const {
      fields,
      forms,
      messages
    } = recordTypeConfig;
    const handlers = {
      onAddInstance: (path, position) => {
        onAddInstance(recordTypeConfig, csid, path, position);
      },
      onCommit: (path, value) => {
        onCommit(recordTypeConfig, csid, path, value);
      },
      onSortInstances: (path, byField) => {
        onSortInstances(config, recordTypeConfig, csid, path, byField);
      },
      onMoveInstance: (path, newPosition) => {
        onMoveInstance(recordTypeConfig, csid, path, newPosition);
      },
      onRemoveInstance: path => {
        onRemoveInstance(recordTypeConfig, csid, path);
      }
    };
    let formTemplate;
    if (formName) {
      formTemplate = (0, _get.default)(forms, [formName, 'template']);
    }
    if (!formTemplate) {
      // Try to get the configured default form.

      const defaultFormName = recordTypeConfig.defaultForm || 'default';
      if (defaultFormName) {
        formTemplate = (0, _get.default)(forms, [defaultFormName, 'template']);
      }
      process.env.NODE_ENV !== "production" ? (0, _warning.default)(formTemplate, `No form template found for form name ${formName} or default form name ${defaultFormName} in record type ${recordType}. Check the record type plugin configuration.`) : void 0;
    }
    if (typeof formTemplate === 'function') {
      const result = formTemplate(data, config);
      if (!result) {
        return null;
      }
      if (typeof result === 'string') {
        // The form template function returned a string. This will be the name of another form
        // template to use.

        formTemplate = (0, _get.default)(forms, [result, 'template']);
        process.env.NODE_ENV !== "production" ? (0, _warning.default)(formTemplate, `No form template found for computed form name ${result} for form name ${formName} in record type ${recordType}. Check the record type plugin configuration.`) : void 0;
      } else {
        if ( /*#__PURE__*/(0, _react.isValidElement)(result)) {
          // The form template function returned a React element to use.

          formTemplate = result;
        }
        process.env.NODE_ENV !== "production" ? (0, _warning.default)(formTemplate, `The computed form template for form name ${formName} in record type ${recordType} did not return a string or a React element. Check the record type plugin configuration.`) : void 0;
      }
    }
    const rootPropertyName = Object.keys(fields)[0];
    const formContent = /*#__PURE__*/_react.default.cloneElement(formTemplate, {
      readOnly,
      name: rootPropertyName,
      value: data.get(rootPropertyName),
      children: _react.default.Children.map(formTemplate.props.children, child => renderTemplate(child, messages, handlers))
    });
    const className = (0, _classnames.default)(_RecordForm.default.common, `cspace-ui-RecordForm--${recordType}`);
    return /*#__PURE__*/_react.default.createElement("div", {
      className: className
    }, formContent);
  }
}
exports.default = RecordForm;
RecordForm.propTypes = propTypes;
RecordForm.defaultProps = defaultProps;
RecordForm.childContextTypes = childContextTypes;