package com.cyksj.service.mange.vip.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cyksj.common.exception.BusinessRuntimeException;
import com.cyksj.mapper.GoodsDonSkuMapper;
import com.cyksj.mapper.GroupsMapper;
import com.cyksj.mapper.GroupsRelationMapper;
import com.cyksj.mapper.vip.RefundVipOrderDonMapper;
import com.cyksj.mapper.vip.VipOrderDonMapper;
import com.cyksj.mapper.vip.VipUserMapper;
import com.cyksj.model.entity.*;
import com.cyksj.model.request.OrderRefundReq;
import com.cyksj.service.mange.MirrorUserCleatService;
import com.cyksj.service.mange.vip.CmsVipOrderService;
import com.cyksj.service.order.OrderRefundService;
import com.cyksj.service.relation.GroupRelationClearService;
import com.cyksj.service.user.UserBenefitsService;
import com.cyksj.service.user.UserBindRelationService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 项目名: yhlxj2
 * 文件名: CmsVipOrderServiceImpl
 * 创建者: JavaZou
 * 创建时间:2025/5/13 16:40
 */
@Service
@RequiredArgsConstructor
public class CmsVipOrderServiceImpl implements CmsVipOrderService {
	private final RefundVipOrderDonMapper refundVipOrderDonMapper;

	private final OrderRefundService orderRefundService;

	private final VipOrderDonMapper vipOrderDonMapper;

	private final VipUserMapper vipUserMapper;

	private final GroupsRelationMapper relationMapper;

	private final GoodsDonSkuMapper skuMapper;

	private final GroupsMapper groupsMapper;

	private final MirrorUserCleatService mirrorUserCleatService;

	private final GroupRelationClearService groupRelationClearService;

	private final UserBenefitsService userBenefitsService;

	private final UserBindRelationService userBindRelationService;

	@Override
	public void refundOrders(OrderRefundReq refundReq) throws Exception {
		VipOrderDon orderDon = vipOrderDonMapper.selectById(refundReq.getOrderId());
		if (StrUtil.isEmpty(refundReq.getRefundType())) {
			refundReq.setRefundType("money");
		}
		String refundType = refundReq.getRefundType();
		//校验订单是否符合退款
		checkOrderRefund(orderDon, refundReq);
		//调用第三方接口退款
		String outNo = StrUtil.EMPTY;
		if (refundReq.getRefundMoney() != null && refundReq.getRefundMoney().compareTo(BigDecimal.ZERO) > 0) {
			outNo = orderRefundService.vipCenterRefund(refundReq, orderDon);
		}
		orderDon.setRefundDesc(refundReq.getRefundDesc());
		//记录退款信息
		commonRefund(orderDon, refundReq.getRefundMoney(), refundReq.getOperator(), outNo, refundType, refundReq.getIsOnly(), refundReq.getRefundBalance(), refundReq.getChatImg(), refundReq.getDeductBalance());
		//修改订单状态
		orderDon.setStatus(VipOrderDon.Status.refund);
		vipOrderDonMapper.updateById(orderDon);
	}

