'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 _reactRouter = require('react-router');

var _immutable = require('immutable');

var _immutable2 = _interopRequireDefault(_immutable);

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

var _get2 = _interopRequireDefault(_get);

var _RecordButtonBar = require('./RecordButtonBar');

var _RecordButtonBar2 = _interopRequireDefault(_RecordButtonBar);

var _RecordHeader = require('./RecordHeader');

var _RecordHeader2 = _interopRequireDefault(_RecordHeader);

var _ConfirmRecordNavigationModal = require('./ConfirmRecordNavigationModal');

var _ConfirmRecordNavigationModal2 = _interopRequireDefault(_ConfirmRecordNavigationModal);

var _ConfirmRecordDeleteModal = require('./ConfirmRecordDeleteModal');

var _ConfirmRecordDeleteModal2 = _interopRequireDefault(_ConfirmRecordDeleteModal);

var _LockRecordModal = require('./LockRecordModal');

var _LockRecordModal2 = _interopRequireDefault(_LockRecordModal);

var _HierarchyReparentNotifier = require('./HierarchyReparentNotifier');

var _HierarchyReparentNotifier2 = _interopRequireDefault(_HierarchyReparentNotifier);

var _RecordFormContainer = require('../../containers/record/RecordFormContainer');

var _RecordFormContainer2 = _interopRequireDefault(_RecordFormContainer);

var _permissionHelpers = require('../../helpers/permissionHelpers');

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

var _workflowStateHelpers = require('../../helpers/workflowStateHelpers');

var _RecordEditor = require('../../../styles/cspace-ui/RecordEditor.css');

var _RecordEditor2 = _interopRequireDefault(_RecordEditor);

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

const propTypes = {
  config: _propTypes2.default.object,
  recordType: _propTypes2.default.string.isRequired,
  vocabulary: _propTypes2.default.string,
  csid: _propTypes2.default.string,
  cloneCsid: _propTypes2.default.string,
  data: _propTypes2.default.instanceOf(_immutable2.default.Map),
  dockTop: _propTypes2.default.number,
  formName: _propTypes2.default.string,
  perms: _propTypes2.default.instanceOf(_immutable2.default.Map),
  validationErrors: _propTypes2.default.instanceOf(_immutable2.default.Map),
  vocabularyWorkflowState: _propTypes2.default.string,
  isModified: _propTypes2.default.bool,
  isReadPending: _propTypes2.default.bool,
  isSavePending: _propTypes2.default.bool,
  isHardDelete: _propTypes2.default.bool,
  // The workflow state of the related subject (aka primary) record when we're in a secondary tab.
  relatedSubjectWorkflowState: _propTypes2.default.string,
  openModalName: _propTypes2.default.string,
  checkForRelations: _propTypes2.default.func,
  checkForUses: _propTypes2.default.func,
  createNewRecord: _propTypes2.default.func,
  readRecord: _propTypes2.default.func,
  onRecordCreated: _propTypes2.default.func,
  onRecordSaved: _propTypes2.default.func,
  onSaveCancelled: _propTypes2.default.func,
  closeModal: _propTypes2.default.func,
  openModal: _propTypes2.default.func,
  deleteRecord: _propTypes2.default.func,
  save: _propTypes2.default.func,
  saveWithTransition: _propTypes2.default.func,
  revert: _propTypes2.default.func,
  clone: _propTypes2.default.func,
  transitionRecord: _propTypes2.default.func,
  removeNotification: _propTypes2.default.func,
  removeValidationNotification: _propTypes2.default.func,
  setForm: _propTypes2.default.func,
  validateRecordData: _propTypes2.default.func,
  onRecordDeleted: _propTypes2.default.func,
  onRecordTransitioned: _propTypes2.default.func
};

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

