import { message, Modal } from 'antd';
import { routerRedux } from 'dva/router';
import pathToRegexp from 'path-to-regexp';

import { dataUtils, enums, formUtils, mathUtils } from '@utils';
import * as bpmService from '../../../services/common/bpm';
import * as purchasingOrderService from '../../../services/cooperate/order/purchasingOrder';
import { numberUtils } from '@utils';

const { order, resultCode, viewMode, customMsg } = enums;

export default {

  namespace: 'purchasingOrderDetails',

  state: {
    formData: {},
    mode: 'view',
    from: '',
    list: [],
    total: 0,
    showTitle: false,
    advice: '',
    remoteCfg: null,
  },

  subscriptions: {
    setup({ dispatch, history }) {
      history.listen(() => {
        const match = pathToRegexp('/cooperate/order/po/:id').exec(location.pathname);
        if (match) {
          const mode = dataUtils.queryStringToJSON(location.search).mode;
          dispatch({ type: 'clean', payload: { mode } });
          dispatch({ type: 'query', payload: { poId: match[1], mode } });
        }
      });
    },
  },

  effects: {
    * query({ payload }, { call, put, select }) {

      const data = yield call(purchasingOrderService.getSingle, payload.poId);
      const details = yield call(purchasingOrderService.queryDtls, { poId: payload.poId });
      if (data.success) {

        const formData = data.data;

        let mode = payload.mode && viewMode[payload.mode.toUpperCase()]
          ? (payload.mode === 'approve' ? viewMode.VIEW : payload.mode)
          : viewMode.VIEW;
        // 判断登录用户是否为当前处理人
        if (formData.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;
          }
        } else if (!formData.prcId) {
          mode = viewMode.VIEW;
        }

        formData.demandDate = dataUtils.ymd(formData.demandDate);
        formData.docTime = dataUtils.ymd(formData.docTime);
        // formData.reqDate = dataUtils.ymd(formData.reqDate)
        formData.deliveryTimeFrom = formData.deliveryTimeFrom
          && formData.deliveryTimeFrom.slice(formData.deliveryTimeFrom.indexOf('T') + 1);
        formData.deliveryTimeTo = formData.deliveryTimeTo
          && formData.deliveryTimeTo.slice(formData.deliveryTimeTo.indexOf('T') + 1);
        formData.netAmt = numberUtils.round_half_up_format(formData.netAmt, 2);
        formData.amt = numberUtils.round_half_up_format(formData.amt, 2);
        formData.taxAmt = numberUtils.round_half_up_format(formData.taxAmt, 2);
        // 收货地址 = 仓库编码 + 仓库名称
        const whCode = formData.whCode || '';
        const whName = formData.whName || '';
        formData.acceptAddr = `${whCode} ${whName}`;

        details.data.length > 0 && details.data.map((d) => {
          d.diffQty = d.qty - d.promiseQty;
        });

        // 初始配置文件参数
        const defId = formData.defId || 'PurchasingOrder:';
        const nodeId = mode === viewMode.VIEW ? viewMode.VIEW : (formData.taskKey || 'initiator');
        const params = {
          defId,
          nodeId,
          mode,
        };
        // 拉去远程文件配置
        const cfgData = yield call(bpmService.getFormCfg, params);
        if (cfgData.success) {
          yield put({
            type: 'updateState',
            payload: {
              formData,
              list: details.data,
              remoteCfg: cfgData.data,
              mode,
            },
          });
        } else {
          throw cfgData;
        }
      } else {
        throw data;
      }
    },

    * save({ payload }, { select, call, put }) {
      const { formData, list } = yield select(({ purchasingOrderDetails }) => purchasingOrderDetails)

      const newPayload = [{
        ...formUtils.standardiseFormData(formData),
        ...formUtils.standardiseFormData(payload),
        details: list,
        submitted: true,
      }];

      // 按照后端的字段格式需求清洗数据
      const promiseDate = newPayload[0].promiseDate || newPayload[0].demandDate;
      if (newPayload[0].deliveryTimeFrom) {
        newPayload[0].deliveryTimeFrom = promiseDate + 'T' + newPayload[0].deliveryTimeFrom;
      }
      if (newPayload[0].deliveryTimeTo) {
        newPayload[0].deliveryTimeTo = promiseDate + 'T' + newPayload[0].deliveryTimeTo;
      }

      const data = yield call(purchasingOrderService.update, newPayload);
      if (data.success) {
        yield call(bpmService.doApprove, { taskId: formData.taskId, advice: '' });
        yield put({ type: 'clean' });
        message.success(resultCode.OK);
        yield put(routerRedux.goBack());
      } else {
        let errorMsg = data.message + " " + ( data.data && 'info' in data.data ? data.data.info : "");
        message.error(errorMsg);
      }
    },

    * approve({ payload }, { put, call, select }) {
      const { formData, advice } = yield select(({ purchasingOrderDetails }) => purchasingOrderDetails);
      // if(!advice.trim()){
      //   message.error('请填写审批意见');
      //   return;
      // }
      yield call(bpmService.doApprove, { taskId: formData.taskId, advice });
      yield put(routerRedux.goBack());
    },

    * reject({ payload }, { put, call, select }) {
      const { formData, advice } = yield select(({ purchasingOrderDetails }) => purchasingOrderDetails);
      if(!advice.trim()){
        message.error('请填写审批意见');
        return;
      }
      yield call(bpmService.doReject, { taskId: formData.taskId, advice });
      yield put(routerRedux.goBack());
    },

    * redirect({ payload }, { put }) {
      // yield put(routerRedux.push('/cooperate/order/po'))
      yield put(routerRedux.goBack());
    },

    * cancel({ payload }, { put }) {
      yield put(routerRedux.goBack());
      // yield put({ type: 'redirect' })
    },

    * clean({ payload }, { put, select }) {
      const newPayload = {
        formData: {},
        mode: (payload && payload.mode) || 'view',
        from: '',
        list: [],
        total: 0,
        advice: '',
        remoteCfg: null,
      };
      yield put({
        type: 'updateState',
        payload: newPayload,
      });
    },

    * checkValid({ payload }, { put, select }) {
      const { list, formData } = yield select(({ purchasingOrderDetails }) => purchasingOrderDetails);
      const { key, index, maxVal } = payload;
      let { value } = payload;

      // const reg= /^(-?\d+)(\.\d{1,2})?$/ // 校验小数点后两位+负数
      const reg = /^\d+(\.\d{1,4})?$/; // 校验小数点后两位
      const regNum = /^\d+(\.\d+)?$/; // 校验是非负浮点数

      if (typeof value === 'string' && !value.split('.')[1]) {
        // 校验
        if (value.split('.').length > 2) {
          value = list[index][key];
          message.warning(order.EDIT_NUM_FAIL); // 修改数量失败
        } else {
          list[index][key] = value;
        }
      } else {
        if (value && !regNum.test(value)) {
          message.warning(order.NUM_ALLOW); // 请填写非负数
        } else if (value && !reg.test(value)) {
          message.warning(order.FOUR_BITS_AFTER_POINT); // 仅支持小数点后四位
        } else if (value && value.length > 8) {
          message.warning(order.MAX_LENGTH); // 最长仅支持8位数字
        } else if (value > maxVal) {
          message.warning(order.OVER_LIMIT); // 数量超限
        } else if (value > list[index].qty) {
          message.warn(order.PRO_QTY_ERR); // 承诺数量不可大于采购数量
        } else if (!value && value != 0) {
          list[index][key] = null;
        } else {
          list[index][key] = value;
          // 实时更新差异数量
          if (key === 'promiseQty') {
            list[index].diffQty = mathUtils.sub(list[index].qty, value);
            list[index].netAmt = mathUtils.mul(value, list[index].netPrice)  // 修改未税总金额
            list[index].amt = mathUtils.mul(value, list[index].price)// 修改含税总金额
            list[index].taxAmt = mathUtils.sub(list[index].amt, list[index].netAmt) // 修改税额

            let totalNetAmt = 0;
            let totalAmt = 0;
            let totalDiffQty = 0;
            list.map(d => {
              totalDiffQty = mathUtils.add(totalDiffQty, d.diffQty);
              totalAmt = mathUtils.add(totalAmt, d.amt);
              totalNetAmt = mathUtils.add(totalNetAmt, d.netAmt);
            })
            formData.totalNetAmt = totalNetAmt;
            formData.totalAmt = totalAmt;
            formData.totalTaxAmt = mathUtils.sub(totalAmt, totalNetAmt);

            formData.netAmt = numberUtils.round_half_up_format(totalNetAmt, 2);
            formData.amt = numberUtils.round_half_up_format(totalAmt, 2);
            formData.taxAmt = numberUtils.round_half_up_format(formData.totalTaxAmt, 2);
          }
        }
      }

      // 当输入为promiseQty并且值为0/null时
      if (key === 'promiseQty' && !value) {
        list[index].diffQty = list[index].qty;
      }

      yield put({
        type: 'updateState',
        payload: { list, formData },
      });
    },

    * updatePromisePeriod({ payload }, { put, select }) {
      const { formData } = yield select(({ purchasingOrderDetails }) => purchasingOrderDetails);
      const { key, value } = payload;

      if (key === 'deliveryTimeTo' && formData.deliveryTimeFrom > value) {
        message.warning(order.TO_TIME_ERR); // 送货TO不可小于送货FROM
        return;
      } else if (key === 'deliveryTimeFrom' && value > formData.deliveryTimeTo) {
        message.warning(order.FROM_TIME_ERR); // 送货FROM不可大于送货TO
        return;
      } else {
        formData[key] = value || null;
      }
      yield put({
        type: 'updateState',
        payload: {
          formData
        }
      });
    },
  },

  reducers: {

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

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

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

    showModal(state, action) {
      return { ...state, ...action.payload, modalVisible: true };
    },

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