import { randomCode } from "../../plugins/utils";

const state = {
  cardConfig: {},
  curElement: {},
  curDragElement: {},
  curCopyElement: {},
  curPage: {},
  curPageNo: 0,
  curColumnId: 0,
  pages: [],
  openElementEditDialog: false,
};

const mutations = {
  setCardConfig(state, cardConfig) {
    state.cardConfig = Object.assign({}, state.cardConfig, cardConfig);
  },
  setCurElement(state, curElement) {
    state.curElement = curElement;

    if (!curElement.id) return;
    const curColumn = state.curPage.columns.find(
      (column) => !!column.elements.find((elem) => elem.id === curElement.id)
    );
    state.curColumnId = curColumn.id;
  },
  setCurDragElement(state, curDragElement) {
    state.curDragElement = curDragElement;
  },
  setCurCopyElement(state, curCopyElement) {
    state.curCopyElement = curCopyElement;
  },
  setCurPageNo(state, curPageNo) {
    const pageNo = state.pages[curPageNo] ? curPageNo : 0;
    state.curPage = state.pages[pageNo];
    state.curPageNo = pageNo;
  },
  setCurPage(state, curPage) {
    state.curPage = curPage;
  },
  setCurColumnId(state, curColumnId) {
    state.curColumnId = curColumnId;
  },
  setPages(state, pages) {
    state.pages = pages;
  },
  setOpenElementEditDialog(state, openElementEditDialog) {
    state.openElementEditDialog = openElementEditDialog;
  },
  initState(state) {
    state.curElement = {};
    state.curDragElement = {};
    state.curCopyElement = {};
    state.curPage = {};
    state.curPageNo = 0;
    state.pages = [];
    state.cardConfig = {};
    state.openElementEditDialog = false;
  },
};

const findElementById = (id, curPage) => {
  let curElement = null;
  let columnIndex = 0;
  let elementIndex = 0;
  curPage.columns.forEach((column, cindex) => {
    column.elements.forEach((element, eindex) => {
      if (curElement) return;
      if (element.id === id) {
        curElement = element;
        columnIndex = cindex;
        elementIndex = eindex;
        return;
      }
    });
  });
  return { curElement, columnIndex, elementIndex };
};

const updateElementsZindex = (elements) => {
  const maxZindex = elements.length + 9 - 1;
  elements.forEach((element, index) => {
    element.zindex = maxZindex - index;
    element.key = randomCode();
  });
};

const actions = {
  addPage({ state }, page) {
    state.pages.push(page);
  },
  modifyPage({ state, commit }, page) {
    const pos = state.pages.findIndex((p) => p.id === page.id);
    state.pages.splice(pos, 1, page);
    commit("setCurPageNo", pos);
  },
  modifyAllPageShowForbidArea({ state, commit }, showForbidArea) {
    state.pages.forEach((page) => {
      page.showForbidArea = showForbidArea;
    });
    commit("setCurPageNo", state.curPageNo);
  },
  removePage({ state, commit }, page) {
    const pos = state.pages.findIndex((p) => p.id === page.id);
    state.pages.splice(pos, 1);
    if (pos === state.curPageNo) commit("setCurPageNo", state.curPageNo);
  },
  actElementById({ state, commit }, id) {
    const { curElement } = findElementById(id, state.curPage);
    if (!curElement) return;

    commit("setCurElement", curElement);
  },
  addElement({ state, commit }, { columnIndex, element }) {
    // 层级大的放最前面，层级自增，即后创建的元素放前面
    const elements = state.curPage.columns[columnIndex].elements;
    elements.unshift(element);
    updateElementsZindex(elements);
    commit(
      "setCurElement",
      elements.find((elem) => elem.id === element.id)
    );
  },
  modifyElement({ state, commit }, element) {
    const { columnIndex, elementIndex } = findElementById(
      element.id,
      state.curPage
    );
    const elements = state.curPage.columns[columnIndex].elements;
    elements.splice(elementIndex, 1, element);
    commit("setCurElement", element);
  },
  removeElement({ state }, element) {
    const { columnIndex, elementIndex } = findElementById(
      element.id,
      state.curPage
    );
    const elements = state.curPage.columns[columnIndex].elements;
    elements.splice(elementIndex, 1);
    updateElementsZindex(elements);
  },
  pasteElement({ state, dispatch }, { element, toColumnId }) {
    const columnIndex = state.curPage.columns.findIndex(
      (col) => col.id === toColumnId
    );
    dispatch("addElement", { columnIndex, element });
  },
  moveElementToElement(
    { state, commit },
    { curElement, toElementId, curColumnId, isDragDown }
  ) {
    const columnIndex = state.curPage.columns.findIndex(
      (col) => col.id === curColumnId
    );
    const elements = state.curPage.columns[columnIndex].elements;
    const curPos = elements.findIndex((elem) => elem.id === curElement.id);
    elements.splice(curPos, 1);

    const toPos = elements.findIndex((elem) => elem.id === toElementId);
    const offset = isDragDown ? 1 : 0;
    elements.splice(toPos + offset, 0, curElement);
    // console.log(toPos);

    updateElementsZindex(elements);
    commit(
      "setCurElement",
      elements.find((elem) => elem.id === curElement.id)
    );
  },
  moveElementZindex({ state, commit }, { curElement, pos }) {
    let curColumn = null,
      curElementPos = null;

    state.curPage.columns.forEach((column) =>
      column.elements.forEach((elem, eindex) => {
        if (elem.id === curElement.id) {
          curElementPos = eindex;
          curColumn = column;
        }
      })
    );

    const elements = curColumn.elements;

    if (
      (curElementPos === elements.length - 1 && pos > 0) ||
      (curElementPos === 0 && pos < 0)
    )
      return;

    const toPos = curElementPos + pos;
    elements.splice(curElementPos, 1);
    elements.splice(toPos, 0, curElement);

    updateElementsZindex(elements);
    commit(
      "setCurElement",
      elements.find((elem) => elem.id === curElement.id)
    );
  },
};

export default {
  namespaced: true,
  state,
  mutations,
  actions,
};