class RecordEditor extends _react.Component {
  constructor() {
    super();

    // Confirm delete modal button handlers.

    this.handleConfirmDeleteButtonClick = this.handleConfirmDeleteButtonClick.bind(this);

    // Confirm navigation modal button handlers.

    this.handleConfirmNavigationSaveButtonClick = this.handleConfirmNavigationSaveButtonClick.bind(this);

    this.handleConfirmNavigationRevertButtonClick = this.handleConfirmNavigationRevertButtonClick.bind(this);

    // Lock modal button handlers.

    this.handleSaveOnlyButtonClick = this.handleSaveOnlyButtonClick.bind(this);
    this.handleSaveLockButtonClick = this.handleSaveLockButtonClick.bind(this);

    // Shared modal handlers.

    this.handleModalCancelButtonClick = this.handleModalCancelButtonClick.bind(this);

    // Button bar handlers.

    this.handleDeprecateButtonClick = this.handleDeprecateButtonClick.bind(this);
    this.handleSaveButtonClick = this.handleSaveButtonClick.bind(this);
    this.handleSaveButtonErrorBadgeClick = this.handleSaveButtonErrorBadgeClick.bind(this);
    this.handleRevertButtonClick = this.handleRevertButtonClick.bind(this);
    this.handleCloneButtonClick = this.handleCloneButtonClick.bind(this);
    this.handleDeleteButtonClick = this.handleDeleteButtonClick.bind(this);
    this.handleRecordFormSelectorCommit = this.handleRecordFormSelectorCommit.bind(this);
    this.handleUndeprecateButtonClick = this.handleUndeprecateButtonClick.bind(this);
  }

  componentDidMount() {
    this.initRecord();
  }

  componentDidUpdate(prevProps) {
    var _props = this.props;
    const recordType = _props.recordType,
          vocabulary = _props.vocabulary,
          csid = _props.csid,
          cloneCsid = _props.cloneCsid;
    const prevRecordType = prevProps.recordType,
          prevVocabulary = prevProps.vocabulary,
          prevCsid = prevProps.csid,
          prevCloneCsid = prevProps.cloneCsid;


    if (recordType !== prevRecordType || vocabulary !== prevVocabulary || csid !== prevCsid || cloneCsid !== prevCloneCsid) {
      this.initRecord();
    }
  }

  componentWillUnmount() {
    var _props2 = this.props;
    const removeNotification = _props2.removeNotification,
          removeValidationNotification = _props2.removeValidationNotification;


    if (removeValidationNotification) {
      removeValidationNotification();
    }

    if (removeNotification) {
      removeNotification(_HierarchyReparentNotifier2.default.notificationID);
    }
  }

  initRecord() {
    var _props3 = this.props;
    const csid = _props3.csid,
          cloneCsid = _props3.cloneCsid,
          createNewRecord = _props3.createNewRecord,
          readRecord = _props3.readRecord,
          removeValidationNotification = _props3.removeValidationNotification;


    if (removeValidationNotification) {
      removeValidationNotification();
    }

    if (csid) {
      if (readRecord) {
        readRecord();
      }
    } else if (createNewRecord) {
      createNewRecord(cloneCsid);
    }
  }

  save(onRecordCreated) {
    var _props4 = this.props;
    const config = _props4.config,
          recordType = _props4.recordType,
          openModal = _props4.openModal,
          save = _props4.save,
          saveWithTransition = _props4.saveWithTransition;


    const recordTypeConfig = config.recordTypes[recordType];
    const lockOnSave = recordTypeConfig.lockOnSave;


    if (lockOnSave === 'prompt' && openModal) {
      openModal(_LockRecordModal2.default.modalName);

      return false;
    }

    if (lockOnSave === true && saveWithTransition) {
      saveWithTransition('lock', onRecordCreated);
    } else if (save) {
      save(onRecordCreated).then(() => {
        const onRecordSaved = this.props.onRecordSaved;


        if (onRecordSaved) {
          onRecordSaved();
        }
      });
    }

    return true;
  }

  handleModalCancelButtonClick(event) {
    var _props5 = this.props;
    const closeModal = _props5.closeModal,
          onSaveCancelled = _props5.onSaveCancelled;


    if (closeModal) {
      event.stopPropagation();

      closeModal(false);
    }

    if (onSaveCancelled) {
      onSaveCancelled();
    }
  }

