package com.yifu.cloud.plus.v1.yifu.insurances.util;

import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.SalaryDaprUtil;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.SocialDaprUtils;
import com.yifu.cloud.plus.v1.yifu.common.security.util.SecurityUtils;
import com.yifu.cloud.plus.v1.yifu.ekp.constant.EkpConstants;
import com.yifu.cloud.plus.v1.yifu.ekp.util.EkpInsuranceUtil;
import com.yifu.cloud.plus.v1.yifu.insurances.constants.InsurancesConstants;
import com.yifu.cloud.plus.v1.yifu.insurances.entity.*;
import com.yifu.cloud.plus.v1.yifu.insurances.mapper.insurances.TInsuranceDetailMapper;
import com.yifu.cloud.plus.v1.yifu.insurances.mapper.insurances.TUpdateStatusErrorMapper;
import com.yifu.cloud.plus.v1.yifu.insurances.service.ekp.EkpSettleService;
import com.yifu.cloud.plus.v1.yifu.insurances.service.insurance.TInsuranceEkpService;
import com.yifu.cloud.plus.v1.yifu.insurances.service.insurance.TInsuranceSettleCancelService;
import com.yifu.cloud.plus.v1.yifu.insurances.service.insurance.TInsuranceSettleService;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.EkpInsuranceViewVo;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.EkpInteractiveParam;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.EkpSocialViewVo;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.EkpStatusParamVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 主要执行商险的异步推送
 * @author huyc
 * @Date 2022-11-30
 * @Description 多线程的执行
 */
@Slf4j
@Component
public class DoJointInsuranceTask {

    @Resource
	private TInsuranceSettleService tInsuranceSettleService;

	@Autowired
	private EkpInsuranceUtil eKPInsuranceUtil;

	@Autowired
	private TInsuranceEkpService tInsuranceEkpService;

	@Autowired
	private TInsuranceSettleCancelService tInsuranceSettleCancelService;

	@Autowired
	private EkpSettleService ekpSettleService;

	@Autowired
	private TInsuranceDetailMapper insuranceDetailMapper;

	@Autowired
	private SocialDaprUtils socialDaprUtils;

	@Autowired
	private SalaryDaprUtil salaryDaprUtil;

	@Autowired
	private TUpdateStatusErrorMapper updateStatusErrorMapper;

    /**
     * @Description: 商险明细推送
     * @Author: huyc
     * @Date: 2022-11-30
     * @return: void
     **/
    @Async
    public void asynchronousEkpInfo(TInsuranceDetail detail, TInsuranceSettle settle, Integer type) {
        log.info("推送商险明细到EKP-线程开始");
        try {
			String s = pushEstimate(detail,type);
			if(StringUtils.isNotBlank(s)){
				if (type == CommonConstants.ONE_INT) {
					settle.setIsEstimatePush(CommonConstants.ONE_INT);
					settle.setEstimatePushTime(LocalDateTime.now());
				} else {
					settle.setIsActualPush(CommonConstants.ONE_INT);
					settle.setActualPushTime(LocalDateTime.now());
				}
				tInsuranceSettleService.updateById(settle);
			}
        } catch (Exception e) {
            log.error("推送商险明细到EKP错误", e);
        }
        log.info("推送商险明细到EKP结束");
    }

