package com.yifu.cloud.plus.v1.yifu.insurances.service.insurance.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.R;
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.TInsuranceDetail;
import com.yifu.cloud.plus.v1.yifu.insurances.entity.TInsuranceEkp;
import com.yifu.cloud.plus.v1.yifu.insurances.entity.TInsuranceSettle;
import com.yifu.cloud.plus.v1.yifu.insurances.mapper.insurances.TInsuranceEkpMapper;
import com.yifu.cloud.plus.v1.yifu.insurances.service.ekp.EkpSettleService;
import com.yifu.cloud.plus.v1.yifu.insurances.service.insurance.TInsuranceDetailService;
import com.yifu.cloud.plus.v1.yifu.insurances.service.insurance.TInsuranceEkpService;
import com.yifu.cloud.plus.v1.yifu.insurances.service.insurance.TInsuranceSettleService;
import com.yifu.cloud.plus.v1.yifu.insurances.util.BeanCopyUtils;
import com.yifu.cloud.plus.v1.yifu.insurances.util.BigDecimalUtils;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.EkpInteractiveParam;
import com.yifu.cloud.plus.v1.yifu.insurances.vo.SettleVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
* @author Administrator
* @description 针对表【t_insurance_ekp(ekp交互失败存储表)】的数据库操作Service实现
* @createDate 2022-08-23 17:02:49
*/
@Service
@Slf4j
public class TInsuranceEkpServiceImpl extends ServiceImpl<TInsuranceEkpMapper, TInsuranceEkp> implements TInsuranceEkpService {

	@Resource
	EkpInsuranceUtil ekpInsuranceUtil;

	@Resource
	TInsuranceSettleService tInsuranceSettleService;
	@Resource
	@Lazy
	TInsuranceDetailService tInsuranceDetailService;

	@Resource
	@Lazy
	EkpSettleService ekpSettleService;


