package com.dhcc.finance.main.service.impl;

import brave.Tracer;
import com.dhcc.common.constant.FinanceStatusCode;
import com.dhcc.common.constant.SysConstants;
import com.dhcc.common.constant.enums.BusStateEnum;
import com.dhcc.common.constant.enums.UsestateEnum;
import com.dhcc.common.model.CurrencyMeta;
import com.dhcc.common.model.response.RestfulResponse;
import com.dhcc.common.util.SnowflakeIdWorker;
import com.dhcc.finance.constant.FinanceDictConsts;
import com.dhcc.finance.main.client.BatchTaskMonitorFeignClient;
import com.dhcc.finance.main.dao.CwBdGlorgbookMapper;
import com.dhcc.finance.main.dao.CwBdRecordTransferMapper;
import com.dhcc.finance.main.domain.CwBdGlorgbook;
import com.dhcc.finance.main.domain.CwBdRecordTransfer;
import com.dhcc.finance.main.domain.CwBdRecordTransferExample;
import com.dhcc.finance.main.model.CwGlTransferWeb;
import com.dhcc.finance.main.service.CwGlSettleService;
import com.dhcc.finance.main.service.CwGlTransferExecService;
import com.dhcc.finance.main.service.FinanceBatchService;
import com.dhcc.finance.util.FinanceDateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 功能描述：财务批量处理
 *
 * @author dml
 * @date 2019年11月27日 上午10:52:25
 * @修改日志：
 */
@Slf4j
@Service
public class FinanceBatchServiceImpl implements FinanceBatchService {

    @Autowired
    private Tracer tracer;

    @Autowired
    CwBdGlorgbookMapper cwBdGlorgbookMapper;// 账套信息

    @Autowired
    CwGlTransferExecService cwGlTransferExecService;// 结转服务

    @Autowired
    CwGlSettleService cwGlSettleService;// 结账服务

    @Autowired
    CwBdRecordTransferMapper cwBdRecordTransferMapper;// 记录表

    @Autowired
    BatchTaskMonitorFeignClient batchTaskMonitorFeignClient;

