"use strict";

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

var _react = _interopRequireDefault(require("react"));

var _immutabilityHelper = _interopRequireDefault(require("immutability-helper"));

var _store = _interopRequireDefault(require("./stores/store"));

var _formElementsEdit = _interopRequireDefault(require("./form-elements-edit"));

var _sortableFormElements = _interopRequireDefault(require("./sortable-form-elements"));

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

function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }

const {
  PlaceHolder
} = _sortableFormElements.default;

class Preview extends _react.default.Component {
  constructor(props) {
    super(props);

    _defineProperty(this, "editModeOff", e => {
      if (this.editForm.current && !this.editForm.current.contains(e.target)) {
        this.manualEditModeOff();
      }
    });

    _defineProperty(this, "manualEditModeOff", () => {
      const {
        editElement
      } = this.props;

      if (editElement && editElement.dirty) {
        editElement.dirty = false;
        this.updateElement(editElement);
      }

      this.props.manualEditModeOff();
    });

    const {
      onLoad,
      onPost
    } = props;

    _store.default.setExternalHandler(onLoad, onPost);

    this.editForm = /*#__PURE__*/_react.default.createRef();
    this.state = {
      data: props.data || [],
      answer_data: {}
    };
    this.seq = 0;

    const onUpdate = this._onChange.bind(this);

    _store.default.subscribe(state => onUpdate(state.data));

    this.getDataById = this.getDataById.bind(this);
    this.moveCard = this.moveCard.bind(this);
    this.insertCard = this.insertCard.bind(this);
    this.setAsChild = this.setAsChild.bind(this);
    this.removeChild = this.removeChild.bind(this);
    this._onDestroy = this._onDestroy.bind(this);
  }

  componentDidMount() {
    const {
      data,
      url,
      saveUrl
    } = this.props;

    _store.default.dispatch("load", {
      loadUrl: url,
      saveUrl,
      data: data || []
    });

    document.addEventListener("mousedown", this.editModeOff);
  }

  componentWillUnmount() {
    document.removeEventListener("mousedown", this.editModeOff);
  }

  _setValue(text) {
    return text.replace(/[^A-Z0-9]+/gi, "_").toLowerCase();
  }

  updateElement(element) {
    const {
      data
    } = this.state;
    let found = false;

    for (let i = 0, len = data.length; i < len; i++) {
      if (element.id === data[i].id) {
        data[i] = element;
        found = true;
        break;
      }
    }

    if (found) {
      this.seq = this.seq > 100000 ? 0 : this.seq + 1;

      _store.default.dispatch("updateOrder", data);
    }
  }

  _onChange(data) {
    const answer_data = {};
    data.forEach(item => {
      if (item && item.readOnly && this.props.variables[item.variableKey]) {
        answer_data[item.field_name] = this.props.variables[item.variableKey];
      }
    });
    this.setState({
      data,
      answer_data
    });
  }

  _onDestroy(item) {
    if (item.childItems) {
      item.childItems.forEach(x => {
        const child = this.getDataById(x);

        if (child) {
          _store.default.dispatch("delete", child);
        }
      });
    }

    _store.default.dispatch("delete", item);
  }

  getDataById(id) {
    const {
      data
    } = this.state;
    return data.find(x => x && x.id === id);
  }

  swapChildren(data, item, child, col) {
    if (child.col !== undefined && item.id !== child.parentId) {
      return false;
    }

    if (!(child.col !== undefined && child.col !== col && item.childItems[col])) {
      // No child was assigned yet in both source and target.
      return false;
    }

    const oldId = item.childItems[col];
    const oldItem = this.getDataById(oldId);
    const oldCol = child.col; // eslint-disable-next-line no-param-reassign

    item.childItems[oldCol] = oldId;
    oldItem.col = oldCol; // eslint-disable-next-line no-param-reassign

    item.childItems[col] = child.id;
    child.col = col;

    _store.default.dispatch("updateOrder", data);

    return true;
  }

  setAsChild(item, child, col) {
    const {
      data
    } = this.state;

    if (this.swapChildren(data, item, child, col)) {
      return;
    }

    const oldParent = this.getDataById(child.parentId);
    const oldCol = child.col; // eslint-disable-next-line no-param-reassign

    item.childItems[col] = child.id;
    child.col = col; // eslint-disable-next-line no-param-reassign

    child.parentId = item.id; // eslint-disable-next-line no-param-reassign

    child.parentIndex = data.indexOf(item);

    if (oldParent) {
      oldParent.childItems[oldCol] = null;
    }

    const list = data.filter(x => x && x.parentId === item.id);
    const toRemove = list.filter(x => item.childItems.indexOf(x.id) === -1);
    let newData = data;

    if (toRemove.length) {
      // console.log('toRemove', toRemove);
      newData = data.filter(x => toRemove.indexOf(x) === -1);
    }

    if (!this.getDataById(child.id)) {
      newData.push(child);
    }

    _store.default.dispatch("updateOrder", newData);
  }

