import * as definitionService from '../../services/sys/definitions';
import * as bpmService from '../../services/common/bpm';
import { message } from 'antd';
import { enums } from '../../utils';

export default {
  namespace: 'definitions',
  state: {
    list: [],
    total: 0,
    latestList: [],
    latestTotal: 0,
    currentItem: {},
    deployModalVisible: false,
    roleModalVisible: false,
    notifyModalVisible: false,
    mode: 'create',
    taskRoles: [],
    taskNotifies: [],
  },

  subscriptions: {
    setup({ dispatch, history }) {
      history.listen(location => {
        if (location.pathname === '/sys/definitions') {
          dispatch({ type: 'query' });
        }
      });
    },
  },

  effects: {
    * query({ payload }, { call, put }) {
      yield put({ type: 'queryLatest', payload });
      yield put({ type: 'queryHistoric', payload });
    },

    * queryLatest({ payload }, { call, put }) {
      const data = yield call(definitionService.queryLatest, payload);
      if (data.success) {
        yield put({
          type: 'updateState',
          payload: {
            latestList: data.data.rows,
            latestTotal: data.data.total,
          },
        });
      } else {
        throw data;
      }
    },

    * queryHistoric({ payload }, { call, put }) {
      const data = yield call(definitionService.queryHistoric, payload);
      if (data.success) {
        yield put({
          type: 'updateState',
          payload: {
            list: data.data.rows,
            total: data.data.total,
          },
        });
      } else {
        throw data;
      }
    },

    * loadExtraInfo({ payload }, { call, put }) {
      const data = yield call(bpmService.getBpmInfo, payload.defId);
      if (data.success) {
        yield put({
          type: 'attachExtraInfo',
          payload: {
            defId: payload.defId,
            isLatest: payload.isLatest,
            extraInfo: data.data,
          },
        });
      } else {
        throw data;
      }
    },

    * showDeployModal({ payload }, { put }) {
      yield put({
        type: 'updateState',
        payload: {
          deployModalVisible: true
        },
      });
    },

    * showRoleModal({ payload }, { put }) {
      yield put({
        type: 'updateState',
        payload: {
          roleModalVisible: true
        },
      });
    },

    * showNotifyModal({ payload }, { put }) {
      yield put({
        type: 'updateState',
        payload: {
          notifyModalVisible: true
        },
      });
    },

    * hideAndRefresh({ payload }, { put }) {
      yield put({ type: 'hideModal' });
      yield put({ type: 'query' });
    },

    * view({ payload }, { put }) {
      yield put({ type: 'hideModal' });
    },

    * hideModal({ payload }, { put }) {
      yield put({
        type: 'updateState',
        payload: {
          deployModalVisible: false,
          roleModalVisible: false,
          notifyModalVisible: false,
          currentItem: {},
          taskRoles: [],
          taskNotifies: [],
        },
      });
    },

    * commitModel({ payload }, { put, call }) {
      const data = yield call(definitionService.commitModel, payload);
      if (data.success) {
        message.success(enums.bpmOpResult.BPM_COMMIT_SUCCESS);
      } else {
        message.error(enums.resultCode.NG_NO_MODEL_IN_EDITING);
      }
    },

    * queryTaskRoles({ payload }, { put, call }) {
      const data = yield call(definitionService.taskRolesOf, { defId: payload.selectedRow.defId });
      if (data.success) {
        yield put({
          type: 'updateState',
          payload: {
            taskRoles: data.data,
            currentItem: payload.selectedRow,
          },
        });
        yield put({ type: 'showRoleModal' });
      } else {
        throw data;
      }
    },

    * updateTaskRoles({ payload }, { select, put, call }) {
      const taskRoles = yield select(({ definitions }) => definitions.taskRoles);
      const newTaskRoles = taskRoles.slice();
      newTaskRoles.splice(taskRoles.indexOf(payload.srcRow), 1, payload.distRow);

      yield put({
        type: 'updateState',
        payload: {
          taskRoles: newTaskRoles
        },
      });
    },

    * saveTaskRoles({ payload }, { select, put, call }) {
      const taskRoles = yield select(({ definitions }) => definitions.taskRoles);
      taskRoles.map(task => {
        if (task.settled === 'Y') {
          if (task.bpmRoles.length === 0) {
            throw { message: `${task.name} 节点流程角色必填` };
          }
        }
      });
      const data = yield call(definitionService.saveTaskRoles, { taskRoles });
      if (data.success) {
        yield put({ type: 'hideAndRefresh' });
        message.success(enums.bpmOpResult.BPM_SAVE_SUCCESS);
      } else {
        throw data;
      }
    },

    * queryTaskNotifies({ payload }, { put, call }) {
      const data = yield call(definitionService.taskNotifiesOf, { defId: payload.selectedRow.defId });
      if (data.success) {
        yield put({
          type: 'updateState',
          payload: {
            taskNotifies: data.data,
            currentItem: payload.selectedRow,
          },
        });
        yield put({ type: 'showNotifyModal' });
      } else {
        throw data;
      }
    },

    * updateTaskNotifies({ payload }, { select, put, call }) {
      const taskNotifies = yield select(({ definitions }) => definitions.taskNotifies);
      const newTaskNotifies = taskNotifies.slice();
      newTaskNotifies.splice(taskNotifies.indexOf(payload.srcRow), 1, payload.distRow);

      yield put({
        type: 'updateState',
        payload: {
          taskNotifies: newTaskNotifies
        },
      });
    },

    * saveTaskNotifies({ payload }, { select, put, call }) {
      const taskNotifies = yield select(({ definitions }) => definitions.taskNotifies);
      const data = yield call(definitionService.saveTaskNotifies, { taskNotifies, procDefId: payload.defId });
      if (data.success) {
        message.success(enums.bpmOpResult.BPM_SAVE_SUCCESS);
      } else {
        throw data;
      }
    },

  },

  reducers: {

    querySuccess(state, action) {
      const { list, total } = action.payload;
      return {
        ...state,
        list,
        total,
      };
    },

    updateState(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },

    attachExtraInfo(state, { payload }) {
      const { defId, extraInfo, isLatest } = payload;

      const newList = (list) => list.map(l => {
        if (l => l.defId === defId) {
          return { ...l, ...extraInfo };
        } else {
          return l;
        }
      });

      return isLatest ? { ...state, latestList: newList(state.latestList) } : { ...state, list: newList(state.list) };
    },

  },
};