  handleUndeprecateButtonClick() {
    var _props6 = this.props;
    const transitionRecord = _props6.transitionRecord,
          onRecordTransitioned = _props6.onRecordTransitioned;


    const transitionName = 'undeprecate';

    if (transitionRecord) {
      transitionRecord(transitionName).then(() => {
        if (onRecordTransitioned) {
          onRecordTransitioned(transitionName);
        }
      });
    }
  }

  handleDeprecateButtonClick() {
    var _props7 = this.props;
    const transitionRecord = _props7.transitionRecord,
          onRecordTransitioned = _props7.onRecordTransitioned;


    const transitionName = 'deprecate';

    if (transitionRecord) {
      transitionRecord(transitionName).then(() => {
        if (onRecordTransitioned) {
          onRecordTransitioned(transitionName);
        }
      });
    }
  }

  handleConfirmDeleteButtonClick() {
    var _props8 = this.props;
    const closeModal = _props8.closeModal,
          isHardDelete = _props8.isHardDelete,
          deleteRecord = _props8.deleteRecord,
          onRecordDeleted = _props8.onRecordDeleted,
          transitionRecord = _props8.transitionRecord,
          onRecordTransitioned = _props8.onRecordTransitioned;


    if (isHardDelete) {
      if (deleteRecord) {
        deleteRecord().then(() => {
          if (closeModal) {
            closeModal(true);
          }

          if (onRecordDeleted) {
            onRecordDeleted();
          }
        });
      }
    } else {
      const transitionName = 'delete';

      if (transitionRecord) {
        transitionRecord(transitionName).then(() => {
          if (closeModal) {
            closeModal(true);
          }

          if (onRecordTransitioned) {
            onRecordTransitioned(transitionName);
          }
        });
      }
    }
  }

  handleConfirmNavigationSaveButtonClick() {
    var _props9 = this.props;
    const closeModal = _props9.closeModal,
          onRecordCreated = _props9.onRecordCreated;

    // Wrap the onRecordCreated callback in a function that sets isNavigating to true. This lets
    // the callback know that we're already navigating away, so it should not do any navigation
    // of its own.

    const callback = onRecordCreated ? newRecordCsid => {
      onRecordCreated(newRecordCsid, true);
    } : undefined;

    const saveCalled = this.save(callback);

    if (saveCalled && closeModal) {
      closeModal(true);
    }
  }

  handleConfirmNavigationRevertButtonClick() {
    var _props10 = this.props;
    const closeModal = _props10.closeModal,
          revert = _props10.revert;


    if (revert) {
      revert();
    }

    if (closeModal) {
      closeModal(true);
    }
  }

  handleCloneButtonClick() {
    var _props11 = this.props;
    const clone = _props11.clone,
          csid = _props11.csid;


    if (clone) {
      clone(csid);
    }
  }

  handleDeleteButtonClick() {
    const openModal = this.props.openModal;


    if (openModal) {
      openModal(_ConfirmRecordDeleteModal2.default.modalName);
    }
  }

  handleRevertButtonClick() {
    const revert = this.props.revert;


    if (revert) {
      revert();
    }
  }

  handleSaveButtonClick() {
    const onRecordCreated = this.props.onRecordCreated;


    this.save(onRecordCreated);
  }

  handleSaveButtonErrorBadgeClick() {
    const validateRecordData = this.props.validateRecordData;


    if (validateRecordData) {
      validateRecordData();
    }
  }

  handleSaveOnlyButtonClick() {
    var _props12 = this.props;
    const save = _props12.save,
          closeModal = _props12.closeModal,
          onRecordCreated = _props12.onRecordCreated;


    if (save) {
      save(onRecordCreated).then(() => {
        if (closeModal) {
          closeModal(true);
        }
      });
    }
  }

  handleSaveLockButtonClick() {
    var _props13 = this.props;
    const saveWithTransition = _props13.saveWithTransition,
          closeModal = _props13.closeModal,
          onRecordCreated = _props13.onRecordCreated;


    if (saveWithTransition) {
      saveWithTransition('lock', onRecordCreated).then(() => {
        if (closeModal) {
          closeModal(true);
        }
      });
    }
  }