	/**
	 * 推送EKP
	 *
	 * @author zhaji
	 * @param
	 * @return {@link String}
	 */
	private String pushEstimate(TInsuranceDetail tInsuranceDetail,Integer type){
		YifuUser user = SecurityUtils.getUser();
		Integer pushType = null;
		//1,推送预估保费，2，推送实际保费，3推送预估冲正保费，4更新实际保费
		EkpInteractiveParam param = new EkpInteractiveParam();
		TInsuranceSettleCancel cancel = new TInsuranceSettleCancel();
		BeanCopyUtils.copyProperties(tInsuranceDetail,param);
		param.setDetailId(tInsuranceDetail.getId());
		Integer settleType = tInsuranceDetail.getSettleType();
		if(CommonConstants.ZERO_INT == settleType){
			param.setEstimateStatus(EkpConstants.HAVE);
		}else {
			param.setEstimateStatus(EkpConstants.NOTHING);
		}
		if (Common.isNotNull(tInsuranceDetail.getUnitName())) {
			param.setCustomerName(tInsuranceDetail.getUnitName());
		}
		if (Common.isNotNull(tInsuranceDetail.getUnitNo())) {
			param.setCustomerCode(tInsuranceDetail.getUnitNo());
		}
		//1,推送预估保费(用户办理成功，推送预估保费)
		if(CommonConstants.ONE_INT == type){
			param.setInteractiveType(InsurancesConstants.NEW_SETTLE_BILL);
			param.setSettleType(InsurancesConstants.ESTIMATE_SETTLE_BILL);
			pushType = CommonConstants.ONE_INT;
		}
		//2，推送实际保费(用于登记保单保费未推送过实缴保费)
		if(CommonConstants.TWO_INT == type){
			param.setInteractiveType(InsurancesConstants.NEW_SETTLE_BILL);
			param.setSettleType(InsurancesConstants.ACTUAL_SETTLE_BILL);
			pushType = CommonConstants.TWO_INT;
		}
		//3推送预估冲正保费(用于投保退回场景)
		if(CommonConstants.THREE_INT == type){
			String defaultSettleId = tInsuranceDetail.getDefaultSettleId();
			TInsuranceSettle byId = tInsuranceSettleService.getById(defaultSettleId);
			//冲正取负数
			if(null != byId.getEstimatePremium()){
				param.setEstimatePremium(byId.getEstimatePremium());
			}
			param.setInteractiveType(InsurancesConstants.CORRECT_SETTLE_BILL);
			param.setSettleType(InsurancesConstants.ESTIMATE_SETTLE_BILL);
			pushType = CommonConstants.FIVE_INT;
		}
		//6推送实缴红冲(用于投保退回场景)
		if(CommonConstants.SIX_INT == type){
			String defaultSettleId = tInsuranceDetail.getDefaultSettleId();
			TInsuranceSettle byId = tInsuranceSettleService.getById(defaultSettleId);
			//冲正取负数
			if(null != byId.getActualPremium()){
				param.setActualPremium(byId.getActualPremium());
			}
			param.setInteractiveType(InsurancesConstants.CORRECT_SETTLE_BILL);
			param.setSettleType(InsurancesConstants.ACTUAL_SETTLE_BILL);
			pushType = CommonConstants.SIX_INT;
		}
		//4更新实际保费(用于登记保单保费场景推送过实缴保费)
		if(CommonConstants.FOUR_INT == type){
			param.setInteractiveType(InsurancesConstants.UPDATE_SETTLE_BILL);
			param.setSettleType(InsurancesConstants.ACTUAL_SETTLE_BILL);
			pushType = CommonConstants.THREE_INT;
		}
		//作废
		if(CommonConstants.FIVE_INT == type){
			cancel.setDeptNo(tInsuranceDetail.getDeptNo());
			cancel.setInsDetailId(tInsuranceDetail.getId());
			cancel.setSettleId(tInsuranceDetail.getDefaultSettleId());
			cancel.setCreateUesr(user.getId());
			cancel.setCreateTime(LocalDateTime.now());
			cancel.setDeptName(param.getDeptName());
			cancel.setIsCancelPush(CommonConstants.ZERO_INT);
			tInsuranceSettleCancelService.save(cancel);
			param.setInteractiveType(InsurancesConstants.ABOLISH_SETTLE_BILL);
			param.setSettleType(CommonConstants.EMPTY_STRING);
			pushType = CommonConstants.FOUR_INT;
		}
		String s = eKPInsuranceUtil.sendToEkp(param);
		if(StringUtils.isBlank(s)){
			saveInsuranceEkp(param,pushType);
			return null;
		}else {
			return s;
		}
	}

	/**
	 * 保存失败信息
	 *
	 * @author zhaji
	 * @param
	 * @return {@link String}
	 */
	private void saveInsuranceEkp(EkpInteractiveParam param, Integer pushType){
		TInsuranceEkp ekp = new TInsuranceEkp();
		BeanCopyUtils.copyProperties(param,ekp);
		ekp.setId(null);
		ekp.setCreateTime(LocalDateTime.now());
		ekp.setPushType(pushType);
		tInsuranceEkpService.save(ekp);
	}

