import { ReduxAction, ReduxSagaEffects } from '@interfaces';
import { message, Modal } from 'antd';
import { routerRedux } from 'dva/router';
import pathToRegexp from 'path-to-regexp';
import * as compareService from '../../../services/source/compare';
import { dataUtils, formUtils, enums } from '../../../utils';
import * as bpmService from '../../../services/common/bpm';
import { numberUtils } from '@utils';

const { customMsg, viewMode } = enums;

export default {

  namespace: 'compareDetail',

  state: {
    filterParams: {},
    formData: {},
    list: [],
    substituteList: [],
    total: 0,
    currentItem: {},
    docId: null,
    suppCenterId: null,
    confirmBtnFlag: false,
    remoteCfg: null,
    advice: '',
    mode: 'create',
    collectData: [],
  },

  subscriptions: {
    setup({ dispatch, history }: object) {
      history.listen((location) => {
        const match = pathToRegexp('/source-mgmt/qo/compare/detail').exec(location.pathname);
        if (match) {
          window.onbeforeunload = function(e) {
            return '确定离开此页吗？';
          };
          const queryparam = dataUtils.queryStringToJSON(location.search);
          dispatch({
            type: 'queryDetails',
            payload: {
              mode: queryparam.mode,
              docId: queryparam.docId
            }
          });
        }
      });
    },
  },

  effects: {

    // 做前端分页，防止DataTable组件自动调用query，改名为queryDetails
    * queryDetails({ payload }: ReduxAction, { call, put, select }: ReduxSagaEffects) {
      yield put({
        type: 'updateState',
        payload: {
          docId: payload.docId,
          filterParams: payload,
        },
      });
      let mode = payload.mode;
      let formData;
      if (mode === viewMode.CREATE) {
        formData = yield call(compareService.getCreateDetial, payload);
      } else {
        formData = yield call(compareService.getAuditDetial, payload);
      }
      if (formData.success) {

        const initializePercent  = mode === viewMode.CREATE && payload.docId.split(",").length === 1;

        formData.data.priceInterval = formData.data.priceEffectDate + "--" + formData.data.priceExpireDate;

        // 初始化 数据
        if (formData.data.srmCompItemsInfoList) {

          let itemMap = new Map();

          formData.data.srmCompItemsInfoList.map((i) => {

            // 如果只有一个询价单进行询价，初始化 分配比例 为100
            if (initializePercent) {
              i.percent = 100;
              const number = i.estimatedNum;
              i.allottedQuantity = parseFloat(number).toFixed(2);
              i.allottedAmt = parseFloat(number *i.bargainWithTax).toFixed(2);
            }

            // 初始化 未税降本差异金额 由前端计算 未税降本差异金额 = (未税单价 - 未税基准价) * 数量(有分配比例按分配比例算，没有按1算即不进入计算)
            if (i.guidePrice != null && i.netPrice != null) {
              const num = (i.estimatedNum ? i.estimatedNum : 0) * (i.percent == null ? 1 : i.percent/100);
              i.gapAmt = ((i.netPrice - i.guidePrice) * num).toFixed(2);
            }

            // 初始化 议报价差异 由前端计算 议报价差异 = 含税议价 - 含税报价
            if (i.bargainWithTax != null && i.quoteWithTax != null) {
              i.gapPrice = (i.bargainWithTax - i.quoteWithTax).toFixed(4);
            }

            // 记录百分比总和
            if (itemMap.has(i.itemId)) {
              let { percent } = itemMap.get(i.itemId);
              itemMap.set(i.itemId, { name: i.itemName, percent: percent + i.percent ? i.percent : 0 });
            } else {
              itemMap.set(i.itemId, { name: i.itemName, percent: i.percent ? i.percent : 0 });
            }

          });

          // 将所有百分比总和不为100的设置CSS样式为红框
          let keys = Array.from(itemMap.keys());
          for (let key of keys) {
            if (itemMap.get(key).percent !== 100) {
              formData.data.srmCompItemsInfoList.map(i => {
                if (i.itemId === key) {
                  i.invalidate = true;
                }
              })
            }
          }
        }

        //判断登录用户是否为当前处理人，如果不是当前处理人则直接转为查看页面
        if (mode !== viewMode.VIEW && mode !== viewMode.CREATE && mode !== viewMode.EDIT) {
          const status = yield call(bpmService.doCheckActived, formData.data.prcId);
          if (!(status.success && status.data)) {
            Modal.error({
              title: customMsg.NOT_ACTIVE_HANDLER,//您不是当前处理人
            });
            mode = viewMode.VIEW;
          }

          //初始配置文件参数，后端根据文件参数寻找文件路径，根据后端逻辑，nodeId这里需要设置为mode才可以找到
          //文件拼接大概逻辑 : defId-nodeId-mode.json || defId-nodeId.json || defId.json
          let taskKey = '';
          if (formData.data.taskKey) {
            taskKey = formData.data.taskKey;
            switch (taskKey) {
              case 'initiator':
                mode = viewMode.EDIT;
                break;
              case 'purchasingManager':
              case 'purchasingDirector':
                mode = viewMode.APPROVAL;
                break;
              default:
                mode = viewMode.VIEW;
            }
          }
        }

        //更新mode到state，用于审批意见判断
        yield put({
          type: 'updateState',
          payload: {
            mode: mode
          },
        });

        //初始配置文件参数
        const params = {
          defId: 'PriceCompare:1',
          nodeId: 'initiator',
          mode: mode,
        };
        //拉去远程文件配置
        const cfgData = yield call(compareService.remoteCfg, params);
        if (cfgData.success) {
          yield put({
            type: 'queryConfigSuccess',
            payload: {
              remoteCfg: cfgData.data,
            },
          });
        } else {
          throw cfgData;
        }

        // 汇总列表统计
        const { srmCompItemsInfoList } = formData.data;
        const groups = {};
        srmCompItemsInfoList.forEach(i => {
          const dataKey = i.suppName;
          groups[dataKey] = groups[dataKey] || [];
          groups[dataKey].push(i);
        });
        const collectData = Object.keys(groups).map(key =>{
          const compareData = groups[key];
          const itemNumber = compareData.map(m => m.estimatedNum).reduce((prev, next) => (prev + next), 0);
          const itemAmt = compareData.map(m => m.amt).reduce((prev, next) => (prev + next), 0);
          return {
            suppName: key,
            itemCount: compareData.length,
            itemNumber: numberUtils.round_half_up_format(itemNumber, 2),
            itemAmt: numberUtils.round_half_up_format(itemAmt, 2),
          };
        });

        yield put({
          type: 'updateState',
          payload: {
            formData: formData.data,
            list: formData.data.srmCompItemsInfoList ? formData.data.srmCompItemsInfoList : [],
            substituteList: formData.data.substituteList ? formData.data.substituteList : [],
            collectData,
          },
        });
      } else {
        throw formData;
      }
    },

    //更新
    * update({ payload }: ReduxAction, { select, call, put }: ReduxSagaEffects) {
      let newDetailView = Object.assign({}, yield select(({ compareDetail }) => compareDetail.formData));
      newDetailView.isSubmit = payload.isSubmit;
      const data = yield call(compareService.submit, newDetailView);
      if (data.success) {
        if (payload.isSubmit) {
          message.success('提交成功');
          yield put({ type: 'cancel' });
        } else {
          message.success('保存成功');
          // 如果是新建比价单，在第一次进行了保存操作后，必须跳转到修改页面
          // 如果是修改或在第一个节点进行审批操作(也为修改)，则保持原来的状态重新刷新一遍表单数据就行
          const filterParams = yield select(({ compareDetail }) => compareDetail.filterParams);
          if (filterParams.mode === viewMode.CREATE) {
            yield put(routerRedux.replace({
              pathname: '/source-mgmt/qo/compare/detail',
              search: `?mode=edit&docId=${data.data}`,
            }));
          } else {
            yield put({
              type: 'queryDetails',
              payload: filterParams
            });
          }
        }
      } else {
        throw data;
      }
    },

    //获取替代料列表
    * substitutes({ payload }: ReduxAction, { select, call, put }: ReduxSagaEffects) {
      const result = yield call(compareService.substitutes, payload);
      if (result.success) {
        result.data.priceInterval = result.data.fromDate + "--" + result.data.toDate;
        yield put({
          type: 'updateState',
          payload: {
            substituteList: result.data ? result.data : []
          },
        });
      } else {
        throw result;
      }
    },

    * redirect({ payload }: ReduxAction, { put }: ReduxSagaEffects) {
      yield put(routerRedux.push(`/source-mgmt/qo/qo`));
    },
    * cancel({ payload }: ReduxAction, { put }: ReduxSagaEffects) {
      yield put({ type: 'clean' });
      yield put(routerRedux.goBack());
    },
    * clean({ payload }: ReduxAction, { call, put }: ReduxSagaEffects) {
      yield put({
        type: 'updateState',
        payload: {
          formData: {},
          list: [],
          substituteList: [],
          total: 0,
          currentItem: {},
          mode: 'update',
          itemId: null,
          suppCenterId: null,
          collectData: [],
        },
      });
    },
    * approve({ payload }, { put, call, select }) {
      const formData = yield select(({ compareDetail }) => compareDetail.formData);
      const advice = yield select(({ compareDetail }) => compareDetail.advice);
      // if (!advice.trim()) {
      //   message.error('请填写审批意见');
      //   return;
      // }
      const data = yield call(bpmService.doApprove, { taskId: formData.taskId, advice: advice });
      if (data.success) {
        message.success('操作成功');
        yield put({ type: 'cancel' });
      } else {
        throw data;
      }
    },
    * reject({ payload }, { put, call, select }) {
      const formData = yield select(({ compareDetail }) => compareDetail.formData);
      const advice = yield select(({ compareDetail }) => compareDetail.advice);
      if (!advice.trim()) {
        message.error('请填写审批意见');
        return;
      }
      const data = yield call(bpmService.doReject, { taskId: formData.taskId, advice: advice });
      if (data.success) {
        message.success('操作成功');
        yield put({ type: 'cancel' });
      } else {
        throw data;
      }
    },
  },

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

    updateCell(state: object, { payload }: ReduxAction) {
      console.log("updateCell-payload==>", payload);
      console.log("updateCell-state==>", state);
      const { list } = state;
      const newList = list.slice();
      const { rowKey, key, value } = payload;

      // 由于使用了组件自带的前端分页，因为组件传过来的index是每页的index，而不是list中的index
      // 所以这里不使用组件的index，而是自己通过pqdDocId来获取真实的index，然后进行更新操作
      const index = newList.findIndex(item => {
        return item.pqdDocId === rowKey;
      });
      newList[index][key] = value;

      // 更新百分比做如下操作
      // 1. 更新分配数量和分配金额
      // 2. 根据数量计算差异金额
      // 3. 计算分配比例之和，不符合要求的修改页面显示红框
      if (key === 'percent') {
        // 1. 更新分配数量和分配金额
        // 2. 根据数量计算差异金额
        if (value === 0 || value) {
          const number = newList[index]['estimatedNum'] * (value / 100);
          const netPrice = newList[index]['netPrice'];
          const guidePrice = newList[index]['guidePrice'];
          newList[index]['allottedQuantity'] = parseFloat(number).toFixed(2);
          newList[index]['allottedAmt'] = parseFloat(number * newList[index]['bargainWithTax']).toFixed(2);
          if (guidePrice != null && netPrice != null) {
            newList[index]['gapAmt'] = parseFloat((netPrice - guidePrice) * number).toFixed(2);
          }
        } else {
          newList[index]['allottedQuantity'] = null;
          newList[index]['allottedAmt'] = null;
          const number = newList[index]['estimatedNum'];
          const netPrice = newList[index]['netPrice'];
          const guidePrice = newList[index]['guidePrice'];
          if (guidePrice != null && netPrice != null) {
            newList[index]['gapAmt'] = parseFloat((netPrice - guidePrice) * number).toFixed(2);
          }
        }

        // 3. 计算分配比例之和，不符合要求的修改页面显示红框
        // 如果相同物料分配比例只和 != 100 则改变css样式，输入框变红
        const itemId = newList[index]['itemId'];
        let percentSum = 0;
        newList.map(item => {
          if (item.itemId === itemId) {
            percentSum = percentSum + (item.percent ? item.percent : 0);
          }
        });
        if (percentSum === 100) {
          newList.map(item => {
            if (item.itemId === itemId) {
              item.invalidate = false;
            }
          });
        } else {
          newList.map(item => {
            if (item.itemId === itemId) {
              item.invalidate = true;
            }
          });
        }
      }
      return {
        ...state,
        list: newList,
      };
    },

    updateState(state: object, { payload }: ReduxAction) {
      return { ...state, ...payload };
    },
  },
};
