import * as performancesService from '../../services/supplier/performances';
import * as bpmService from '../../services/common/bpm';
import { routerRedux } from 'dva/router';
import pathToRegexp from 'path-to-regexp';
import { dataUtils, enums } from '@utils';
import { Modal,message } from 'antd';

const { customMsg, viewMode, docStatus } = enums;

export default {

  namespace: 'performanceDetail',
  state: {
    scores: { scoreQuality: [], scoreDelivery: [], scoreService: [], scoreAddition: [] },
    grades: [90, 80, 70], // 绩效评分标准: >=90 A；>=80 B；>=70 C；<70 D;
    sgNames: ['A', 'B', 'C', 'D'],
    formData: { scoreTotal: '', sgName: '', opinion1: '' },
    mode: 'create',
    rectifyData: {},
    advice: '',
    attachment: [],
    remoteCfg: null,
    supplier: {},
    showSubmit: false,
  },

  subscriptions: {
    setup({ dispatch, history }) {
      history.listen((location) => {
        const match = pathToRegexp('/lifecycle/supp-performance/:id').exec(location.pathname);
        if (match) {
          dispatch({ type: 'clean' });
          dispatch({ type: 'updateState', payload: dataUtils.queryStringToJSON(location.search) || { from: '' } });
          dispatch({ type: 'querySingle', payload: { id: match[1] } });
        }
      });
    },
  },

  effects: {
    * querySingle({ payload }, { call, put, select }) {
      let { mode, showSubmit } = yield select(({ performanceDetail }) => performanceDetail);
      const { scores } = yield select(({ performanceDetail }) => performanceDetail);

      const perms = yield select(({ app }) => app.perms);
      const menuId = perms.map((i) => i.menuId).find((k) => k === '');
      if (menuId) {
        showSubmit = true;
      }

      // 拉去页面数据
      const data = yield call(performancesService.getSingle, payload.id);
      if (data.success) {
        if (data.data.prcId && mode !== viewMode.VIEW) {
          // 判断登录用户是否为当前处理人
          const status = yield call(bpmService.doCheckActived, data.data.prcId);
          if (!(status.success && status.data)) {
            Modal.error({
              title: customMsg.NOT_ACTIVE_HANDLER, // 您不是当前处理人
            });
            mode = viewMode.VIEW;
          }
        }

        // 导入的历史绩效 没有prcId
        if (!data.data.prcId && data.data.status !== docStatus.DOC_STATUS_WAITING) {
          mode = viewMode.VIEW;
        }

        if (mode === viewMode.CREATE) {
          const lastMonth = yield call(performancesService.lastMonth, data.data);
          if (lastMonth.success && lastMonth.data && (lastMonth.data.status !== docStatus.DOC_STATUS_FINISH)) {
            Modal.error({
              title: customMsg.PERFORMANCE_NOT_FINISHED, // 上月绩效评分未完成，不能进行当月评分
            });
            mode = viewMode.VIEW;
          }
        }

        // 初始配置文件参数
        const defId = data.data.defId ? data.data.defId : 'SuppliperPerformance:';
        const nodeId = mode === viewMode.VIEW ? mode : (data.data.prcId ? data.data.taskKey : 'initiator');
        const params = {
          defId,
          nodeId: nodeId ? nodeId : mode,
          mode: mode === viewMode.APPROVE ? viewMode.EDIT : mode,
        };
        // 拉去远程文件配置
        const cfgData = yield call(performancesService.remoteCfg, params);
        if (cfgData.success) {
          yield put({
            type: 'queryConfigSuccess',
            payload: {
              remoteCfg: cfgData.data,
            },
          });
        } else {
          throw cfgData;
        }

        // 计算总分
        const calc = (params) => {
          const total = params.map((record) => record.score).reduce((pre, next) => (pre + next), 0);
          params.total = total;
          return params;
        };
        const { perScores } = data.data;
        scores.scoreQuality = calc(perScores.splice(0, 3));
        scores.scoreDelivery = calc(perScores.splice(0, 3));
        scores.scoreService = calc(perScores.splice(0, 4));
        scores.scoreAddition = calc(perScores.splice(0, 5));

        yield put({
          type: 'updateState',
          payload: {
            formData: data.data,
            scores,
            mode,
            showSubmit,
          },
        });
      } else {
        throw data;
      }
    },

    * save({ payload }, { put, call, select }) {
      const { formData, scores, grades, advice } = yield select(({ performanceDetail }) => performanceDetail);
      const { scoreQuality, scoreDelivery, scoreService, scoreAddition } = scores;
      const { finalScore } = formData;
      const { submitted, type } = payload;

      const scoreMerge = [...scoreQuality, ...scoreDelivery, ...scoreService, ...scoreAddition]; // 4个数组合并
      let total = scoreMerge.map((record) => record.score).reduce((pre, next) => (pre + next), 0); // 然后计算总分

      formData.perScores = scoreMerge;
      formData.score = total;
      formData.submitted = submitted; // 是否提交到工作流

      if (submitted || finalScore) {
        // 评分对应的 评级规则（调整得分为主）
        total = finalScore ? finalScore : total;
        let scoreGrade = grades.length;
        for (const value of grades) {
          if (total >= value) {
            scoreGrade = grades.indexOf(value);
            break;
          }
        }
        formData.scoreGrade = scoreGrade + 1;

        // 采购员录入评分时，如果连续两个月为D，则整改信息为必填信息
        if (!formData.prcId && !formData.rectificationMemo &&
          formData.scoreGrade === (grades.length + 1) &&
          formData.pre1month === (grades.length + 1)) {
          Modal.error({
            title: customMsg.PERFORMANCE_LOW_QUALITY, // 连续两次评级为D 要求必填整改意见
          });
          return false;
        }
      }
      if(type && type !== viewMode.APPROVE && !advice.trim()){
        message.error('请填写审批意见');
        return;
      }
      const data = yield call(performancesService.update, formData);
      if (data.success) {
        if (type) {
          const bpmUri = type === viewMode.APPROVE ? bpmService.doApprove : bpmService.doReject;
          const result = yield call(bpmUri, { taskId: formData.taskId, advice });
          if (result.success) {
            yield put({ type: 'cancel' });
          } else {
            throw result;
          }
        } else {
          yield put({ type: 'cancel' });
        }
      } else {
        throw data;
      }
    },

    * cancel({ payload }, { put }) {
      yield put(routerRedux.goBack());
    },

    * clean({ payload }, { call, put }) {
      yield put({
        type: 'updateState',
        payload: {
          scores: { scoreQuality: [], scoreDelivery: [], scoreService: [], scoreAddition: [] },
          grades: [90, 80, 70],
          formData: { scoreTotal: '', sgName: '', opinion1: '' },
          mode: 'create',
          rectifyData: {},
          advice: '',
          attachment: [],
          remoteCfg: null,
          supplier: {},
          showSubmit: false,
        },
      });
    },
  },

  reducers: {

    queryConfigSuccess(state, action) {
      const { remoteCfg } = action.payload;
      return {
        ...state,
        remoteCfg,
      };
    },

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

    updateUploadState(state, { payload }) {
      const { scores } = state;
      const { part, index, file } = payload;
      scores[part][index].viewFiles = file;
      return {
        ...state,
        scores,
      };
    },

    updateCell(state, { payload }) {
      const { scores } = state;
      const { part, index, column, value } = payload;
      const newList = scores[part];
      newList[index][column] = value;
      if (column === 'score') {
        newList.total = newList.map((record) => record.score).reduce((pre, next) => (pre + next), 0);
      }
      return {
        ...state,
        scores,
      };
    },

    updateForm(state, { payload }) {
      const { key, value } = payload;
      const { formData, grades, sgNames } = state;
      const newFormData = Object.assign({}, formData);
      newFormData[key] = value;

      if (key === 'finalScore') {
        let scoreGrade = grades.length;
        for (const scoreVal of grades) {
          if (value >= scoreVal) {
            scoreGrade = grades.indexOf(scoreVal);
            break;
          }
        }
        newFormData['sgName'] = sgNames[scoreGrade];
        newFormData['showScore'] = value;
      }
      return {
        ...state,
        formData: newFormData,
      };
    },

    updateAdvice(state, { payload }) {
      const { value } = payload;
      let advice = state.advice;
      advice = value;
      return {
        ...state,
        advice,
      };
    },
  },

};
