'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 _reactIntl = require('react-intl');

var _immutable = require('immutable');

var _immutable2 = _interopRequireDefault(_immutable);

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

var _get2 = _interopRequireDefault(_get);

var _SearchConditionInput = require('./input/SearchConditionInput');

var _SearchConditionInput2 = _interopRequireDefault(_SearchConditionInput);

var _PanelContainer = require('../../containers/layout/PanelContainer');

var _searchOperators = require('../../constants/searchOperators');

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

const messages = (0, _reactIntl.defineMessages)({
  title: {
    'id': 'advancedSearchBuilder.title',
    'defaultMessage': 'Advanced Search'
  }
});

const propTypes = {
  condition: _propTypes2.default.instanceOf(_immutable2.default.Map),
  config: _propTypes2.default.object,
  inline: _propTypes2.default.bool,
  preferredBooleanOp: _propTypes2.default.string,
  readOnly: _propTypes2.default.bool,
  recordType: _propTypes2.default.string,
  onConditionCommit: _propTypes2.default.func
};

const childContextTypes = {
  recordType: _propTypes2.default.string
};

class AdvancedSearchBuilder extends _react.Component {
  getChildContext() {
    const recordType = this.props.recordType;


    return {
      recordType
    };
  }

  componentDidMount() {
    this.normalizeCondition();
  }

  componentDidUpdate() {
    this.normalizeCondition();
  }

  normalizeCondition() {
    var _props = this.props;
    const condition = _props.condition,
          config = _props.config,
          preferredBooleanOp = _props.preferredBooleanOp,
          recordType = _props.recordType,
          onConditionCommit = _props.onConditionCommit;

    // FIXME: Uncomment this once conditions may be added by the end user.

    // if (!condition && onConditionCommit) {
    //   const defaultCondition = get(config, ['recordTypes', recordType, 'advancedSearch']);
    //
    //   if (defaultCondition) {
    //     onConditionCommit(Immutable.fromJS(defaultCondition));
    //   }
    // }

    // FIXME: There will be no need for this once conditions may be added by the end user.
    // For now do a quick and dirty merge of the (possibly normalized) condition into the
    // default, so that fields aren't unrecoverable after normalization.

    if (onConditionCommit) {
      const defaultCondition = _immutable2.default.fromJS((0, _get2.default)(config, ['recordTypes', recordType, 'advancedSearch']));

      const op = condition && condition.get('op');

      if (preferredBooleanOp && (op === _searchOperators.OP_AND || op === _searchOperators.OP_OR) && op !== preferredBooleanOp) {
        onConditionCommit(condition.set('op', preferredBooleanOp));
      } else if (defaultCondition && condition) {
        if (op !== defaultCondition.get('op') || !_immutable2.default.List.isList(condition.get('value')) || condition.get('value').size !== defaultCondition.get('value').size) {
          let mergedCondition = defaultCondition;
          let clauses;

          if (op === _searchOperators.OP_AND || op === _searchOperators.OP_OR) {
            mergedCondition = mergedCondition.set('op', op);

            clauses = condition.get('value');
          } else {
            if (preferredBooleanOp) {
              mergedCondition = mergedCondition.set('op', preferredBooleanOp);
            }

            clauses = _immutable2.default.List([condition]);
          }

          clauses.forEach(clause => {
            const targetClauses = mergedCondition.get('value');

            const index = targetClauses.findKey(targetClause => targetClause.get('path') === clause.get('path'));

            if (typeof index !== 'undefined') {
              const targetClause = targetClauses.get(index);

              let value = clause.get('value');

              if (targetClause.get('op') === _searchOperators.OP_RANGE && !_immutable2.default.List.isList(value)) {
                value = clause.get('op') === _searchOperators.OP_GTE ? _immutable2.default.List([value]) : _immutable2.default.List([undefined, value]);
              }

              mergedCondition = mergedCondition.setIn(['value', index, 'value'], value);
            }
          });

          if (!mergedCondition.equals(condition)) {
            onConditionCommit(mergedCondition);
          }
        }
      } else {
        onConditionCommit(preferredBooleanOp ? defaultCondition.set('op', preferredBooleanOp) : defaultCondition);
      }
    }
  }

  render() {
    var _props2 = this.props;
    const condition = _props2.condition,
          config = _props2.config,
          inline = _props2.inline,
          readOnly = _props2.readOnly,
          recordType = _props2.recordType,
          onConditionCommit = _props2.onConditionCommit;


    if (!condition) {
      return null;
    }

    const fieldDescriptor = (0, _get2.default)(config, ['recordTypes', recordType, 'fields']);

    const searchConditionInput = _react2.default.createElement(_SearchConditionInput2.default, {
      condition: condition,
      fields: fieldDescriptor,
      inline: inline,
      readOnly: readOnly,
      onCommit: onConditionCommit
    });

    if (inline) {
      return searchConditionInput;
    }

    const panelHeader = _react2.default.createElement(
      'h3',
      null,
      _react2.default.createElement(_reactIntl.FormattedMessage, messages.title)
    );

    return _react2.default.createElement(
      _PanelContainer.ConnectedPanel,
      {
        collapsible: true,
        header: panelHeader,
        name: 'advancedSearch',
        recordType: recordType
      },
      searchConditionInput
    );
  }
}

exports.default = AdvancedSearchBuilder;
AdvancedSearchBuilder.propTypes = propTypes;
AdvancedSearchBuilder.childContextTypes = childContextTypes;