'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _propTypes = require('prop-types');

var _propTypes2 = _interopRequireDefault(_propTypes);

var _immutable = require('immutable');

var _immutable2 = _interopRequireDefault(_immutable);

var _get = require('lodash/get');

var _get2 = _interopRequireDefault(_get);

var _classnames = require('classnames');

var _classnames2 = _interopRequireDefault(_classnames);

var _warning = require('warning');

var _warning2 = _interopRequireDefault(_warning);

var _recordDataHelpers = require('../../helpers/recordDataHelpers');

var _RecordForm = require('../../../styles/cspace-ui/RecordForm.css');

var _RecordForm2 = _interopRequireDefault(_RecordForm);

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

function renderTemplate(component, messages, handlers) {
  const overrideProps = {};
  const type = (0, _get2.default)(component, 'type');

  if (type) {
    const propTypes = type.propTypes;

    if (propTypes) {
      Object.keys(handlers).forEach(handlerName => {
        if (propTypes[handlerName] && !component.props[handlerName]) {
          overrideProps[handlerName] = handlers[handlerName];
        }
      });
    }

    return _react2.default.cloneElement(component, overrideProps, _react2.default.Children.map(component.props.children, child => renderTemplate(child, messages, handlers)));
  }

  return component;
}

const propTypes = {
  config: _propTypes2.default.object,
  recordType: _propTypes2.default.string.isRequired,
  vocabulary: _propTypes2.default.string,
  csid: _propTypes2.default.string,
  data: _propTypes2.default.instanceOf(_immutable2.default.Map),
  formName: _propTypes2.default.string,
  readOnly: _propTypes2.default.bool,
  onAddInstance: _propTypes2.default.func,
  onCommit: _propTypes2.default.func,
  onMoveInstance: _propTypes2.default.func,
  onRemoveInstance: _propTypes2.default.func,
  onSortInstances: _propTypes2.default.func
};

const defaultProps = {
  data: _immutable2.default.Map()
};

const childContextTypes = {
  config: _propTypes2.default.object,
  recordData: _propTypes2.default.instanceOf(_immutable2.default.Map),
  recordType: _propTypes2.default.string,
  vocabulary: _propTypes2.default.string,
  csid: _propTypes2.default.string,
  readOnly: _propTypes2.default.bool
};

class RecordForm extends _react.Component {
  getChildContext() {
    var _props = this.props;
    const config = _props.config,
          csid = _props.csid,
          data = _props.data,
          recordType = _props.recordType,
          vocabulary = _props.vocabulary,
          readOnly = _props.readOnly;

    // 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,
      recordType,
      vocabulary,
      readOnly,
      csid: dataCsid || csid,
      recordData: data
    };
  }

  render() {
    var _props2 = this.props;
    const config = _props2.config,
          data = _props2.data,
          formName = _props2.formName,
          readOnly = _props2.readOnly,
          recordType = _props2.recordType,
          onAddInstance = _props2.onAddInstance,
          onCommit = _props2.onCommit,
          onMoveInstance = _props2.onMoveInstance,
          onRemoveInstance = _props2.onRemoveInstance,
          onSortInstances = _props2.onSortInstances;


    const recordTypeConfig = config.recordTypes[recordType];

    if (!recordTypeConfig) {
      return null;
    }

    const fields = recordTypeConfig.fields,
          forms = recordTypeConfig.forms,
          messages = recordTypeConfig.messages;


    const handlers = {
      onAddInstance,
      onCommit,
      onSortInstances,
      onMoveInstance,
      onRemoveInstance
    };

    let formTemplate;

    if (formName) {
      formTemplate = (0, _get2.default)(forms, [formName, 'template']);
    }

    if (!formTemplate) {
      // Try to get the configured default form.

      const defaultFormName = recordTypeConfig.defaultForm || 'default';

      if (defaultFormName) {
        formTemplate = (0, _get2.default)(forms, [defaultFormName, 'template']);
      }

      process.env.NODE_ENV !== 'production' ? (0, _warning2.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, _get2.default)(forms, [result, 'template']);

        process.env.NODE_ENV !== 'production' ? (0, _warning2.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 ((0, _react.isValidElement)(result)) {
          // The form template function returned a React element to use.

          formTemplate = result;
        }

        process.env.NODE_ENV !== 'production' ? (0, _warning2.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 = _react2.default.cloneElement(formTemplate, {
      readOnly,
      name: rootPropertyName,
      value: data.get(rootPropertyName),
      children: _react2.default.Children.map(formTemplate.props.children, child => renderTemplate(child, messages, handlers))
    });

    const className = (0, _classnames2.default)(_RecordForm2.default.common, `cspace-ui-RecordForm--${recordType}`);

    return _react2.default.createElement(
      'div',
      { className: className },
      formContent
    );
  }
}

exports.default = RecordForm;
RecordForm.propTypes = propTypes;
RecordForm.defaultProps = defaultProps;
RecordForm.childContextTypes = childContextTypes;