  handleRecordFormSelectorCommit(path, value) {
    const setForm = this.props.setForm;


    if (setForm) {
      setForm(value);
    }
  }

  renderConfirmNavigationModal() {
    var _props14 = this.props;
    const isModified = _props14.isModified,
          isSavePending = _props14.isSavePending,
          openModalName = _props14.openModalName,
          validationErrors = _props14.validationErrors;


    return _react2.default.createElement(_ConfirmRecordNavigationModal2.default, {
      isOpen: openModalName === _ConfirmRecordNavigationModal2.default.modalName,
      isModified: isModified,
      isSavePending: isSavePending,
      validationErrors: validationErrors,
      onCancelButtonClick: this.handleModalCancelButtonClick,
      onCloseButtonClick: this.handleModalCancelButtonClick,
      onSaveButtonClick: this.handleConfirmNavigationSaveButtonClick,
      onSaveButtonErrorBadgeClick: this.handleSaveButtonErrorBadgeClick,
      onRevertButtonClick: this.handleConfirmNavigationRevertButtonClick
    });
  }

  renderConfirmRecordDeleteModal() {
    var _props15 = this.props;
    const config = _props15.config,
          csid = _props15.csid,
          data = _props15.data,
          isSavePending = _props15.isSavePending,
          openModalName = _props15.openModalName,
          recordType = _props15.recordType,
          vocabulary = _props15.vocabulary,
          checkForRelations = _props15.checkForRelations,
          checkForUses = _props15.checkForUses;


    return _react2.default.createElement(_ConfirmRecordDeleteModal2.default, {
      config: config,
      csid: csid,
      data: data,
      isOpen: openModalName === _ConfirmRecordDeleteModal2.default.modalName,
      isSavePending: isSavePending,
      recordType: recordType,
      vocabulary: vocabulary,
      checkForRelations: checkForRelations,
      checkForUses: checkForUses,
      onCancelButtonClick: this.handleModalCancelButtonClick,
      onCloseButtonClick: this.handleModalCancelButtonClick,
      onDeleteButtonClick: this.handleConfirmDeleteButtonClick
    });
  }

  renderLockRecordModal() {
    var _props16 = this.props;
    const config = _props16.config,
          csid = _props16.csid,
          isSavePending = _props16.isSavePending,
          openModalName = _props16.openModalName,
          recordType = _props16.recordType;


    const recordTypeConfig = config.recordTypes[recordType];
    const lockOnSave = recordTypeConfig.lockOnSave;


    if (lockOnSave !== 'prompt') {
      return null;
    }

    return _react2.default.createElement(_LockRecordModal2.default, {
      csid: csid,
      isOpen: openModalName === _LockRecordModal2.default.modalName,
      isSavePending: isSavePending,
      onCancelButtonClick: this.handleModalCancelButtonClick,
      onCloseButtonClick: this.handleModalCancelButtonClick,
      onSaveOnlyButtonClick: this.handleSaveOnlyButtonClick,
      onSaveLockButtonClick: this.handleSaveLockButtonClick
    });
  }