  removeChild(item, col) {
    const {
      data
    } = this.state;
    const oldId = item.childItems[col];
    const oldItem = this.getDataById(oldId);

    if (oldItem) {
      const newData = data.filter(x => x !== oldItem); // eslint-disable-next-line no-param-reassign

      item.childItems[col] = null; // delete oldItem.parentId;

      this.seq = this.seq > 100000 ? 0 : this.seq + 1;

      _store.default.dispatch("updateOrder", newData);

      this.setState({
        data: newData
      });
    }
  }

  restoreCard(item, id) {
    const {
      data
    } = this.state;
    const parent = this.getDataById(item.data.parentId);
    const oldItem = this.getDataById(id);

    if (parent && oldItem) {
      const newIndex = data.indexOf(oldItem);
      const newData = [...data]; // data.filter(x => x !== oldItem);
      // eslint-disable-next-line no-param-reassign

      parent.childItems[oldItem.col] = null;
      delete oldItem.parentId; // eslint-disable-next-line no-param-reassign

      delete item.setAsChild; // eslint-disable-next-line no-param-reassign

      delete item.parentIndex; // eslint-disable-next-line no-param-reassign

      item.index = newIndex;
      this.seq = this.seq > 100000 ? 0 : this.seq + 1;

      _store.default.dispatch("updateOrder", newData);

      this.setState({
        data: newData
      });
    }
  }

  insertCard(item, hoverIndex, id) {
    const {
      data
    } = this.state;

    if (id) {
      this.restoreCard(item, id);
    } else {
      data.splice(hoverIndex, 0, item);
      this.saveData(item, hoverIndex, hoverIndex);
    }
  }

  moveCard(dragIndex, hoverIndex) {
    const {
      data
    } = this.state;
    const dragCard = data[dragIndex];
    this.saveData(dragCard, dragIndex, hoverIndex);
  } // eslint-disable-next-line no-unused-vars


  cardPlaceHolder(dragIndex, hoverIndex) {// Dummy
  }

  saveData(dragCard, dragIndex, hoverIndex) {
    const newData = (0, _immutabilityHelper.default)(this.state, {
      data: {
        $splice: [[dragIndex, 1], [hoverIndex, 0, dragCard]]
      }
    });
    this.setState(newData);

    _store.default.dispatch("updateOrder", newData.data);
  }

  getElement(item, index) {
    if (item.custom) {
      if (!item.component || typeof item.component !== "function") {
        // eslint-disable-next-line no-param-reassign
        item.component = this.props.registry.get(item.key);
      }
    }

    const SortableFormElement = _sortableFormElements.default[item.element];

    if (SortableFormElement === null) {
      return null;
    }

    return /*#__PURE__*/_react.default.createElement(SortableFormElement, {
      id: item.id,
      seq: this.seq,
      index: index,
      moveCard: this.moveCard,
      insertCard: this.insertCard,
      mutable: false,
      parent: this.props.parent,
      editModeOn: this.props.editModeOn,
      isDraggable: true,
      key: item.id,
      sortData: item.id,
      data: item,
      getDataById: this.getDataById,
      setAsChild: this.setAsChild,
      removeChild: this.removeChild,
      _onDestroy: this._onDestroy
    });
  }

  render() {
    let classes = this.props.className;

    if (this.props.editMode) {
      classes += " is-editing";
    }

    const data = this.state.data.filter(x => !!x && !x.parentId);
    const items = data.map((item, index) => this.getElement(item, index));
    return /*#__PURE__*/_react.default.createElement("div", {
      className: classes
    }, /*#__PURE__*/_react.default.createElement("div", {
      className: "edit-form",
      ref: this.editForm
    }, this.props.editElement !== null && /*#__PURE__*/_react.default.createElement(_formElementsEdit.default, {
      showCorrectColumn: this.props.showCorrectColumn,
      files: this.props.files,
      manualEditModeOff: this.manualEditModeOff,
      preview: this,
      element: this.props.editElement,
      updateElement: this.updateElement
    })), /*#__PURE__*/_react.default.createElement("div", {
      className: "Sortable"
    }, items), /*#__PURE__*/_react.default.createElement(PlaceHolder, {
      id: "form-place-holder",
      show: items.length === 0,
      index: items.length,
      moveCard: this.cardPlaceHolder,
      insertCard: this.insertCard
    }));
  }

}

exports.default = Preview;
Preview.defaultProps = {
  showCorrectColumn: false,
  files: [],
  editMode: false,
  editElement: null,
  className: "col-md-9 react-form-builder-preview float-left"
};