	private void commonRefund(VipOrderDon orderDon, BigDecimal refundMoney, String operator, String outNo, String refundType, Boolean isOnly, BigDecimal refundBalance, String chatImg, BigDecimal deductBalance) {
		//记录退款
		recordRefundOrder(orderDon, outNo, refundMoney, operator, chatImg, refundType);
		//退等比例
		if (isOnly != null && isOnly) {
			userBenefitsService.addUserBalance(orderDon.getUserId(), refundBalance, UserBalanceSourceRecord.Source.vip_refund, null, orderDon.getId(), orderDon.getPayTitle() + UserBalanceSourceRecord.Source.vip_refund.getDesc(), true);
			BigDecimal orderDonRefundBalance = Optional.ofNullable(orderDon.getRefundBalance()).orElse(BigDecimal.ZERO);
			orderDon.setRefundBalance(orderDonRefundBalance.add(refundBalance));
		}
		//若存在余额支付，退还余额
		if (isOnly == null && orderDon.getBalance().compareTo(BigDecimal.ZERO) > 0) {
			BigDecimal addBalance = orderDon.getBalance();
			//需额外扣除余额
			if (deductBalance != null && deductBalance.compareTo(BigDecimal.ZERO) > 0) {
				addBalance = addBalance.subtract(deductBalance);
			}
			userBenefitsService.addUserBalance(orderDon.getUserId(), addBalance, UserBalanceSourceRecord.Source.vip_refund, null, orderDon.getId(), orderDon.getPayTitle() + UserBalanceSourceRecord.Source.vip_refund.getDesc(), true);
		}
		//扣除会员时长
		List<Long> userIdList = userBindRelationService.getRelationUserIdList(orderDon.getUserId(), null);
		VipUser vipUser = vipUserMapper.selectOne(Wrappers.lambdaQuery(VipUser.class)
				.in(VipUser::getUserId, userIdList)
				.last("limit 1"));
		if (vipUser != null) {
			Date expiryTime = vipUser.getExpiryTime();
			DateTime subExpiryTime = DateUtil.offsetMonth(expiryTime, -1);
			vipUser.setExpiryTime(subExpiryTime);
			//若会员过期清除镜像user
			clearVipMirrorUser(vipUser.getUserId(), subExpiryTime);
			vipUserMapper.updateById(vipUser);
		}
	}

	private void recordRefundOrder(VipOrderDon orderDon, String outRefundNo, BigDecimal refundMoney, String operator, String chatImg, String refundType) {
		RefundVipOrderDon refund = new RefundVipOrderDon();
		refund.setOrderId(orderDon.getId());
		refund.setOutRefundNo(outRefundNo);
		refund.setTotalFee(orderDon.getMoney());
		refund.setRefundDesc(orderDon.getRefundDesc());
		//退款金额
		refund.setRefundFee(refundMoney);
		refund.setUserId(orderDon.getUserId());
		refund.setGoodsTitle(orderDon.getPayTitle());
		refund.setRefundMethod(orderDon.getType().name());
		refund.setOperator(operator);
		refund.setChatImg(chatImg);
		//退款方式
		if (StrUtil.isNotBlank(refundType) && refundType.equals(VipOrderDon.Type.BALANCE.getType())) {
			refund.setRefundMethod(refundType);
			refund.setRefundFee(orderDon.getRefundBalance());
		}
		refundVipOrderDonMapper.insert(refund);
	}

	private void checkOrderRefund(VipOrderDon orderDon, OrderRefundReq refundReq) {
		if (orderDon.getStatus()!= VipOrderDon.Status.complete) {
			throw BusinessRuntimeException.getInstance("订单状态异常");
		}
		Long userId = orderDon.getUserId();
		//会员是否已过期
		VipUser vipUser = vipUserMapper.selectOne(Wrappers.lambdaQuery(VipUser.class)
				.eq(VipUser::getUserId, userId)
				.gt(VipUser::getExpiryTime, DateTime.now())
				.last("limit 1"));
		if (vipUser == null) {
			throw BusinessRuntimeException.getInstance("用户会员已过期，无法退款");
		}
	}

	/**
	 * 整理会员车票时长
	 * 过期清除镜像user
	 */
	private void clearVipMirrorUser(Long userId, Date expiryTimeAfterSub) {
		Boolean overdue = expiryTimeAfterSub.before(DateTime.now());
		List<GroupsRelation> groupsRelations = relationMapper.selectList(Wrappers.lambdaQuery(GroupsRelation.class)
				.eq(GroupsRelation::getUserId, userId)
				.eq(GroupsRelation::getIsVip, Boolean.TRUE));
		groupsRelations.forEach(ticket -> {
			if (overdue) {
				//清除车票
				groupRelationClearService.clearTicket(ticket, UserTicketClearedRecord.Source.vip_refund);
				return;
			}
			ticket.setExpiryTime(expiryTimeAfterSub);
			relationMapper.updateById(ticket);
		});
	}
}
