import _regeneratorRuntime from "@babel/runtime/regenerator";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";

/* eslint-disable */
import dotProp from 'dot-prop-immutable';
import undoable from 'redux-undo';
import { i18n } from '@fishx/i18n';
import { cloneElement, createElement, addElementToParent, createRow, cssToSetting, loadTheme, matchCodePrefix, deleteFormSettingsInBlockElement } from "../editor/utils";
import { getContent, getElementWithChildren, getParentElementWithChildren, getContainerElementWithChildren } from "../editor/selectors"; // import { getPlugins } from "@whalecloud/page-builder/plugins/index";

import cloneDeep from "lodash/cloneDeep";
import { getNewState, distributeColumnWidths } from "../utils/util";
import { formBuilderConfig } from "../config/config";
import { transformBlockToJson } from "../utils/blockUtil";

var deleteElementFromParent = function deleteElementFromParent(globalState, element, target) {
  var parent = getParentElementWithChildren(globalState, element.id); // Remove child from parent

  if (!parent) {
    return;
  }

  if (target && target.id === parent.id) {
    parent = target;
  }

  var childIndex = parent.elements.findIndex(function (el) {
    return el.id === element.id;
  });

  if (parent.type === 'row' && parent.elements.length <= 2) {
    var grandParent = getParentElementWithChildren(globalState, parent.id);

    if (target && target.id === grandParent.id) {
      grandParent = target;
    }

    var index = grandParent.elements.findIndex(function (el) {
      return el.id === parent.id;
    });

    if (parent.elements.length <= 1) {
      grandParent = dotProp.delete(grandParent, "elements.".concat(index));
    } else {
      var targetElement = parent.elements[parent.elements.length - 1 - childIndex];
      targetElement.data.settings.cols = {
        span: 24
      };
      grandParent = dotProp.set(grandParent, "elements.".concat(index), targetElement);
    }

    return grandParent;
  }

  parent = dotProp.delete(parent, "elements.".concat(childIndex));

  if (parent.type === 'row') {
    parent = distributeColumnWidths(parent);

    if (target && target.path.length < parent.path.length) {
      var _index = target.elements.findIndex(function (el) {
        return el.id === parent.id;
      });

      if (_index > -1) {
        target = dotProp.set(target, "elements.".concat(_index), parent);
        return target;
      }
    }
  }

  if (target && target.path.length > parent.path.length) {
    var _index2 = parent.elements.findIndex(function (el) {
      return el.id === target.id;
    });

    if (_index2 > -1) {
      parent = dotProp.set(parent, "elements.".concat(_index2), target);
      return parent;
    }
  }

  return parent;
};

var updateFormInstanceById = function updateFormInstanceById(content, id, formInstance) {
  if (content) {
    if (content.id === id) {
      content.data.formInstance = formInstance;
      return true;
    } else if (content.elements) {
      for (var i = 0; i < content.elements.length; i += 1) {
        var item = content.elements[i];
        var update = updateFormInstanceById(item, id, formInstance);

        if (update) {
          break;
        }
      }
    }
  }
};

var handleBlockContainerDrop = function handleBlockContainerDrop(source, target, payloadTarget, direction, globalState) {
  // 当前source对应的element
  var element; // 最终的element

  var targetElement = target;
  var opts = {};

  if (target.type === 'table') {
    var _target$elements = target.elements,
        elements = _target$elements === void 0 ? [] : _target$elements;
    opts = {
      data: {
        componentSettings: {
          dataIndex: "newColumn-".concat(elements.length),
          key: elements.length.toString(),
          title: i18n('PAGEBUIDER_EDITOR_TABLE_HEADER_CELL')
        }
      }
    };
  }

  if (source.path) {
    element = cloneElement(source);

    if (['top', 'bottom'].includes(direction)) {
      element.data.settings.cols = {
        span: 24,
        offset: 0
      };
    }
  } else {
    element = createElement(source.type, opts, target);
  }

  var container = getContainerElementWithChildren(globalState, target.id);

  if (container.type !== 'form') {
    // 普通容器内的元素，删除data.formSettings
    element = deleteFormSettingsInBlockElement(element);
  }

  var position = payloadTarget.position,
      positionId = payloadTarget.positionId;
  var targetEle;

  if (positionId) {
    if (['left', 'right'].includes(direction)) {
      // 水平方向直接插入row内
      targetEle = target.elements.find(function (v, index) {
        if (v.id === positionId) {
          targetEle = v;
          position = index;
        }

        return v.id === positionId;
      });
    } else if (target.type === 'row') {
      // 垂直方向需要插入row外
      targetElement = getParentElementWithChildren(globalState, target.id);
      targetEle = target;
      position = targetElement.elements.findIndex(function (v) {
        return v.id === target.id;
      });
    } else {
      position = targetElement.elements.findIndex(function (v) {
        return v.id === positionId;
      });
      targetEle = targetElement.elements[position];
    }
  } else if (/^\d+$/.test(position)) {
    targetEle = target.elements[position];
  } else {
    position = target.elements.length;
    targetEle = target.elements[position];
  }

  if (['right', 'bottom'].includes(direction)) {
    position += 1;
  } // 处理水平排列,水平最多存放4个控件


  if (['left', 'right'].includes(direction)) {
    // 判断目标元素外层是否存在Row行组件
    if (target.type !== 'row' && !['table', 'headerCell', 'button', 'rowCell'].includes(target.type)) {
      var childs = direction === 'left' ? [element, targetEle] : [targetEle, element];
      var row = createRow({
        elements: childs
      }); // 平均分配栅格

      row = distributeColumnWidths(row); // 删除原目标

      targetElement = dotProp.delete(targetElement, "elements.".concat(['right', 'bottom'].includes(direction) ? position - 1 : position));
      targetElement = addElementToParent(row, targetElement, position);
    } else {
      targetElement = addElementToParent(element, targetElement, position); // 平均分配栅格

      targetElement = distributeColumnWidths(targetElement);
    }
  } else {
    targetElement = addElementToParent(element, targetElement, position);
  }

  if (source.path) {
    // 删除
    targetElement = deleteElementFromParent(globalState, source, targetElement);
  }

  return {
    element: element,
    targetElement: targetElement
  };
};