	@Override
	public R resend() {
		List<TInsuranceEkp> ekpRefundList = this.baseMapper.getEkpRefundList();
		if (CollectionUtils.isNotEmpty(ekpRefundList)){
			for (TInsuranceEkp tInsuranceEkp : ekpRefundList) {
				LambdaUpdateWrapper<TInsuranceEkp> ekpUpdate = new LambdaUpdateWrapper<>();
				ekpUpdate.eq(TInsuranceEkp :: getId,tInsuranceEkp.getId());
				TInsuranceDetail byId = tInsuranceDetailService.getById(tInsuranceEkp.getDetailId());
				if(Common.isEmpty(byId)){
					ekpUpdate.set(TInsuranceEkp :: getResendFlag,CommonConstants.TWO_INT);
					ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_INSURANCE_IS_DELETE_OR_EMPTY);
					update(ekpUpdate);
					continue;
				}
				String defaultSettleId = byId.getDefaultSettleId();
				String s = null;
				String settleType = tInsuranceEkp.getSettleType();
				Integer pushType = tInsuranceEkp.getPushType();
				//商险结算信息
				TInsuranceSettle insuranceSettle = tInsuranceSettleService.getById(tInsuranceEkp.getDefaultSettleId());
				//结算id是否一致
				boolean settleIdEquals = tInsuranceEkp.getDefaultSettleId().equals(defaultSettleId);
				//预估是否已发送
				boolean estimatePush = Common.isEmpty(insuranceSettle) || insuranceSettle.getIsEstimatePush() == CommonConstants.ZERO_INT;
				//实缴是否已发送
				boolean actualPush = Common.isEmpty(insuranceSettle) || insuranceSettle.getIsActualPush() == CommonConstants.ZERO_INT;
				//结算类型是否一致
				boolean settleTypeEquals = settleType.equals(byId.getSettleType().toString());
				EkpInteractiveParam ekpParam = new EkpInteractiveParam();
				BeanCopyUtils.copyProperties(tInsuranceEkp,ekpParam);
				LambdaUpdateWrapper<TInsuranceSettle> settleUpdate = new LambdaUpdateWrapper<>();
				settleUpdate.eq(TInsuranceSettle :: getId,tInsuranceEkp.getDefaultSettleId());
				LambdaUpdateWrapper<TInsuranceDetail> detailUpdate = new LambdaUpdateWrapper<>();
				detailUpdate.eq(TInsuranceDetail :: getId,tInsuranceEkp.getDetailId());
				//ekp结算信息
				SettleVo settleVo = tInsuranceDetailService.getInsuranceDetailSettleStatus(tInsuranceEkp.getDetailId(), tInsuranceEkp.getDefaultSettleId());
				if(settleType.equals(CommonConstants.ZERO_STRING)){
					ekpParam.setEstimateStatus(EkpConstants.HAVE);
				}else{
					ekpParam.setEstimateStatus(EkpConstants.NOTHING);
				}
				//预估新增重发
				if(CommonConstants.ONE_INT == pushType){
					//如果结算类型不一致，预估已推送，结算id不一致，结算信息不为空
					if(!settleTypeEquals  || !settleIdEquals || !estimatePush){
						if(!settleTypeEquals){
							ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_SETTLE_TYPE_IS_CHANGE);
						}
						if(!settleIdEquals){
							ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_SETTLE_ID_IS_CHANGE);
						}
						if(!estimatePush){
							ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_ESTIMATE_IS_PUSH);
						}
						ekpUpdate.set(TInsuranceEkp :: getResendFlag,CommonConstants.TWO_INT);
						update(ekpUpdate);
						if(!Common.isEmpty(settleVo)){
							settleUpdate.set(TInsuranceSettle :: getEstimatePushTime,LocalDateTime.now())
									.set(TInsuranceSettle ::getIsEstimatePush,CommonConstants.ONE_INT);
							tInsuranceSettleService.update(settleUpdate);
						}
						continue;
					} else{
						ekpParam.setInteractiveType(InsurancesConstants.NEW_SETTLE_BILL);
						ekpParam.setSettleType(InsurancesConstants.ESTIMATE_SETTLE_BILL);
						s = ekpInsuranceUtil.sendToEkp(ekpParam);
						if(StringUtils.isNotBlank(s)){
							settleUpdate.set(TInsuranceSettle :: getEstimatePushTime,LocalDateTime.now())
									.set(TInsuranceSettle ::getIsEstimatePush,CommonConstants.ONE_INT);
							tInsuranceSettleService.update(settleUpdate);
							ekpUpdate.set(TInsuranceEkp :: getResendFlag ,CommonConstants.ONE_INT)
									.set(TInsuranceEkp :: getPushTime ,LocalDateTime.now());
							update(ekpUpdate);
						}else{
							break;
						}
					}
				}
				//实缴新增重发
				if(CommonConstants.TWO_INT == pushType){
					//如果结算类型不一致，实缴已推送，结算id不一致，则不再推送
					if(!settleTypeEquals || !actualPush || !settleIdEquals){
						if(!settleTypeEquals){
							ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_SETTLE_TYPE_IS_CHANGE);
						}
						if(!settleIdEquals){
							ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_SETTLE_ID_IS_CHANGE);
						}
						if(!actualPush){
							ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_ACTUAL_IS_PUSH);
						}
						ekpUpdate.set(TInsuranceEkp :: getResendFlag,CommonConstants.TWO_INT);
						update(ekpUpdate);
						continue;
					}else{
						ekpParam.setInteractiveType(InsurancesConstants.NEW_SETTLE_BILL);
						ekpParam.setSettleType(InsurancesConstants.ACTUAL_SETTLE_BILL);
						s = ekpInsuranceUtil.sendToEkp(ekpParam);
						if(StringUtils.isNotBlank(s)){
							settleUpdate.set(TInsuranceSettle :: getActualPushTime,LocalDateTime.now())
									.set(TInsuranceSettle ::getIsActualPush,CommonConstants.ONE_INT);
							tInsuranceSettleService.update(settleUpdate);
							ekpUpdate.set(TInsuranceEkp :: getResendFlag ,CommonConstants.ONE_INT)
									.set(TInsuranceEkp :: getPushTime ,LocalDateTime.now());
							update(ekpUpdate);
						}else{
							break;
						}
					}
				}
				//实缴结算状态
				String actualStatus = null;
				//预缴结算状态
				String estimateStatus = null;
				if(!Common.isEmpty(settleVo) ){
					estimateStatus = settleVo.getEstimateStatus();
					actualStatus = settleVo.getActualStatus();
				}
				boolean eStatus = InsurancesConstants.SETTLE_ZERO.equals(estimateStatus);
				boolean aStatus = InsurancesConstants.SETTLE_ZERO.equals(actualStatus);
				//变更结算信息
				if(CommonConstants.THREE_INT == pushType){
					//如果结算类型不一致，结算类型不为空且已发送，结算id不一致
					if(!settleIdEquals || !eStatus || !aStatus){
						if(!settleIdEquals){
							ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_SETTLE_ID_IS_CHANGE);
						}
						if(!eStatus){
							ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_ESTIMATE_STATUS_ERROR);
						}
						if(!aStatus){
							ekpUpdate.set(TInsuranceEkp :: getNotResendMessage,InsurancesConstants.EKP_ACTUAL_STATUS_ERROR);
						}
						ekpUpdate.set(TInsuranceEkp :: getResendFlag,CommonConstants.TWO_INT);
						update(ekpUpdate);
						continue;
					}else{
						ekpParam.setInteractiveType(InsurancesConstants.UPDATE_SETTLE_BILL);
						s = ekpInsuranceUtil.sendToEkp(ekpParam);
						if(StringUtils.isNotBlank(s)){
							ekpUpdate.set(TInsuranceEkp :: getResendFlag ,CommonConstants.ONE_INT)
									.set(TInsuranceEkp :: getPushTime ,LocalDateTime.now());
							update(ekpUpdate);
						}else{
							break;
						}
					}
				}
				//推送作废信息
				if(CommonConstants.FOUR_INT == pushType){
					//如果结算类型不一致，结算类型不为空且已发送，结算id不一致
					if(eStatus && aStatus){
						ekpParam.setSettleType(InsurancesConstants.ESTIMATE_SETTLE_BILL);
						ekpParam.setInteractiveType(InsurancesConstants.ABOLISH_SETTLE_BILL);
						s = ekpInsuranceUtil.sendToEkp(ekpParam);
						if(StringUtils.isNotBlank(s)){
							ekpUpdate.set(TInsuranceEkp :: getResendFlag ,CommonConstants.ONE_INT)
									.set(TInsuranceEkp :: getPushTime ,LocalDateTime.now());
							update(ekpUpdate);
						}else{
							break;
						}
					}
					if(!eStatus || !aStatus){
						ekpParam.setInteractiveType(InsurancesConstants.CORRECT_SETTLE_BILL);
						//如果为合并结算,则推送预估红冲
						if(settleType.equals(CommonConstants.ZERO_STRING) && actualPush){
							BigDecimal estimatePremium = ekpParam.getEstimatePremium();
							ekpParam.setEstimatePremium(estimatePremium.negate());
							ekpParam.setSettleType(InsurancesConstants.ESTIMATE_SETTLE_BILL);
							s = ekpInsuranceUtil.sendToEkp(ekpParam);
							if(StringUtils.isNotBlank(s)){
								ekpUpdate.set(TInsuranceEkp :: getResendFlag ,CommonConstants.ONE_INT)
										.set(TInsuranceEkp :: getPushTime ,LocalDateTime.now());
								update(ekpUpdate);
							}else{
								break;
							}
						}
						//如果为合并结算,则推送实缴红冲
						if(!actualPush){
							ekpParam.setSettleType(InsurancesConstants.ACTUAL_SETTLE_BILL);
							BigDecimal actualPremium = ekpParam.getActualPremium();
							ekpParam.setActualPremium(actualPremium.negate());
							s = ekpInsuranceUtil.sendToEkp(ekpParam);
							if(StringUtils.isNotBlank(s)){
								ekpUpdate.set(TInsuranceEkp :: getResendFlag ,CommonConstants.ONE_INT)
										.set(TInsuranceEkp :: getPushTime ,LocalDateTime.now());
								update(ekpUpdate);
							}else{
								break;
							}
						}
					}
				}
				//推送预估红冲信息
				if(CommonConstants.FIVE_INT == pushType){
					ekpParam.setSettleType(InsurancesConstants.ESTIMATE_SETTLE_BILL);
					ekpParam.setInteractiveType(InsurancesConstants.CORRECT_SETTLE_BILL);
					s = ekpInsuranceUtil.sendToEkp(ekpParam);
					if(StringUtils.isNotBlank(s)){
						ekpUpdate.set(TInsuranceEkp :: getResendFlag ,CommonConstants.ONE_INT)
								.set(TInsuranceEkp :: getPushTime ,LocalDateTime.now());
						update(ekpUpdate);
					}else{
						break;
					}
				}
				//推送实缴红冲信息
				if(CommonConstants.SIX_INT == pushType){
					ekpParam.setSettleType(InsurancesConstants.ACTUAL_SETTLE_BILL);
					ekpParam.setInteractiveType(InsurancesConstants.CORRECT_SETTLE_BILL);
					s = ekpInsuranceUtil.sendToEkp(ekpParam);
					if(StringUtils.isNotBlank(s)){
						ekpUpdate.set(TInsuranceEkp :: getResendFlag ,CommonConstants.ONE_INT)
								.set(TInsuranceEkp :: getPushTime ,LocalDateTime.now());
						update(ekpUpdate);
					}else{
						break;
					}
				}
			}
			return R.ok("EKP重发成功");
		}else{
			return R.failed("无需要重新发送的EKP结算信息");
		}
	}
}