  render() {
    var _props17 = this.props;
    const config = _props17.config,
          csid = _props17.csid,
          data = _props17.data,
          dockTop = _props17.dockTop,
          formName = _props17.formName,
          isModified = _props17.isModified,
          isReadPending = _props17.isReadPending,
          isSavePending = _props17.isSavePending,
          perms = _props17.perms,
          recordType = _props17.recordType,
          relatedSubjectWorkflowState = _props17.relatedSubjectWorkflowState,
          validationErrors = _props17.validationErrors,
          vocabulary = _props17.vocabulary,
          vocabularyWorkflowState = _props17.vocabularyWorkflowState;


    const recordTypeConfig = config.recordTypes[recordType];

    if (!recordTypeConfig) {
      return null;
    }

    const selectedFormName = formName || recordTypeConfig.defaultForm || 'default';
    const relatedSubjectLocked = (0, _workflowStateHelpers.isLocked)(relatedSubjectWorkflowState);
    const vocabularyLocked = (0, _workflowStateHelpers.isLocked)(vocabularyWorkflowState);
    const immutable = (0, _recordDataHelpers.isRecordImmutable)(data);

    const readOnly = isReadPending || immutable || !(csid ? (0, _permissionHelpers.canUpdate)(recordType, perms) : (0, _permissionHelpers.canCreate)(recordType, perms));

    const isCloneable =
    // The record must be saved.
    !!csid && !vocabularyLocked &&
    // If we're editing an object record in a secondary tab, and the primary record is locked,
    // a new cloned record would not be able to be related to the primary, so the clone
    // button should not appear.
    !relatedSubjectLocked &&
    // We must have permission to create a new record of the type.
    (0, _permissionHelpers.canCreate)(recordType, perms);

    const isDeletable = !!csid && !immutable && !vocabularyLocked && (
    // Security resources don't have soft-delete, so also need to check hard delete.
    (0, _permissionHelpers.canSoftDelete)(recordType, perms) || (0, _permissionHelpers.canDelete)(recordType, perms));

    const serviceType = (0, _get2.default)(recordTypeConfig, ['serviceConfig', 'serviceType']);
    const showDeprecationButtons = config.termDeprecationEnabled && serviceType === 'authority';
    const isDeprecated = (0, _recordDataHelpers.isRecordDeprecated)(data);

    return _react2.default.createElement(
      'form',
      { className: _RecordEditor2.default.common, autoComplete: 'off' },
      _react2.default.createElement(_RecordHeader2.default, {
        config: config,
        data: data,
        dockTop: dockTop,
        formName: selectedFormName,
        isCloneable: isCloneable,
        isDeletable: isDeletable,
        isDeprecated: isDeprecated,
        isModified: isModified,
        isReadPending: isReadPending,
        isSavePending: isSavePending,
        readOnly: readOnly,
        recordType: recordType,
        showDeprecationButtons: showDeprecationButtons,
        validationErrors: validationErrors,
        onCloneButtonClick: this.handleCloneButtonClick,
        onCommit: this.handleRecordFormSelectorCommit,
        onDeprecateButtonClick: this.handleDeprecateButtonClick,
        onDeleteButtonClick: this.handleDeleteButtonClick,
        onSaveButtonClick: this.handleSaveButtonClick,
        onSaveButtonErrorBadgeClick: this.handleSaveButtonErrorBadgeClick,
        onRevertButtonClick: this.handleRevertButtonClick,
        onUndeprecateButtonClick: this.handleUndeprecateButtonClick
      }),
      _react2.default.createElement(_RecordFormContainer2.default, {
        config: config,
        csid: csid,
        data: data,
        formName: selectedFormName,
        readOnly: readOnly,
        recordType: recordType,
        vocabulary: vocabulary
      }),
      _react2.default.createElement(
        'footer',
        null,
        _react2.default.createElement(_RecordButtonBar2.default, {
          isCloneable: isCloneable,
          isDeletable: isDeletable,
          isDeprecated: isDeprecated,
          isModified: isModified,
          isReadPending: isReadPending,
          isSavePending: isSavePending,
          readOnly: readOnly,
          showDeprecationButtons: showDeprecationButtons,
          validationErrors: validationErrors,
          onSaveButtonClick: this.handleSaveButtonClick,
          onSaveButtonErrorBadgeClick: this.handleSaveButtonErrorBadgeClick,
          onRevertButtonClick: this.handleRevertButtonClick,
          onCloneButtonClick: this.handleCloneButtonClick,
          onDeleteButtonClick: this.handleDeleteButtonClick
        })
      ),
      _react2.default.createElement(_reactRouter.Prompt, {
        when: isModified && !isSavePending,
        message: _ConfirmRecordNavigationModal2.default.modalName
      }),
      this.renderConfirmNavigationModal(),
      this.renderConfirmRecordDeleteModal(),
      this.renderLockRecordModal()
    );
  }
}

exports.default = RecordEditor;
RecordEditor.propTypes = propTypes;
RecordEditor.defaultProps = defaultProps;