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

import * as bpmService from '../../../services/common/bpm';
import * as formaInvoiceService from '../../../services/cooperate/finance/formaInvoice';
import * as taxService from '../../../services/mdata/tax';
import item from '../../../routes/common/register/item';
import { numberUtils } from '@utils';

export default {
  namespace: 'formaInvoice',

  state: {
    filterParams: {},
    formData: null, // 发票详情(供应商的税率等)
    mode: 'view',
    list: [],  // 拆分后的发票列表
    advice: '',
    quotaList: [],
    accountCheckList: [], // 对账明细
    itemVisible: false,
    itemList: [],
    total: 0,
    itemCode: '',
    taxRate: 0,
    accountId: 0,
    handleBtn:true,
  },

  subscriptions: {
    setup({ dispatch, history }) {
      history.listen(() => {
        const match = pathToRegexp('/cooperate/finance/s-invoice/:id').exec(location.pathname);
        if (match) {
          if (match[1] === 'create') {
            dispatch({ type: 'updateState', payload: { mode: 'create' } });
            const checkId = stringUtils.queryURL('checkId');
            checkId && dispatch({ type: 'queryCreate', payload: { checkId: parseFloat(checkId) } });
          } else {
            dispatch({
              type: 'updateState',
              payload: {
                mode: stringUtils.queryURL('mode'),
                advice:'',
                filterParams: {
                  id: parseFloat(match[1])
                },
              }
            });
            dispatch({ type: 'queryView', payload: { id: parseFloat(match[1]) } });
          }
        }
      });
    },
  },

  effects: {
    // 编辑/查看等查询
    * queryView({ payload }, { call, put, select }) {
      const quotaList = yield call(formaInvoiceService.queryQuota);
      const result = yield call(formaInvoiceService.getSingle, payload.id);
      let { mode } = yield select(({ formaInvoice }) => formaInvoice);
      let { handleBtn } = yield select(({ formaInvoice }) => formaInvoice);
      const perms = yield select(({app}) => app.perms);
      if (perms) {
        for (const p of perms) {
          if (p.menuId === 'cp_fn_si_handle') {
            handleBtn = false;
          }
        }
      }
      if (result.success) {
        if (mode === 'approval') {
          const status = yield call(bpmService.doCheckActived, result.data.prcId);
          if (status.success) {
            if (!status.data) {
              Modal.error({
                title: '您不是当前处理人',
                okText: '确认'
              });
              mode = 'view';
            }
          }
        }
        // 根据发票ID查询 正式发票表
        result.data.invAmt = parseFloat(result.data.invAmt).toFixed(2);
        result.data.invAmtStr = numberUtils.round_half_up_format(result.data.invAmt, 2);
        result.data.taxAmt = parseFloat(result.data.taxAmt).toFixed(2);
        result.data.taxAmtStr = numberUtils.round_half_up_format(result.data.taxAmt, 2);
        result.data.netAmt = parseFloat(result.data.netAmt).toFixed(2);
        result.data.netAmtStr = numberUtils.round_half_up_format(result.data.netAmt, 2);
        result.data.actTaxAmt = parseFloat(result.data.actTaxAmt).toFixed(2);
        result.data.actTaxAmtStr = numberUtils.round_half_up_format(result.data.actTaxAmt, 2);
        result.data.actNetAmt = parseFloat(result.data.actNetAmt).toFixed(2);
        result.data.actNetAmtStr = numberUtils.round_half_up_format(result.data.actNetAmt, 2);
        result.data.actInvAmt = parseFloat(result.data.actInvAmt).toFixed(2);
        result.data.actInvAmtStr = numberUtils.round_half_up_format(result.data.actInvAmt, 2);
        const quota = +result.data.quota;
        // 发票明细
        const list = result.data.invItemList;

        if (list && list.length > 0) {
          list.map((i) => {
            i.invAmt = parseFloat(i.invAmt).toFixed(2);
            i.taxAmt = parseFloat(i.taxAmt).toFixed(2);
            i.netAmt = parseFloat(i.netAmt).toFixed(2);
            // i.taxRate = (i.taxRate === null || i.taxRate === '') ? [] : i.taxRate.split(',');
          });
          for (let inv of list) {
            if (inv.taxRate) {
              const tax = yield call(taxService.getSingle, inv.taxRate);
              if (tax.success && tax.data) {
                inv.taxVal = tax.data.taxRate;
              } else {
                throw result.message;
              }
            }
          }
        }

        // 计算差异金额
        const formData = formaInvoiceService.countFormGapAmt(result.data);

        yield put({
          type: 'updateState',
          payload: {
            formData: {
              ...formData,
              invNum: list ? list.length : 0,
              quota: quota,
            }, // 发票详情
            list,  // 拆分后的发票列表
            quotaList: quotaList.data, // 定额api
            mode: mode,
            handleBtn,
          },
        });
      } else {
        throw result.message;
      }
    },

    // 新建(未生成汇总发票时)的查询
    * queryCreate({ payload }, { call, put }) {
      const quotaList = yield call(formaInvoiceService.queryQuota);
      const result = yield call(formaInvoiceService.getSingleFromAcc, payload.checkId);
      if (result.success) {
        result.data.invAmt = parseFloat(result.data.invAmt).toFixed(2); // 金额转为保留到小数点后两位
        result.data.invAmtStr = numberUtils.round_half_up_format(result.data.invAmt, 2);
        result.data.taxAmt = parseFloat(result.data.taxAmt).toFixed(2);
        result.data.taxAmtStr = numberUtils.round_half_up_format(result.data.taxAmt, 2);
        result.data.netAmt = parseFloat(result.data.netAmt).toFixed(2);
        result.data.netAmtStr = numberUtils.round_half_up_format(result.data.netAmt, 2);
        result.data.actTaxAmt = parseFloat(result.data.actTaxAmt).toFixed(2);
        result.data.actTaxAmtStr = numberUtils.round_half_up_format(result.data.actTaxAmt, 2);
        result.data.actNetAmt = parseFloat(result.data.actNetAmt).toFixed(2);
        result.data.actNetAmtStr = numberUtils.round_half_up_format(result.data.actNetAmt, 2);
        result.data.actInvAmt = parseFloat(result.data.actInvAmt).toFixed(2);
        result.data.actInvAmtStr = numberUtils.round_half_up_format(result.data.actInvAmt, 2);
        const amt = +result.data.invAmt;
        // 对账单list
        yield put({
          type: 'updateState',
          payload: {
            formData: { ...result.data, invForm: '2', invNum: 0, quota: 10000000, quotaCode: '05' }, // 发票详情  发票类型默认为预制发票
            quotaList: quotaList.data, // 定额api
          },
        });

        amt > 0 ? yield put({ type: 'split', }) : null; // 金额大于0则自动拆分发票
      } else {
        throw result.message;
      }
    },

    // 拆分发票按钮
    * split({ payload }, { select, put }) {
      const { formData } = yield select(({ formaInvoice }) => formaInvoice);
      const quota = +formData.quota; // 定额
      const invAmt = +formData.invAmt; // 开票总金额
      let netAmt = +formData.netAmt; // 开票未税金额

      // 判断是否填写定额
      if (invAmt <= 0) {
        message.warn('开票金额异常无法拆分');
        return false;
      }
      if (quota <= 0 || quota === null) {
        message.warn('定额是必填项');
        return false;
      }
      if (quota !== 0 && invAmt / quota > 100) {
        message.warn('最多支持拆分一百张发票,请您重新调整定额');
        return false;
      }
      // list 列的值
      const taxVal = 0; //税率，由于之后的计算有问题，这里放弃使用原值进行计算，直接默认税率为0，进行计算则不会出问题
      // const taxVal = +formData.taxVal; //税率
      // const taxRate = formData.taxRate; //税率id
      // const taxDesc = formData.taxDesc; //税率描述
      // const taxCode = formData.taxCode; // 税率编码
      const invType = formData.invForm; // 发票形式
      const invClass = formData.invType; // 发票种类
      const invDate = moment().format('YYYY-MM-DD');
      let newList = [];
      const sumTaxAmt = +formData.taxAmt; // 税额
      let amtObject = formaInvoiceService.countAmt(quota, taxVal, sumTaxAmt); // 按税率计算税额, 未税金额
      const row = {
        id: 0,
        invNo: '',
        invSymbol: '',
        invType,
        invStatusName: '待验证',
        invAmt: amtObject.invAmt,
        taxAmt: amtObject.taxAmt,
        netAmt: amtObject.netAmt,
        invClass,
        // taxCode,
        // taxRate,
        // taxDesc,
        // taxVal,
        invDate,
      };
      if (quota > 0 && invAmt > 0) {
        const num = parseInt(invAmt / quota); // 向上取整
        const remainder = invAmt % quota; // 求模取余
        if (invAmt >= quota) {
          for (let i = 0; i < num; i++) {
            if (i !== 0) { // 第一次已经计算过netAmt 和 taxAmt 了
              amtObject = formaInvoiceService.countAmt(quota, taxVal, amtObject.sumTaxAmt);
            }
            const newRow = { ...row, id: i, taxAmt: amtObject.taxAmt, netAmt: amtObject.netAmt, };
            newList.push(newRow);
            netAmt -= amtObject.netAmt;
          }
        }
        if (remainder) {
          amtObject = formaInvoiceService.countAmt(remainder, taxVal, amtObject.sumTaxAmt);
          const lastRow = {
            ...row,
            id: newList.length,
            invAmt: amtObject.invAmt,
            netAmt: amtObject.invAmt, // 计算方法有问题，暂时先不做处理，默认未税含税相等
            taxAmt: 0,
          };
          newList.push(lastRow);
        } else { // 如果总额大于定额, 不存在余额
          let last = newList[newList.length - 1][0];
          last = {
            ...last,
            id: newList.length,
            // invAmt: amtObject.invAmt,
            taxAmt: last.invAmt - (netAmt + amtObject.netAmt),
            netAmt: netAmt + amtObject.netAmt,
          };

          newList[newList.length - 1][0] = last;
        }

        // 拆分发票后，重新计算发票总金额
        const newFormData = formaInvoiceService.countFormActAmt(formData, newList);

        yield put({ type: 'updateState', payload: { list: newList, formData: { ...newFormData, invNum: newList.length } } });
      }
    },

    // 发票保存
    * save({ payload }, { select, call, put }) {
      const { formData, list } = yield select(({ formaInvoice }) => formaInvoice);
      const newList = list.map(item => {
        return {
          ...item,
          invDate: moment(item.invDate).format('YYYY-MM-DD'),
          // taxRate: item.taxRate.join(',')
        };
      });
      const result = yield call(formaInvoiceService.save, { ...formData, invForm: '2', invItemList: newList }); // 发票类型默认为预制发票
      if (result.success) {
        yield put(routerRedux.replace(`/cooperate/finance/s-invoice/${result.data.id}?mode=update`));
      } else {
        throw result.message;
      }
    },

    // 发票提交
    * submit({ payload }, { select, call, put }) {
      const { formData, list } = yield select(({ formaInvoice }) => formaInvoice);
      const newList = list.map(item => {
        return {
          ...item,
          invDate: moment(item.invDate).format('YYYY-MM-DD'),
          // taxRate: item.taxRate.join(',')
        };
      });
      const result = yield call(formaInvoiceService.approval, { ...formData, invForm: '2', submitted: true, invItemList: newList }); // 发票类型默认为预制发票
      if (result.success) {
        yield put(routerRedux.goBack());
      } else {
        throw result.message;
      }

    },

    // 发票list里的字段编辑
    * updateListProp({ payload }, { select, put, call }) {
      const { value, key, index } = payload;
      const { formData, list } = yield select(({ formaInvoice }) => formaInvoice);
      let taxVal = 0; // 默认计算税率为0

      if (key === 'netAmt') {
        // // 校验
        // const flag = formaInvoiceService.numValidation(+value); // 校验金额
        // if (!flag) {
        //   return false;
        // }
        // const newList = formaInvoiceService.countTaxAmt(payload, list); // 按输入项计算税额
        // yield put({ type: 'updateState', payload: { list: newList } });

        const { value: netAmt = 0 } = payload;
        const { taxAmt = 0 } = list[index];
        const invAmt = ((+taxAmt) + (+netAmt)).toFixed(2);

        list[index].netAmt = netAmt;
        list[index].invAmt = invAmt;
        yield put({ type: 'updateState', payload: { list: list } });
      } else if (key === 'taxAmt') {
        const { value: taxAmt = 0 } = payload;
        const { netAmt = 0 } = list[index];
        const invAmt = ((+netAmt) + (+taxAmt)).toFixed(2);

        list[index].taxAmt = taxAmt;
        list[index].invAmt = invAmt;
        yield put({ type: 'updateState', payload: { list: list } });
      } else if (key === 'invAmt') {
        // 校验
        // const flag = formaInvoiceService.numValidation(+value);
        // if (!flag) {
        //   return false;
        // }
        // const newList = formaInvoiceService.countTaxAmt(payload, list); // 按输入项计算税额
        //
        // yield put({ type: 'updateState', payload: { list: newList } });

        // if (value != null) {

        //   taxVal = list[index].taxVal == null ? 0 : list[index].taxVal;
        //   const netAmt = (value / (1 + taxVal/100)).toFixed(2);
        //   list[index].invAmt = value;
        //   list[index].netAmt = netAmt;
        //   list[index].taxAmt = value - +netAmt;
        // } else {
        //   list[index].invAmt = 0;
        //   list[index].netAmt = 0;
        //   list[index].taxAmt = 0;
        // }

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

      } else if (key === 'taxRate') {

        let taxCode = null;

        // 如果税率被置空，则按照0算
        if (value != null) {
          // 获取真实税率
          const result = yield call(taxService.getSingle,value);
          if (result.success && result.data) {
            taxVal = result.data.taxRate;
            taxCode = result.data.taxCode;
          } else {
            throw result.message;
          }
        } else {
          taxVal = 0;
        }

        // const invAmt = list[index].invAmt == null ? 0 : list[index].invAmt;
        // const netAmt = (invAmt/(1+taxVal/100)).toFixed(2);
        list[index].taxRate = value; // 更新列表中的税率值为新的税率ID
        list[index].taxVal = taxVal; // 将税率值缓存到列中
        list[index].taxCode = taxCode; // 更新列表中的税率编码
        // list[index].netAmt = netAmt;
        // list[index].taxAmt = invAmt - +netAmt;

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

      } else {
        yield put({type: 'updateCell', payload: {...payload}});
      }

      // 如果更新的是invAmt或taxRate，则更新完后重新统计发票总金额
      if (key === 'netAmt' || key === 'taxAmt') {
        const newFormData = formaInvoiceService.countFormActAmt(formData, list);
        yield put({type: 'updateState', payload: {formData: newFormData}});
      }
    },

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

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

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

    * clean({ payload }, { put }) {
      yield put({
        type: 'updateState',
        payload: {
          formData: null, // 发票详情(供应商的税率等)
          mode: 'view',
          list: [],  // 拆分后的发票列表
          advice: '',
          quotaList: [],
          accountCheckList: [], // 对账明细
          itemVisible: false,
          itemList: [],
          total: 0,
          itemCode: '',
          taxRate: 0,
        },
      });
    },

    * query({ payload }, { call, put,select }) {
      const {itemCode,taxRate,accountId} =yield select(({formaInvoice})=>formaInvoice);
      if(payload){
        payload.itemCode=itemCode;
        payload.taxRate=taxRate;
        payload.accountId=accountId;
      }
      const result = yield call(formaInvoiceService.queryList, payload);
      if (result.success) {
        result.data.invAmt = parseFloat(result.data.invAmt).toFixed(2); // 金额转为保留到小数点后两位
        result.data.taxAmt = parseFloat(result.data.taxAmt).toFixed(2);
        result.data.netAmt = parseFloat(result.data.netAmt).toFixed(2);
        // 对账单list
        yield put({
          type: 'updateState',
          payload: {
            itemList: result.data.rows,
            total: result.data.total,
          },
        });
      } else {
        throw result.message;
      }
    },

    * addRow({ payload }, { select, put }) {
      const { formData, list } = yield select(({formaInvoice})=>formaInvoice);
      const newList = list.slice();

      // const taxVal = +formData.taxVal; //税率
      // const taxRate = formData.taxRate; //税率id
      // const taxDesc = formData.taxDesc; //税率描述
      // const taxCode = formData.taxCode; // 税率编码
      const invType = formData.invForm; // 发票形式
      const invClass = formData.invType; // 发票种类
      const invDate = moment().format('YYYY-MM-DD');
      const newRow = {
        id: newList.length,
        invNo: '',
        invSymbol: '',
        invType,
        invStatusName: '待验证',
        invClass,
        // taxCode,
        // taxRate,
        // taxDesc,
        // taxVal,
        invDate,
        invAmt: 0,
        netAmt: 0,
        taxAmt: 0
      };
      newList.push(newRow);

      const newFormData = formaInvoiceService.countFormActAmt(formData, newList);

      yield put({
        type: 'updateState',
        payload: {
          formData: { ...newFormData, invNum: newList.length },
          list: newList
        }
      })
    },

    * deleteRow({ payload }, { select, put }) {
      const { formData, list } = yield select(({formaInvoice})=>formaInvoice);
      const newList = list.slice().filter((item) => item.id !== payload);

      const newFormData = formaInvoiceService.countFormActAmt(formData, newList);

      yield put({
        type: 'updateState',
        payload: {
          formData: { ...newFormData, invNum: newList.length },
          list: newList
        }
      })
    },

    // 所有发票需要进行的校验：
    // 1.当前开票，开票金额不允许大于定额
    // 进行发票校验
    // 正式发票需要进行的校验：
    // 1.当前开票，不允许出现 代码+号码+税率 均相同的发票
    // 2.当前开票，不允许出现 代码+号码 与历史发票相同的发票
    * checkInv({ payload }, { select, put, call }) {
      const { formData, list } = yield select(({formaInvoice})=>formaInvoice);

      console.log('formData', formData);
      console.log('list', list);
      // 所有发票
      // 1.开票金额不允许大于定额
      if (list && list.length > 0) {
        for (let inv of list) {
          if (inv.invAmt > formData.quota) {
            message.error("发票金额不能大于定额");
            return;
          }
        }
      }

      // 正式发票列表
      const newList = list.filter(i => i.invType === '1');

      // 1.校验是否存在 代码+号码+税率 均相同的发票
      // 只有发票数量大于1才进行校验
      if (newList && newList.length > 1) {
        for (let index = 0; index < newList.length; index++) {
          let invCode = `${newList[index].invNo}${newList[index].invIdCode}${newList[index].taxCode}`;
          for (let i = index + 1; i < newList.length; i++) {
            if (invCode === `${newList[i].invNo}${newList[i].invIdCode}${newList[i].taxCode}`) {
              message.error("发现重复发票，请修改后再进行操作");
              return;
            }
          }
        }
      }

      // 2.校验是否又相同的历史发票
      if (newList && newList.length > 0) {
        const data = yield call(formaInvoiceService.checkInv, newList);
        if (!data.success) {
          let errorMsg = data.message + " " + ( data.data && 'info' in data.data ? data.data.info : "");
          message.error(errorMsg);
          return;
        }
      }

      if (payload.submit) {
        yield put({
          type: 'submit'
        });
      } else {
        yield put({
          type: 'save',
        });
      }
    },
  },

  reducers: {

    updateCell(state, { payload }) {
      const { list } = state;
      const newList = list.slice();
      const { key, index, value } = payload;
      newList[index][key] = value;
      return {
        ...state,
        list: newList,
      };
    },

    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: object, { payload }) {
      const { itemCode, taxRate, accountId } = payload;
      return { ...state, itemCode, taxRate, accountId, itemVisible: true };
    },

    hideModal(state: object, { payload }) {
      return {
        ...state, ...payload, itemCode: '', taxRate: 0, accountId: 0, itemVisible: false, itemList: [], total: 0
      };
    },

  },

};