    /*
     * (非 Javadoc)
     * Title: startCarryForwardAndSettle
     * Description:结转结账
     * @param period
     * @return
     * @see com.dhcc.finance.main.service.FinanceBatchService#startCarryForwardAndSettle(java.lang.String)
     * @author dml
     * @date 2019年11月27日 上午10:52:57
     * @修改日志：
     */
    @Async
    @Override
    public void startCarryForwardAndSettle(String quartzJobName, String batchMonitorId) {
        // 查出所有在用的帐套
        List<CwBdGlorgbook> selectIsBatch = cwBdGlorgbookMapper.selectIsBatch();
        // 取到当期日期上一个月
        String period = FinanceDateUtil.getLastMonth(FinanceDateUtil.getPeriod(new Date()), "yyyy-MM", -1);
        int failsNum = selectIsBatch.size();
        int allNum = selectIsBatch.size();
        for (CwBdGlorgbook cwBdGlorgbook : selectIsBatch) {
            try {
                // 新增记录
                CwBdRecordTransfer cwBdRecordTransfer = new CwBdRecordTransfer();
                String cwId = SnowflakeIdWorker.getInstance().nextIdString();
                cwBdRecordTransfer.setId(cwId);
                cwBdRecordTransfer.setBatchMonitorId(batchMonitorId);
                cwBdRecordTransfer.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
                cwBdRecordTransfer.setGlorgbookName(cwBdGlorgbook.getName());
                cwBdRecordTransfer.setPeriod(period);
                cwBdRecordTransfer.setIsTransfer(FinanceDictConsts.Syzt.INVALID);// 初始化都失败了成功在修改
                cwBdRecordTransfer.setIsSettle(FinanceDictConsts.Syzt.INVALID);
                cwBdRecordTransfer.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
                cwBdRecordTransfer.setCreateTime(new Date());
                int insert = cwBdRecordTransferMapper.insert(cwBdRecordTransfer);
                if (insert != 1) {
                    continue;
                }
                RestfulResponse<Object, CurrencyMeta> res1 = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                        SysConstants.DEFAULT_MESSAGE.OPERATION_FAIL);
                RestfulResponse<Object, CurrencyMeta> res2 = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                        SysConstants.DEFAULT_MESSAGE.OPERATION_FAIL);
                // 先结转在结账
                try {
                    List<CwGlTransferWeb> cwGlSettles = new ArrayList<CwGlTransferWeb>();
                    CwGlTransferWeb param = new CwGlTransferWeb();
                    BeanUtils.copyProperties(cwBdGlorgbook, param);
                    param.setPkCurrperiod(period);
                    param.setAccounting_id("admin");
                    cwGlSettles.add(param);
                    res1 = cwGlTransferExecService.updateCwGlTransferExecForBatch(cwGlSettles);
                    // 已结转的继续结账
                    if (res1 != null && (SysConstants.CODE.SUCCESS == res1.getCode() || res1.getMsg().contains(FinanceStatusCode.GLORGBOOK_COVERAGE_BEEN_SETTLE.message()))) {
                        res2 = cwGlSettleService.updateCwGlSettleForBatch(cwGlSettles);
                    }
                } catch (Exception e) {
                    log.error("结转结账异常>>>>>>>>>>>", e);
                } finally {
                    // 更新执行结果
                    CwBdRecordTransfer updInfo = new CwBdRecordTransfer();
                    updInfo.setId(cwId);
                    updInfo.setUpdateTime(new Date());
                    if (SysConstants.CODE.FAIL == res1.getCode() && !res1.getMsg().contains(FinanceStatusCode.GLORGBOOK_COVERAGE_BEEN_SETTLE.message())) {
                        updInfo.setRansferFailreason(res1.getMsg());
                    } else {
                        updInfo.setIsTransfer(FinanceDictConsts.Syzt.EFFECTIVE);
                        if (SysConstants.CODE.FAIL == res2.getCode()) {
                            updInfo.setSettleFailreason(res2.getMsg());
                        } else {
                            failsNum--;
                            updInfo.setIsSettle(FinanceDictConsts.Syzt.EFFECTIVE);
                        }
                    }
                    cwBdRecordTransferMapper.updateByPrimaryKeySelective(updInfo);
                }
            } catch (Exception e) {
                log.error("结转记录失败>>>>", e);
            }
        }

        // 回调更新批量状态
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("quartzJobName", quartzJobName);
        map.put("batchMonitorId", batchMonitorId);
        map.put("busState", BusStateEnum.PARTIALSUCCESS.getCode());

        if (failsNum == 0) {
            map.put("busState", BusStateEnum.SUCCESS.getCode());
        } else if (failsNum == allNum) {
            map.put("busState", BusStateEnum.FAILURE.getCode());
        }
        batchTaskMonitorFeignClient.updateBatchTaskMonitorState(map);

    }

    @Async
    @Override
    public void startCarryForward(String quartzJobName, String batchMonitorId) {
        // 查出所有在用的帐套
        List<CwBdGlorgbook> selectIsBatch = cwBdGlorgbookMapper.selectIsBatch();
        // 取到当期日期上一个月
        String period = FinanceDateUtil.getLastMonth(FinanceDateUtil.getPeriod(new Date()), "yyyy-MM", -1);
        int failsNum = selectIsBatch.size();
        int allNum = selectIsBatch.size();
        for (CwBdGlorgbook cwBdGlorgbook : selectIsBatch) {
            try {
                // 新增记录
                CwBdRecordTransfer cwBdRecordTransfer = new CwBdRecordTransfer();
                String cwId = SnowflakeIdWorker.getInstance().nextIdString();
                cwBdRecordTransfer.setId(cwId);
                cwBdRecordTransfer.setBatchMonitorId(batchMonitorId);
                cwBdRecordTransfer.setPkGlorgbook(cwBdGlorgbook.getPkGlorgbook());
                cwBdRecordTransfer.setGlorgbookName(cwBdGlorgbook.getName());
                cwBdRecordTransfer.setPeriod(period);
                cwBdRecordTransfer.setIsTransfer(FinanceDictConsts.Syzt.INVALID);// 初始化都失败了成功在修改
                cwBdRecordTransfer.setIsSettle(FinanceDictConsts.Syzt.INVALID);
                cwBdRecordTransfer.setUseState(FinanceDictConsts.Syzt.EFFECTIVE);
                cwBdRecordTransfer.setCreateTime(new Date());
                int insert = cwBdRecordTransferMapper.insert(cwBdRecordTransfer);
                if (insert != 1) {
                    continue;
                }
                RestfulResponse<Object, CurrencyMeta> res1 = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                        SysConstants.DEFAULT_MESSAGE.OPERATION_FAIL);
                // 先结转在结账
                try {
                    List<CwGlTransferWeb> cwGlSettles = new ArrayList<CwGlTransferWeb>();
                    CwGlTransferWeb param = new CwGlTransferWeb();
                    BeanUtils.copyProperties(cwBdGlorgbook, param);
                    param.setPkCurrperiod(period);
                    param.setAccounting_id("admin");
                    cwGlSettles.add(param);
                    res1 = cwGlTransferExecService.updateCwGlTransferExecForBatch(cwGlSettles);

                } catch (Exception e) {
                    log.error("结转异常>>>>>>>>>>>", e);
                } finally {
                    // 更新执行结果
                    CwBdRecordTransfer updInfo = new CwBdRecordTransfer();
                    updInfo.setId(cwId);
                    updInfo.setUpdateTime(new Date());
                    if (SysConstants.CODE.FAIL == res1.getCode()) {
                        updInfo.setRansferFailreason(res1.getMsg());
                    } else {
                        updInfo.setIsTransfer(FinanceDictConsts.Syzt.EFFECTIVE);
                        failsNum--;
                    }
                    cwBdRecordTransferMapper.updateByPrimaryKeySelective(updInfo);
                }
            } catch (Exception e) {
                log.error("结转记录失败>>>>", e);
            }
        }

        // 回调更新批量状态
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("quartzJobName", quartzJobName);
        map.put("batchMonitorId", batchMonitorId);
        map.put("busState", BusStateEnum.PARTIALSUCCESS.getCode());

        if (failsNum == 0) {
            map.put("busState", BusStateEnum.SUCCESS.getCode());
        } else if (failsNum == allNum) {
            map.put("busState", BusStateEnum.FAILURE.getCode());
        }
        batchTaskMonitorFeignClient.updateBatchTaskMonitorState(map);

    }

    @Async
    @Override
    public void startSettle(String quartzJobName, String batchMonitorId) {
        // 查出所有在用的帐套
        List<CwBdGlorgbook> selectIsBatch = cwBdGlorgbookMapper.selectIsBatch();
        // 取到当期日期上一个月
        String period = FinanceDateUtil.getLastMonth(FinanceDateUtil.getPeriod(new Date()), "yyyy-MM", -1);
        int failsNum = selectIsBatch.size();
        int allNum = selectIsBatch.size();
        for (CwBdGlorgbook cwBdGlorgbook : selectIsBatch) {
            try {

                RestfulResponse<Object, CurrencyMeta> res2 = new RestfulResponse<Object, CurrencyMeta>(SysConstants.CODE.FAIL,
                        SysConstants.DEFAULT_MESSAGE.OPERATION_FAIL);
                try {
                    List<CwGlTransferWeb> cwGlSettles = new ArrayList<CwGlTransferWeb>();
                    CwGlTransferWeb param = new CwGlTransferWeb();
                    BeanUtils.copyProperties(cwBdGlorgbook, param);
                    param.setPkCurrperiod(period);
                    param.setAccounting_id("admin");
                    cwGlSettles.add(param);
                    // 已结转的继续结账
                    res2 = cwGlSettleService.updateCwGlSettleForBatch(cwGlSettles);
                } catch (Exception e) {
                    log.error("结转结账异常>>>>>>>>>>>", e);
                } finally {
                    // 更新执行结果
                    CwBdRecordTransfer updInfo = new CwBdRecordTransfer();
                    // updInfo.setId(cwId);
                    updInfo.setUpdateTime(new Date());
                    if (SysConstants.CODE.FAIL == res2.getCode()) {
                        updInfo.setSettleFailreason(res2.getMsg());

                    } else {
                        failsNum--;
                        updInfo.setIsSettle(FinanceDictConsts.Syzt.EFFECTIVE);
                    }
                    CwBdRecordTransferExample example = new CwBdRecordTransferExample();
                    CwBdRecordTransferExample.Criteria criteria = example.createCriteria();
                    criteria.andPkGlorgbookEqualTo(cwBdGlorgbook.getPkGlorgbook());
                    criteria.andPeriodEqualTo(period);
                    criteria.andUseStateEqualTo(UsestateEnum.EFFECTIVE.getCodeStr());
                    cwBdRecordTransferMapper.updateByExampleSelective(updInfo, example);

                }
            } catch (Exception e) {
                log.error("结转记录失败>>>>", e);
            }
        }

        // 回调更新批量状态
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("quartzJobName", quartzJobName);
        map.put("batchMonitorId", batchMonitorId);
        map.put("busState", BusStateEnum.PARTIALSUCCESS.getCode());

        if (failsNum == 0) {
            map.put("busState", BusStateEnum.SUCCESS.getCode());
        } else if (failsNum == allNum) {
            map.put("busState", BusStateEnum.FAILURE.getCode());
        }
        batchTaskMonitorFeignClient.updateBatchTaskMonitorState(map);

    }


}