	@Async
	public void updateInsuranceSettleStatus(EkpStatusParamVo vo) {
		try {
			//根据结算单号获取明细id和结算状态
			List<EkpInsuranceViewVo> viewVoList;
			TInsuranceDetail detail;
			viewVoList = ekpSettleService.selectViewBySettleNo(vo.getSettleNo(), vo.getPayFlag());
			if (!viewVoList.isEmpty()) {
				String insuranceId;
				for (EkpInsuranceViewVo viewVo : viewVoList) {
					//获取所有的明细id
					insuranceId = viewVo.getId().substring(0, 19);
					detail = insuranceDetailMapper.selectById(insuranceId);
					if (Common.isNotNull(detail)) {
						//判断订单类型是预估还是实缴
						if (InsurancesConstants.ACTUAL_SETTLE_BILL.equals(viewVo.getOrderType())) {
							//判断是收入还是支出结算单号
							if (CommonConstants.ZERO_STRING.equals(vo.getPayFlag())) {
								detail.setSincomeSettleFlag(viewVo.getIncomeSettleFlag());
								detail.setSincomeCollectFlag(viewVo.getIncomeCollectFlag());
							} else {
								detail.setSpaySettleFlag(viewVo.getPaySettleFlag());
								detail.setSpayCollectFlag(viewVo.getPayCollectFlag());
							}
						} else {
							if (CommonConstants.ZERO_STRING.equals(vo.getPayFlag())) {
								detail.setIncomeSettleFlag(viewVo.getIncomeSettleFlag());
								detail.setIncomeCollectFlag(viewVo.getIncomeCollectFlag());
							} else {
								detail.setPaySettleFlag(viewVo.getPaySettleFlag());
								detail.setPayCollectFlag(viewVo.getPayCollectFlag());
							}
						}
						insuranceDetailMapper.updateById(detail);
					}
				}
			}
		} catch (Exception e) {
			TUpdateStatusError error = new TUpdateStatusError();
			error.setSettleNo(vo.getSettleNo());
			error.setStatus(CommonConstants.ZERO_INT);
			error.setTitle(e.getMessage());
			error.setTypeFlag(CommonConstants.FOUR_STRING);
			error.setCreateTime(DateUtil.getCurrentDateTime());
			error.setSettleType(vo.getPayFlag());
			updateStatusErrorMapper.insert(error);
			log.error("推送商险明细到EKP错误", e);
		}
	}

	@Async
	public void updateSocialSettleStatus(EkpStatusParamVo vo) {
		List<EkpSocialViewVo> viewVo;
		try {
			//根据结算单号获取明细id和结算状态
			if (CommonConstants.ZERO_STRING.equals(vo.getTypeFlag())) {
				viewVo = ekpSettleService.selectSocialViewBySettleNo(vo.getSettleNo(), vo.getPayFlag());
			} else {
				viewVo = ekpSettleService.selectFundViewBySettleNo(vo.getSettleNo(), vo.getPayFlag());
			}
			if (!viewVo.isEmpty()) {
				viewVo.forEach(e -> e.setPayFlag(vo.getPayFlag()));
				R<Boolean> flag = socialDaprUtils.updateSocialSettleStatus(viewVo);
				if (Common.isEmpty(flag) || Boolean.TRUE.equals(!flag.getData())) {
					TUpdateStatusError error = new TUpdateStatusError();
					error.setSettleNo(vo.getSettleNo());
					error.setStatus(CommonConstants.ZERO_INT);
					error.setTitle("社保结算状态同步失败");
					error.setTypeFlag(vo.getTypeFlag());
					error.setCreateTime(DateUtil.getCurrentDateTime());
					error.setSettleType(vo.getPayFlag());
					updateStatusErrorMapper.insert(error);
				}
			}
		} catch (Exception e) {
			TUpdateStatusError error = new TUpdateStatusError();
			error.setSettleNo(vo.getSettleNo());
			error.setStatus(CommonConstants.ZERO_INT);
			error.setTitle("社保结算状态同步失败");
			error.setTypeFlag(vo.getTypeFlag());
			error.setCreateTime(DateUtil.getCurrentDateTime());
			error.setSettleType(vo.getPayFlag());
			updateStatusErrorMapper.insert(error);
			log.error("社保结算状态更新异常", e);
		}
	}