export default {
  namespace: 'appBuilder',
  state: {
    config: formBuilderConfig,
    page: {},
    initialData: {},
    elements: {},
    pageContent: {},
    layoutDetail: {},
    rootElement: {},
    formData: []
  },
  reducers: [{
    save: function save(state, _ref) {
      var payload = _ref.payload;
      return _objectSpread(_objectSpread({}, state), payload);
    },
    changePage: function changePage(state, _ref2) {
      var payload = _ref2.payload;
      return _objectSpread(_objectSpread({}, state), {}, {
        page: _objectSpread(_objectSpread({}, state.page), payload)
      });
    },
    flattenElements: function flattenElements(state, _ref3) {
      var payload = _ref3.payload;
      var content = payload.content;
      var newState = getNewState(state, content); // const elements = getFlattenElements(newState);

      return _objectSpread(_objectSpread({}, state), newState);
    },
    flattenRootElement: function flattenRootElement(state) {
      var rootElement = state.elements[getContent(state).id];
      return _objectSpread(_objectSpread({}, state), {}, {
        rootElement: rootElement
      });
    },
    updateElement: function updateElement(state, _ref4) {
      var payload = _ref4.payload;
      var element = payload.element;
      var newState = getNewState(state, element);
      return _objectSpread(_objectSpread({}, state), newState);
    },
    updateAndFlattenElement: function updateAndFlattenElement(state, _ref5) {
      var payload = _ref5.payload;
      var element = payload.element;
      var newState = getNewState(state, element);
      return _objectSpread(_objectSpread({}, state), newState);
    },
    dropElement: function dropElement(state, _ref6) {
      var payload = _ref6.payload;
      var _payload$direction = payload.direction,
          direction = _payload$direction === void 0 ? 'vertical' : _payload$direction;
      var globalState = {
        appBuilder: state
      };
      var target = getElementWithChildren(globalState, payload.target.id);

      if (!target) {
        return state;
      } // const targetPlugin = getPlugins('pb-editor-page-element').find(pl => pl.elementType === target.type);
      // if (!targetPlugin) {
      //   return state;
      // }


      var source = payload.source;

      if (source.path) {
        source = getElementWithChildren(globalState, source.id);
      }

      var _handleBlockContainer = handleBlockContainerDrop(source, target, payload.target, direction, globalState),
          element = _handleBlockContainer.element,
          targetElement = _handleBlockContainer.targetElement;

      var newState = getNewState(state, cloneDeep(targetElement));
      return _objectSpread(_objectSpread({}, state), newState);
    },
    updateFormElement: function updateFormElement(state, _ref7) {
      var payload = _ref7.payload;
      var element = payload.element;
      var elements = state.elements,
          _state$page = state.page;
      _state$page = _state$page === void 0 ? {} : _state$page;
      var _state$page$content = _state$page.content,
          content = _state$page$content === void 0 ? {} : _state$page$content;

      if (elements[element.id]) {
        elements[element.id].data = element.data; // update content

        updateFormInstanceById(content, element.id, element.data.formInstance);
      }

      return _objectSpread(_objectSpread({}, state), {}, {
        elements: elements,
        page: {
          content: content
        }
      });
    },
    reset: function reset(state) {
      // const newState = state;
      var newState = {
        page: {},
        elements: {},
        initialData: {},
        pageContent: {},
        layoutDetail: {},
        rootElement: {},
        formData: [],
        past: [],
        future: [],
        present: {
          config: state.config || formBuilderConfig,
          page: {},
          elements: {},
          pageContent: {},
          layoutDetail: {},
          rootElement: {},
          formData: []
        }
      };
      return _objectSpread(_objectSpread({}, state), newState);
    }
  }, function (reducer) {
    return function (state, action) {
      var newState = undoable(reducer, {
        filter: function filterActions(action, currentState, previousHistory) {
          return ['appBuilder/dropElement', 'appBuilder/updateAndFlattenElement'].includes(action.type);
        }
      })(state, action);
      var present = newState.present;
      return _objectSpread(_objectSpread({}, newState), present);
    };
  }],
  effects: {
    setInitialPageJson: /*#__PURE__*/_regeneratorRuntime.mark(function setInitialPageJson(_ref8, _ref9) {
      var payload, put, select, content, globalState, _ref10, _ref10$allBlocks, allBlocks, _globalState$appBuild, config, newContent, deviceType, currentPage, _cssToSetting, _cssToSetting$tempora, temporary, _cssToSetting$custom, custom, _cssToSetting$page, page, _content$theme, name, url;

      return _regeneratorRuntime.wrap(function setInitialPageJson$(_context) {
        while (1) {
          switch (_context.prev = _context.next) {
            case 0:
              payload = _ref8.payload;
              put = _ref9.put, select = _ref9.select;
              content = payload.content;
              _context.next = 5;
              return select(function (state) {
                return state;
              });

            case 5:
              globalState = _context.sent;
              _ref10 = globalState.globalUI || {}, _ref10$allBlocks = _ref10.allBlocks, allBlocks = _ref10$allBlocks === void 0 ? [] : _ref10$allBlocks;
              _globalState$appBuild = globalState.appBuilder.config, config = _globalState$appBuild === void 0 ? {} : _globalState$appBuild;
              newContent = !config.isBlock ? transformBlockToJson(content, allBlocks) : content; // preview type: pc/mobile/pad

              _context.next = 11;
              return select(function (state) {
                return state.ui.previewDevice;
              });

            case 11:
              deviceType = _context.sent;
              newContent.data['className'] = matchCodePrefix[deviceType];
              _context.next = 15;
              return put({
                type: 'flattenElements',
                payload: _objectSpread(_objectSpread({}, payload), {}, {
                  content: newContent
                })
              });

            case 15:
              if (!content.css) {
                _context.next = 24;
                break;
              }

              _context.next = 18;
              return select(function (state) {
                var _state$appBuilder$con;

                return (_state$appBuilder$con = state.appBuilder.config) === null || _state$appBuilder$con === void 0 ? void 0 : _state$appBuilder$con.currentPage;
              });

            case 18:
              currentPage = _context.sent;
              _cssToSetting = cssToSetting(content.css, currentPage), _cssToSetting$tempora = _cssToSetting.temporary, temporary = _cssToSetting$tempora === void 0 ? {} : _cssToSetting$tempora, _cssToSetting$custom = _cssToSetting.custom, custom = _cssToSetting$custom === void 0 ? {} : _cssToSetting$custom, _cssToSetting$page = _cssToSetting.page, page = _cssToSetting$page === void 0 ? {} : _cssToSetting$page;
              _context.next = 22;
              return put({
                type: 'style/save',
                payload: {
                  customStyle: custom,
                  temporaryStyle: temporary,
                  pageStyle: page
                }
              });

            case 22:
              _context.next = 26;
              break;

            case 24:
              _context.next = 26;
              return put({
                type: 'style/save',
                payload: {
                  temporaryStyle: {},
                  pageStyle: {}
                }
              });

            case 26:
              if (!(content !== null && content !== void 0 && content.theme)) {
                _context.next = 31;
                break;
              }

              _content$theme = content === null || content === void 0 ? void 0 : content.theme, name = _content$theme.name, url = _content$theme.url;
              loadTheme(name, url);
              _context.next = 31;
              return put({
                type: 'style/saveCurrentTheme',
                payload: _objectSpread({}, content === null || content === void 0 ? void 0 : content.theme)
              });

            case 31:
            case "end":
              return _context.stop();
          }
        }
      }, setInitialPageJson);
    }),
    deleteElement: /*#__PURE__*/_regeneratorRuntime.mark(function deleteElement(_ref11, _ref12) {
      var payload, select, put, globalState, element, parent;
      return _regeneratorRuntime.wrap(function deleteElement$(_context2) {
        while (1) {
          switch (_context2.prev = _context2.next) {
            case 0:
              payload = _ref11.payload;
              select = _ref12.select, put = _ref12.put;
              _context2.next = 4;
              return select(function (state) {
                return state;
              });

            case 4:
              globalState = _context2.sent;
              element = payload.element;
              parent = deleteElementFromParent(globalState, element);
              _context2.next = 9;
              return put({
                type: 'updateAndFlattenElement',
                payload: {
                  element: parent
                }
              });

            case 9:
            case "end":
              return _context2.stop();
          }
        }
      }, deleteElement);
    }),
    // 保存表单
    saveForm: /*#__PURE__*/_regeneratorRuntime.mark(function saveForm(_ref13, _ref14) {
      var payload, select, put;
      return _regeneratorRuntime.wrap(function saveForm$(_context3) {
        while (1) {
          switch (_context3.prev = _context3.next) {
            case 0:
              payload = _ref13.payload;
              select = _ref14.select, put = _ref14.put;

            case 2:
            case "end":
              return _context3.stop();
          }
        }
      }, saveForm);
    })
  }
};
//# sourceMappingURL=appBuilder.js.map