package com.cyksj.service.vip.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.constant.Constant;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.mapper.*;
import com.cyksj.mapper.sys.SysConfigMapper;
import com.cyksj.mapper.vip.VipGoodsSkuMapper;
import com.cyksj.model.dto.VipDeductDto;
import com.cyksj.model.entity.*;
import com.cyksj.model.manage.views.GroupsRelationView;
import com.cyksj.model.response.VipUserPageResp;
import com.cyksj.model.views.RenewalView;
import com.cyksj.service.chatgpt.ChatGptAccountService;
import com.cyksj.service.claude.ClaudeService;
import com.cyksj.service.user.UserBindRelationService;
import com.cyksj.service.vip.VipFrontService;
import com.ejlchina.searcher.BeanSearcher;
import com.ejlchina.searcher.param.Operator;
import com.ejlchina.searcher.util.MapUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目名: yhlxj2
 * 文件名: VipFrontServiceImpl
 * 创建者: JavaZou
 * 创建时间:2025/5/15 16:00
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class VipFrontServiceImpl implements VipFrontService {
	private final SysConfigMapper sysConfigMapper;

	private final VipGoodsSkuMapper vipGoodsSkuMapper;

	private final UserBindRelationService userBindRelationService;

	private final BeanSearcher beanSearcher;

	private final GoodsDonSkuMapper skuMapper;

	private final ChatgptUserMapper chatgptUserMapper;

	private final OrderDonRenewRecordMapper orderDonRenewRecordMapper;

	private final ClaudeUserMapper claudeUserMapper;

	private final OrderDonMapper orderDonMapper;

	private final GoodsDonSkuMapper goodsDonSkuMapper;

	private final ChatGptAccountService chatGptAccountService;

	private final ClaudeService claudeService;

	private final LumaUserMapper lumaUserMapper;

	private final UpgradeOrderDonMapper upgradeOrderDonMapper;

	private final NanoUserQuotaMapper nanoUserQuotaMapper;

	private final MidjourneyUserMapper midjourneyUserMapper;

	@Override
	public void fillVipInfo(Long userId, VipUserPageResp vipUserPageResp) {
		SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.VIP_FEE_KEY).last("limit 1"));
		if (sysConfig != null && StrUtil.isNotBlank(sysConfig.getSysValue())) {
			vipUserPageResp.setVipFee(BigDecimal.valueOf(Integer.parseInt(sysConfig.getSysValue())));
		}
		if (userId == null) {
			return;
		}
		//可抵扣价格
		BigDecimal deductMoney = BigDecimal.ZERO;
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		List<Long> vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
		//可有抵扣车票
		DateTime now = DateTime.now();
		//会员规格
		Set<Long> goodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
				.in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet());
		Number count = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder().field(GroupsRelationView::getUserId, userIdList).op(Operator.InList).field(GroupsRelationView::getGoodsId, goodsIds).op(Operator.InList).field(GroupsRelationView::getIsMirror, Boolean.TRUE).field(GroupsRelationView::getExpiryTime, now).op(Operator.GreaterThan).build());
		//可抵扣车票
		if (count.intValue() > 0) {
			Integer months = vipUserPageResp.getMonths();
			//处理vip抵扣金额
			VipDeductDto vipDeductDto = commonHandleVipDeductMoney(userIdList, goodsIds, months);
			vipUserPageResp.setRelationUserViews(vipDeductDto.getRelationUserViews());
			vipUserPageResp.setExtendsDays(vipDeductDto.getExtendsDays());
			if (months != 12) {
				//取出最大可抵扣info
				vipDeductDto = commonHandleVipDeductMoney(userIdList, goodsIds, 12);
			}
			deductMoney = vipDeductDto.getDeductMoney();
		}
		vipUserPageResp.setDeductMoney(deductMoney);
	}

	/**
	 * 检查用户并获取订单抵扣金额
	 */
	@Override
	public VipDeductDto checkAndGetOrderDeductMoney(Long userId, Integer months) {
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(userId, null);
		List<Long> vipSkuIds = vipGoodsSkuMapper.selectList(null).stream().map(VipGoodsSku::getSkuId).collect(Collectors.toList());
		//会员规格
		Set<Long> goodsIds = goodsDonSkuMapper.selectList(Wrappers.lambdaQuery(GoodsDonSku.class)
				.in(GoodsDonSku::getId, vipSkuIds)).stream().map(GoodsDonSku::getGoodsId).collect(Collectors.toSet());
		Number count = beanSearcher.searchCount(GroupsRelationView.class, MapUtils.builder()
				.field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
				.field(GroupsRelationView::getGoodsId, goodsIds).op(Operator.InList)
				.field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
				.field(GroupsRelationView::getIsVip, false)
				.build());
		if (count.intValue() == 0) {
			throw BusinessRuntimeException.getInstance("暂无可抵扣AI车票");
		}
		VipDeductDto vipDeductDto = commonHandleVipDeductMoney(userIdList, goodsIds, months);
		return vipDeductDto;
	}


	private BigDecimal getVipMoney(Integer months) {
		SysConfig sysConfig = sysConfigMapper.selectOne(Wrappers.lambdaQuery(SysConfig.class).eq(SysConfig::getSysKey, Constant.VIP_FEE_KEY).last("limit 1"));
		if (sysConfig == null || StrUtil.isEmpty(sysConfig.getSysValue())) {
			throw BusinessRuntimeException.getInstance("系统异常");
		}
		BigDecimal vipFee = BigDecimal.valueOf(Long.valueOf(sysConfig.getSysValue()));
		return vipFee.multiply(BigDecimal.valueOf(months));
	}

	/**
	 * 统一处理vip抵扣金额
	 */
	public VipDeductDto commonHandleVipDeductMoney(List<Long> userIdList, Set<Long> goodsIds, Integer months) {
		VipDeductDto vipDeductDto = new VipDeductDto();
		DateTime now = DateTime.now();
		List<Long> deductRelationIds = new ArrayList<>();
		BigDecimal deductMoney = BigDecimal.ZERO;
		BigDecimal vipMoney = getVipMoney(months);
		List<GroupsRelationView> relations = beanSearcher.searchAll(GroupsRelationView.class, MapUtils.builder()
				.field(GroupsRelationView::getGoodsId, goodsIds).op(Operator.InList)
				.field(GroupsRelationView::getIsMirror, Boolean.TRUE)
				.field(GroupsRelationView::getUserId, userIdList).op(Operator.InList)
				.field(GroupsRelationView::getIsVip, false)
				.field(GroupsRelationView::getExpiryTime, DateTime.now()).op(Operator.GreaterThan)
				.field(GroupsRelationView::getAqType, 1)
				.orderBy(GroupsRelationView::getExpiryTime).desc()
				.build());
		Set<Long> deductGoodsIds = null;
		List<GroupsRelationView> deductRelations = null;
		for (GroupsRelationView relation : relations) {
			if (deductGoodsIds == null) {
				deductGoodsIds = new HashSet<>();
			}
			if (deductRelations == null) {
				deductRelations = new ArrayList<>();
			}
			Long goodsId = relation.getGoodsId();
			if (deductGoodsIds.contains(goodsId)) {
				continue;
			}
			if (goodsId == Constant.NANO_GOODS_ID) {
				NanoUserQuota nanoUserQuota = nanoUserQuotaMapper.selectOne(Wrappers.lambdaQuery(NanoUserQuota.class).in(NanoUserQuota::getUid, userIdList).orderByDesc(NanoUserQuota::getRemainingQuota).last("limit 1"));
				if (nanoUserQuota != null) {
					if (!ObjectUtil.equal(nanoUserQuota.getRelationId(), relation.getId())) {
						continue;
					}
				} else {
					//规格最高
					RenewalView renewalView = beanSearcher.searchFirst(RenewalView.class, MapUtils.builder()
							.field(RenewalView::getGoodsId, goodsId)
							.field(RenewalView::getUserId, userIdList).op(Operator.InList)
							.orderBy(RenewalView::getSkuNanoQuota).desc()
							.onlySelect(RenewalView::getRelationId)
							.build());
					if (renewalView != null && !ObjectUtil.equal(renewalView.getRelationId(), relation.getId())) {
						continue;
					}
				}
			}
			//订单是否存在
			Integer selectCount = orderDonMapper.selectCount(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relation.getId()).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
			if (selectCount == 0) {
				continue;
			}
			Long skuId = relation.getSkuId();
			deductGoodsIds.add(goodsId);
			Long relationId = relation.getId();
			Date relationExpiryTime = relation.getExpiryTime();
			//GPT
			if (goodsId == Constant.GPT_PLUS_GID) {
				ChatgptUser chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, relationId).last("limit 1"));
				if (chatgptUser == null) {
					chatGptAccountService.getUserInfo(relation.getUserId(), relation.getId());
					chatgptUser = chatgptUserMapper.selectOne(Wrappers.lambdaQuery(ChatgptUser.class).eq(ChatgptUser::getRelationId, relationId).last("limit 1"));
				}
				if (chatgptUser != null) {
					//获取抵扣金额
					deductMoney = deductMoney.add(getFinalDeductMoney(relationId, relation.getSkuId(), chatgptUser.getRenewSkuId(), chatgptUser.getRenewOrderId(), chatgptUser.getRenewExpiryTime(), relation.getStartTime(), relationExpiryTime, now, userIdList));
				}
			} else if (goodsId == Constant.CLAUDE_PRO_GID) {
				ClaudeUser claudeUser = claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class).eq(ClaudeUser::getRelationId, relationId).last("limit 1"));
				if (claudeUser == null) {
					claudeService.getUserInfo(relation.getUserId(), relation.getId());
					claudeUser = claudeUserMapper.selectOne(Wrappers.lambdaQuery(ClaudeUser.class).eq(ClaudeUser::getRelationId, relationId).last("limit 1"));
				}
				if (claudeUser != null) {
					//获取抵扣金额
					deductMoney = deductMoney.add(getFinalDeductMoney(relationId, relation.getSkuId(), claudeUser.getRenewSkuId(), claudeUser.getRenewOrderId(), claudeUser.getRenewExpiryTime(), relation.getStartTime(), relationExpiryTime, now, userIdList));
				}
			} else if (goodsId == Constant.LUMA_GOODS_ID || goodsId == Constant.NANO_GOODS_ID) {
				//luma、nano
				deductMoney = deductMoney.add(getGeneralRemainNumDeductMoney(relationId, goodsId, skuId, userIdList, relation.getStartTime()));
			} else if (goodsId == Constant.MIDJOURNEY_GOODS_ID) {
				//mj
				deductMoney = deductMoney.add(getMjRemainNumDeductMoney(relationId, skuId, userIdList, relation.getStartTime(), relation.getExpiryTime()));
			} else {
				//该车票抵扣金额
				deductMoney = deductMoney.add(getDeductMoneyFromTicket(relationId, userIdList, skuId, now, relation.getStartTime(), relationExpiryTime));
			}
			deductRelationIds.add(relationId);
			//可抵扣车票
			deductRelations.add(relation);
		}
		//实际可抵扣金额
		vipDeductDto.setActuallyDeDuctMoney(deductMoney);
		vipDeductDto.setDeductMoney(deductMoney);
		//超出可抵扣的金额 直接返回
		if (deductMoney.compareTo(vipMoney) >= 0) {
			BigDecimal overMoney = deductMoney.subtract(vipMoney);
			//超过抵扣金额可换延长会员多少天
			//每天单价
			BigDecimal daySingle = vipMoney.divide(BigDecimal.valueOf(months)).divide(BigDecimal.valueOf(30), 0, RoundingMode.DOWN);
			//超出部分可换取多少天 低于每天单价为0天
			BigDecimal extendsDays = overMoney.divide(daySingle, 0, RoundingMode.UP);
			vipDeductDto.setExtendsDays(extendsDays.intValue());
			vipDeductDto.setDeductMoney(vipMoney);
		}
		vipDeductDto.setDeductRelationIds(deductRelationIds);
		vipDeductDto.setRelationUserViews(deductRelations);
		return vipDeductDto;
	}

	/**
	 * 获取最终抵扣金额
	 */
	public BigDecimal getFinalDeductMoney(Long relationId, Long relationSkuId, Long renewSkuId, Long renewOrderId, Date renewExpiryTime, Date relationStartTime, Date relationExpiryTime, DateTime now, List<Long> userIdList) {
		BigDecimal deductMoney = BigDecimal.ZERO;
		//一个月当30天算单价 往上取整
		//续费规格
		if (renewSkuId != null && renewExpiryTime.compareTo(now) > 0) {
			OrderDon renewOrderDon = orderDonMapper.selectById(renewOrderId);
			BigDecimal orderMoney = renewOrderDon.getMoney().add(Optional.ofNullable(renewOrderDon.getBalance()).orElse(BigDecimal.ZERO));
			GoodsDonSku presentSku = skuMapper.selectById(renewSkuId);
			if (orderMoney.compareTo(BigDecimal.ZERO) == 0) {
				orderMoney = presentSku.getPrice();
			}
			Long betweenDay = DateUtil.betweenDay(now, renewExpiryTime, false) + 1;
			//当天购买的按规格原价抵扣
			BigDecimal renewDeductMoney;
			if (now.toDateStr().equals(DateUtil.format(renewOrderDon.getCreatedTime(), "yyyy-MM-dd"))) {
				renewDeductMoney = orderMoney;
				deductMoney = deductMoney.add(renewDeductMoney);
				if (presentSku.getDays() != null) {
					relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -presentSku.getDays());
				} else {
					relationExpiryTime = DateUtil.offsetMonth(relationExpiryTime, -presentSku.getMonths());
				}
			} else {
				//此次续费规格单价
				BigDecimal single = getPayOrderSingle(orderMoney, presentSku);
				//该车票抵扣金额
				renewDeductMoney = single.multiply(BigDecimal.valueOf(betweenDay));
				log.info("车票id:{}目前续费升级规格可抵扣的金额为：{}", relationId, renewDeductMoney);
				deductMoney = deductMoney.add(renewDeductMoney);
				relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -betweenDay.intValue());
			}
			//上一个续费升级规格
			List<OrderDon> orderDOns = orderDonRenewRecordMapper.getOtherRenewSkus(renewOrderId, relationId, userIdList);
			OrderDon presentRenewOrderDon = renewOrderDon;
			for (OrderDon thisRenewOrderDon : orderDOns) {
				Long skuId = thisRenewOrderDon.getSkuId();
				GoodsDonSku thisRenewSku = skuMapper.selectById(skuId);
				BigDecimal thisOrderMoney = thisRenewOrderDon.getMoney().add(Optional.ofNullable(thisRenewOrderDon.getBalance()).orElse(BigDecimal.ZERO));
				if (thisOrderMoney.compareTo(BigDecimal.ZERO) == 0) {
					thisOrderMoney = thisRenewSku.getPrice();
				}
				//当天购买的按规格原价抵扣
				BigDecimal thisRenewDeductMoney = BigDecimal.ZERO;
				if (now.toDateStr().equals(DateUtil.format(thisRenewOrderDon.getCreatedTime(), "yyyy-MM-dd"))) {
					thisRenewDeductMoney = thisOrderMoney;
					deductMoney = deductMoney.add(thisRenewDeductMoney);
					if (thisRenewSku.getDays() != null) {
						relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -thisRenewSku.getDays());
					} else {
						relationExpiryTime = DateUtil.offsetMonth(relationExpiryTime, -thisRenewSku.getMonths());
					}
				} else {
					//此次续费订单过期时间
					Date thisOrderExpiryTime;
					if (thisRenewSku.getDays() != null) {
						thisOrderExpiryTime = DateUtil.offsetDay(thisRenewOrderDon.getCreatedTime(), thisRenewSku.getDays());
					} else {
						thisOrderExpiryTime = DateUtil.offsetMonth(thisRenewOrderDon.getCreatedTime(), thisRenewSku.getMonths());
					}
					//续费同规格不处理
					if (!ObjectUtil.equal(thisRenewOrderDon.getSkuId(), presentRenewOrderDon.getSkuId())) {
						//先扣除已使用的天数
						//相差多少天
						Long thisRenewBetDay = DateUtil.betweenDay(thisRenewOrderDon.getCreatedTime(), presentRenewOrderDon.getCreatedTime(), false);
						//扣除已使用的
						thisOrderExpiryTime = DateUtil.offsetDay(thisOrderExpiryTime, -thisRenewBetDay.intValue());
					}
					//此订单过期时间
					if (thisOrderExpiryTime.compareTo(now) > 0) {
						//距离过期还剩多少天
						Long thisDeductBetweenDay = DateUtil.betweenDay(now, thisOrderExpiryTime, false) + 1;
						if (thisDeductBetweenDay != 0) {
							//此次续费规格单价
							BigDecimal single = getPayOrderSingle(thisOrderMoney, thisRenewSku);
							//该车票抵扣金额
							thisRenewDeductMoney = single.multiply(BigDecimal.valueOf(thisDeductBetweenDay));
							deductMoney = deductMoney.add(thisRenewDeductMoney);
						}
						//目前级别续费订单
						presentRenewOrderDon = thisRenewOrderDon;
						relationExpiryTime = DateUtil.offsetDay(relationExpiryTime, -thisDeductBetweenDay.intValue());
					}
				}
				log.info("车票id:{}目前次一级规格：{}可抵扣的金额为：{}", relationId, thisRenewSku.getSpecVal(), thisRenewDeductMoney);

			}
		}
		if (relationExpiryTime.after(now)) {
			//该车票抵扣金额
			BigDecimal deductMoneyFromTicket = getDeductMoneyFromTicket(relationId, userIdList, relationSkuId, now, relationStartTime, relationExpiryTime);
			deductMoney = deductMoney.add(deductMoneyFromTicket);
		}
		log.info("车票id:{}最终到期时间为：{}车票可返回 抵扣金额:{}", relationId, DateUtil.format(relationExpiryTime, "yyyy-MM-dd HH:mm:ss"), deductMoney);
		return deductMoney;
	}

	/**
	 * 获取车票可抵扣金额
	 */
	public BigDecimal getDeductMoneyFromTicket(Long relationId, List<Long> userIdList, Long skuId, DateTime now, Date relationStartTime, Date relationExpiryTime) {
		List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
				.eq(OrderDon::getRelationId, relationId)
				.in(OrderDon::getUserId, userIdList)
				.eq(OrderDon::getSkuId, skuId)
				.notIn(OrderDon::getStatus, Constant.noOrderAllStatus)
				.orderByDesc(OrderDon::getId));
		//部分退款
		if (orderDonList.isEmpty()) {
			orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class)
					.eq(OrderDon::getRelationId, relationId)
					.in(OrderDon::getUserId, userIdList)
					.eq(OrderDon::getSkuId, skuId)
					.notIn(OrderDon::getStatus, Constant.noOrderStatus)
					.orderByDesc(OrderDon::getId));
		}
		//原车票订单总实付金额
		BigDecimal totalOrderMoney = BigDecimal.ZERO;
		//原车票订单总天数
		Integer totalDays = 0;
		for (OrderDon orderDon : orderDonList) {
			GoodsDonSku sku = skuMapper.selectById(skuId);
			BigDecimal thisOrderMoney = orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)).subtract(Optional.ofNullable(orderDon.getRefundMoney()).orElse(BigDecimal.ZERO));
			if (thisOrderMoney.compareTo(BigDecimal.ZERO) == 0) {
				thisOrderMoney = sku.getPrice();
			}
			totalOrderMoney = totalOrderMoney.add(thisOrderMoney);
			//总时间
			if (sku.getDays() != null) {
				totalDays += sku.getDays();
			} else {
				totalDays += sku.getMonths() * 30;
			}
			//原订单数
			if (orderDonList.size() == 1) {
				//此次订单过期时间
				Date thisOrderExpiryTime;
				if (sku.getDays() != null) {
					thisOrderExpiryTime = DateUtil.offsetDay(orderDon.getCreatedTime(), sku.getDays());
				} else {
					thisOrderExpiryTime = DateUtil.offsetMonth(orderDon.getCreatedTime(), sku.getMonths());
				}
				//当天购买的按规格原价抵扣
				if (now.toDateStr().equals(DateUtil.format(relationStartTime, "yyyy-MM-dd")) && (DateUtil.betweenDay(thisOrderExpiryTime, relationExpiryTime, true) == 0)) {
					return thisOrderMoney;
				}
			}
		}
		Long thisDeductBetweenDay = DateUtil.betweenDay(now, relationExpiryTime, false) + 1;
		BigDecimal single = totalOrderMoney.divide(BigDecimal.valueOf(totalDays), 0, RoundingMode.HALF_UP);
		//该车票抵扣金额
		BigDecimal deductMoney = single.multiply(BigDecimal.valueOf(thisDeductBetweenDay));
		return deductMoney;
	}

	/**
	 * 获取订单单价
	 */
	public BigDecimal getPayOrderSingle(BigDecimal orderMoney, GoodsDonSku sku) {
		//此次续费规格单价
		BigDecimal single;
		//区分天/月
		if (sku.getDays() != null) {
			single = orderMoney.divide(BigDecimal.valueOf(sku.getDays()), 0, RoundingMode.HALF_UP);
		} else {
			single = orderMoney.divide(BigDecimal.valueOf(sku.getMonths()).multiply(BigDecimal.valueOf(30)), 0, RoundingMode.HALF_UP);
		}
		return single;
	}

	/**
	 * 获取普通剩余次数可抵扣金额
	 */
	private BigDecimal getGeneralRemainNumDeductMoney(Long relationId, Long goodsId, Long skuId, List<Long> userIdList, Date relationStartTime) {
		BigDecimal deductMoney = BigDecimal.ZERO;
		BigDecimal orderTotalMoney = BigDecimal.ZERO;
		//总次数
		Integer totalNum = 0;
		DateTime now = DateTime.now();

		List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relationId).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
		for (OrderDon orderDon : orderDonList) {
			GoodsDonSku sku = skuMapper.selectById(orderDon.getSkuId());
			Date orderCreatedTime = orderDon.getCreatedTime();
			Integer months = sku.getMonths();
			Integer days = sku.getDays();
			Date orderExpiryTime;
			if (days != null) {
				orderExpiryTime = DateUtil.offsetDay(orderCreatedTime, days);
			} else {
				orderExpiryTime = DateUtil.offsetMonth(orderCreatedTime, months);
			}
			//过期的订单不算入
			if (orderExpiryTime.before(now)) {
				continue;
			}
			if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
				orderTotalMoney = orderTotalMoney.add(orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)));
			} else {
				//兑换码订单使用规格价格
				orderTotalMoney = orderTotalMoney.add(sku.getPrice());
			}
			if (goodsId == Constant.LUMA_GOODS_ID) {
				totalNum += sku.getLumaNum();
			} else {
				totalNum += sku.getNanoQuota();
			}
		}
		//加量包订单
		List<UpgradeOrderDon> upgradeOrderDons = upgradeOrderDonMapper.selectList(Wrappers.lambdaQuery(UpgradeOrderDon.class).eq(UpgradeOrderDon::getRelationId, relationId).in(UpgradeOrderDon::getUserId, userIdList).notIn(UpgradeOrderDon::getStatus, Constant.noOrderAllStatus).gt(UpgradeOrderDon::getCreatedTime, relationStartTime));
		for (UpgradeOrderDon upgradeOrderDon : upgradeOrderDons) {
			orderTotalMoney = orderTotalMoney.add(upgradeOrderDon.getMoney().add(Optional.ofNullable(upgradeOrderDon.getBalance()).orElse(BigDecimal.ZERO)));
			totalNum = totalNum + upgradeOrderDon.getNum();
		}
		Integer remainNum = null;
		if (goodsId == Constant.LUMA_GOODS_ID) {
			LumaUser lumaUser = lumaUserMapper.selectOne(Wrappers.lambdaQuery(LumaUser.class).eq(LumaUser::getRelationId, relationId).last("limit 1"));
			if (lumaUser != null) {
				remainNum = lumaUser.getNum();
			}
		} else {
			NanoUserQuota nanoUserQuota = nanoUserQuotaMapper.selectOne(Wrappers.lambdaQuery(NanoUserQuota.class).eq(NanoUserQuota::getRelationId, relationId).last("limit 1"));
			if (nanoUserQuota != null) {
				remainNum = nanoUserQuota.getRemainingQuota();
			}
		}
		//若未使用
		if (remainNum == null) {
			deductMoney = deductMoney.add(orderTotalMoney);
		} else {
			BigDecimal remainMoney = totalNum == 0 ? BigDecimal.ZERO : BigDecimal.valueOf(remainNum).divide(BigDecimal.valueOf(totalNum), 2, RoundingMode.DOWN).multiply(orderTotalMoney);
			deductMoney = deductMoney.add(remainMoney);
		}
		return deductMoney;
	}

	/**
	 * 获取mj剩余次数可抵扣金额
	 */
	private BigDecimal getMjRemainNumDeductMoney(Long relationId, Long skuId, List<Long> userIdList, Date relationStartTime, Date relationExpiryTime) {
		BigDecimal deductMoney = BigDecimal.ZERO;
		BigDecimal orderTotalMoney = BigDecimal.ZERO;
		//总次数
		Integer totalNum = null;
		//原车票订单总天数
		Integer totalDays = 0;
		DateTime now = DateTime.now();

		List<OrderDon> orderDonList = orderDonMapper.selectList(Wrappers.lambdaQuery(OrderDon.class).eq(OrderDon::getRelationId, relationId).in(OrderDon::getUserId, userIdList).notIn(OrderDon::getStatus, Constant.noOrderAllStatus));
		for (OrderDon orderDon : orderDonList) {
			Date orderCreatedTime = orderDon.getCreatedTime();
			GoodsDonSku sku = skuMapper.selectById(orderDon.getSkuId());
			Integer months = sku.getMonths();
			Integer days = sku.getDays();
			//订单过期时间
			Date orderExpiryTime;
			if (days != null) {
				orderExpiryTime = DateUtil.offsetDay(orderCreatedTime, days);
			} else {
				orderExpiryTime = DateUtil.offsetMonth(orderCreatedTime, months);
			}
			//总时间
			totalDays += sku.getMonths() * 30;
			//过期的订单不算入
			if (orderExpiryTime.before(now)) {
				continue;
			}
			if (orderDon.getMoney().compareTo(BigDecimal.ZERO) > 0) {
				orderTotalMoney = orderTotalMoney.add(orderDon.getMoney().add(Optional.ofNullable(orderDon.getBalance()).orElse(BigDecimal.ZERO)));
			} else {
				//兑换码订单使用规格价格
				orderTotalMoney = orderTotalMoney.add(sku.getPrice());
			}
			if (totalNum == null) {
				totalNum = sku.getMjFastNum() + Optional.ofNullable(sku.getMjRelaxNum()).orElse(0);
			}
		}
		if (totalNum == null) {
			GoodsDonSku sku = skuMapper.selectById(skuId);
			totalNum = sku.getMjFastNum() + Optional.ofNullable(sku.getMjRelaxNum()).orElse(0);
		}
		Integer upgradeNum = 0;
		BigDecimal upgradeOrderMoney = BigDecimal.ZERO;
		//加量包订单
		List<UpgradeOrderDon> upgradeOrderDons = upgradeOrderDonMapper.selectList(Wrappers.lambdaQuery(UpgradeOrderDon.class).eq(UpgradeOrderDon::getRelationId, relationId).in(UpgradeOrderDon::getUserId, userIdList).notIn(UpgradeOrderDon::getStatus, Constant.noOrderAllStatus).gt(UpgradeOrderDon::getCreatedTime, relationStartTime));
		for (UpgradeOrderDon upgradeOrderDon : upgradeOrderDons) {
			upgradeNum += upgradeOrderDon.getNum();
			upgradeOrderMoney = upgradeOrderMoney.add(upgradeOrderDon.getMoney().add(Optional.ofNullable(upgradeOrderDon.getBalance()).orElse(BigDecimal.ZERO)));
		}
		MidjourneyUser midjourneyUser = midjourneyUserMapper.selectOne(Wrappers.lambdaQuery(MidjourneyUser.class).eq(MidjourneyUser::getRelationId, relationId).last("limit 1"));
		if (midjourneyUser == null) {
			deductMoney = deductMoney.add(orderTotalMoney).add(upgradeOrderMoney);
		} else {
			if (CollUtil.isNotEmpty(orderDonList)) {
				Integer remainFastNum = midjourneyUser.getMjFastNum();
				Integer remainRelaxNum = Optional.ofNullable(midjourneyUser.getMjRelaxNum()).orElse(0);
				Integer usedNum = totalNum - remainFastNum - remainRelaxNum;
				if (usedNum == 0 && now.toDateStr().equals(DateUtil.format(relationStartTime, "yyyy-MM-dd"))) {
					deductMoney = deductMoney.add(orderTotalMoney);
				} else {
					//每天单价
					BigDecimal single = orderTotalMoney.divide(BigDecimal.valueOf(totalDays), 0, RoundingMode.HALF_UP);
					BigDecimal consumeRate = BigDecimal.valueOf(usedNum).divide(BigDecimal.valueOf(totalNum), 2, RoundingMode.DOWN);
					//消耗的次数当月 值多少钱
					BigDecimal consumeMoney = consumeRate.multiply(single.multiply(BigDecimal.valueOf(30)));
					//该车票多长时间
					Long thisDeductBetweenDay = DateUtil.betweenDay(now, relationExpiryTime, false) + 1;
					//该车票抵扣金额
					BigDecimal orderRemainMoney = single.multiply(BigDecimal.valueOf(thisDeductBetweenDay));
					//最终可抵扣
					deductMoney = deductMoney.add(orderRemainMoney.subtract(consumeMoney));
				}
			}
			//加量包
			Integer remainUpgradeNum = midjourneyUser.getMjUpgradeNum();
			if (CollUtil.isNotEmpty(upgradeOrderDons)) {
				BigDecimal upgradeMoney = BigDecimal.valueOf(remainUpgradeNum).divide(BigDecimal.valueOf(upgradeNum), 2, RoundingMode.DOWN).multiply(upgradeOrderMoney);
				deductMoney = deductMoney.add(upgradeMoney);
			}
		}
		return deductMoney;
	}
}