	@Async
	public void updateIncomeSettleStatus(EkpStatusParamVo vo) {
		List<EkpInsuranceViewVo> viewVo;
		try {
			//根据结算单号获取明细id和结算状态
			//根据结算单号获取明细id和结算状态；判断是管理费还是风险金
			if (CommonConstants.ZERO_STRING.equals(vo.getTypeFlag())) {
				viewVo = ekpSettleService.selectIncomelViewBySettleNo(vo.getSettleNo());
			} else {
				viewVo = ekpSettleService.selectFIncomelViewBySettleNo(vo.getSettleNo());
			}
			if (!viewVo.isEmpty()) {
				R<Boolean> flag = socialDaprUtils.updateIncomeSettleStatus(viewVo);
				if (Common.isEmpty(flag) || Boolean.TRUE.equals(!flag.getData())) {
					TUpdateStatusError error = new TUpdateStatusError();
					error.setSettleNo(vo.getSettleNo());
					error.setStatus(CommonConstants.ZERO_INT);
					error.setTitle("收入结算状态同步失败");
					error.setTypeFlag(CommonConstants.ZERO_STRING.equals(vo.getTypeFlag()) ? "2" : "3");
					error.setCreateTime(DateUtil.getCurrentDateTime());
					error.setSettleType(vo.getPayFlag());
					updateStatusErrorMapper.insert(error);
				}
			}
		} catch (Exception e) {
			TUpdateStatusError error = new TUpdateStatusError();
			error.setSettleNo(vo.getSettleNo());
			error.setStatus(CommonConstants.ZERO_INT);
			error.setTitle("收入结算状态同步失败");
			error.setTypeFlag(CommonConstants.ZERO_STRING.equals(vo.getTypeFlag()) ? "2" : "3");
			error.setCreateTime(DateUtil.getCurrentDateTime());
			error.setSettleType(vo.getPayFlag());
			updateStatusErrorMapper.insert(error);
			log.error("收入结算状态更新异常", e);
		}
	}

	@Async
	public void updateSalarySettleStatus(EkpStatusParamVo vo) {
		List<EkpSocialViewVo> viewVo;
		try {
			//根据结算单号获取明细id和结算状态
			viewVo = ekpSettleService.selectSalarylViewBySettleNo(vo.getSettleNo(), vo.getPayFlag());
			if (!viewVo.isEmpty()) {
				viewVo.forEach(e -> e.setPayFlag(vo.getPayFlag()));
				R<Boolean> flag = salaryDaprUtil.updateSalarySettleStatus(viewVo);
				if (Common.isEmpty(flag) || Boolean.TRUE.equals(!flag.getData())) {
					TUpdateStatusError error = new TUpdateStatusError();
					error.setSettleNo(vo.getSettleNo());
					error.setStatus(CommonConstants.ZERO_INT);
					error.setTitle("薪资结算状态同步失败");
					error.setTypeFlag(CommonConstants.FIVE_STRING);
					error.setCreateTime(DateUtil.getCurrentDateTime());
					error.setSettleType(vo.getPayFlag());
					updateStatusErrorMapper.insert(error);
				}
			}
		} catch (Exception e) {
			TUpdateStatusError error = new TUpdateStatusError();
			error.setSettleNo(vo.getSettleNo());
			error.setStatus(CommonConstants.ZERO_INT);
			error.setTitle("薪资结算状态同步失败");
			error.setTypeFlag(CommonConstants.FIVE_STRING);
			error.setCreateTime(DateUtil.getCurrentDateTime());
			error.setSettleType(vo.getPayFlag());
			updateStatusErrorMapper.insert(error);
			log.error("薪资结算状态更新异常", e);
		}
	}

	public void aUpdateInsuranceSettleStatus(TUpdateStatusError error) {
		try {
			//根据结算单号获取明细id和结算状态
			List<EkpInsuranceViewVo> viewVoList;
			TInsuranceDetail detail;
			viewVoList = ekpSettleService.selectViewBySettleNo(error.getSettleNo(), error.getSettleType());
			if (!viewVoList.isEmpty()) {
				String insuranceId;
				for (EkpInsuranceViewVo viewVo : viewVoList) {
					//获取所有的明细id
					insuranceId = viewVo.getId().substring(0, 19);
					detail = insuranceDetailMapper.selectById(insuranceId);
					if (Common.isNotNull(detail)) {
						//判断订单类型是预估还是实缴
						if (InsurancesConstants.ACTUAL_SETTLE_BILL.equals(viewVo.getOrderType())) {
							//判断是收入还是支出结算单号
							if (CommonConstants.ZERO_STRING.equals(error.getSettleType())) {
								detail.setSincomeSettleFlag(viewVo.getIncomeSettleFlag());
								detail.setSincomeCollectFlag(viewVo.getIncomeCollectFlag());
							} else {
								detail.setSpaySettleFlag(viewVo.getPaySettleFlag());
								detail.setSpayCollectFlag(viewVo.getPayCollectFlag());
							}
						} else {
							if (CommonConstants.ZERO_STRING.equals(error.getSettleType())) {
								detail.setIncomeSettleFlag(viewVo.getIncomeSettleFlag());
								detail.setIncomeCollectFlag(viewVo.getIncomeCollectFlag());
							} else {
								detail.setPaySettleFlag(viewVo.getPaySettleFlag());
								detail.setPayCollectFlag(viewVo.getPayCollectFlag());
							}
						}
						insuranceDetailMapper.updateById(detail);
					}
				}
				error.setStatus(CommonConstants.ONE_INT);
				error.setTitle(InsurancesConstants.AGAIN_UPDATE_STATUS);
				updateStatusErrorMapper.updateById(error);
			}
		} catch (Exception e) {
			log.error("更新商险结算状态错误", e);
		}
	}

	public void aUpdateSocialSettleStatus(TUpdateStatusError error) {
		List<EkpSocialViewVo> viewVo;
		try {
			//根据结算单号获取明细id和结算状态
			if (CommonConstants.ZERO_STRING.equals(error.getTypeFlag())) {
				viewVo = ekpSettleService.selectSocialViewBySettleNo(error.getSettleNo(), error.getSettleType());
			} else {
				viewVo = ekpSettleService.selectFundViewBySettleNo(error.getSettleNo(), error.getSettleType());
			}
			if (!viewVo.isEmpty()) {
				viewVo.forEach(e -> e.setPayFlag(error.getSettleType()));
				R<Boolean> flag = socialDaprUtils.updateSocialSettleStatus(viewVo);
				if (!Common.isEmpty(flag) || Boolean.TRUE.equals(flag.getData())) {
					error.setStatus(CommonConstants.ONE_INT);
					error.setTitle(InsurancesConstants.AGAIN_UPDATE_STATUS);
					updateStatusErrorMapper.updateById(error);
				}
			}
		} catch (Exception e) {
			log.error("社保结算状态更新异常", e);
		}
	}

	public void aUpdateIncomeSettleStatus(TUpdateStatusError error) {
		List<EkpInsuranceViewVo> viewVo;
		try {
			//根据结算单号获取明细id和结算状态
			//根据结算单号获取明细id和结算状态；判断是管理费还是风险金
			if (CommonConstants.TWO_STRING.equals(error.getTypeFlag())) {
				viewVo = ekpSettleService.selectIncomelViewBySettleNo(error.getSettleNo());
			} else {
				viewVo = ekpSettleService.selectFIncomelViewBySettleNo(error.getSettleNo());
			}
			if (!viewVo.isEmpty()) {
				R<Boolean> flag = socialDaprUtils.updateIncomeSettleStatus(viewVo);
				if (!Common.isEmpty(flag) || Boolean.TRUE.equals(flag.getData())) {
					error.setStatus(CommonConstants.ONE_INT);
					error.setTitle(InsurancesConstants.AGAIN_UPDATE_STATUS);
					updateStatusErrorMapper.updateById(error);
				}
			}
		} catch (Exception e) {
			log.error("收入结算状态更新异常", e);
		}
	}

	public void aUpdateSalarySettleStatus(TUpdateStatusError error) {
		List<EkpSocialViewVo> viewVo;
		try {
			//根据结算单号获取明细id和结算状态
			viewVo = ekpSettleService.selectSalarylViewBySettleNo(error.getSettleNo(), error.getSettleType());
			if (!viewVo.isEmpty()) {
				viewVo.forEach(e -> e.setPayFlag(error.getSettleType()));
				R<Boolean> flag = salaryDaprUtil.updateSalarySettleStatus(viewVo);
				if (!Common.isEmpty(flag) && Boolean.TRUE.equals(flag.getData())) {
					error.setStatus(CommonConstants.ONE_INT);
					error.setTitle("再次同步状态成功");
					error.setTypeFlag(CommonConstants.FIVE_STRING);
					updateStatusErrorMapper.updateById(error);
				}
			}
		} catch (Exception e) {
			log.error("薪资结算状态更新异常", e);
		}
	}
}
