package com.kym.service.miniapp.impl;

import com.kym.common.utils.CommUtil;
import com.kym.entity.miniapp.Account;
import com.kym.entity.miniapp.ChargeOrder;
import com.kym.entity.miniapp.UserRechargeRights;
import com.kym.service.miniapp.DiscountService;
import com.kym.service.miniapp.UserRechargeRightsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;

/**
 * 无优惠策略
 *
 * @author skyline
 */
@Service
@Slf4j
public class NoDiscountHandle implements DiscountService {

    private final UserRechargeRightsService userRechargeRightsService;

    public NoDiscountHandle(UserRechargeRightsService userRechargeRightsService) {
        this.userRechargeRightsService = userRechargeRightsService;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void computeDiscount(ChargeOrder chargeOrder, Account account) {
        /*
         *权益只有用完才可以账户减去优惠金额，自然过期怎么处理？
         * 自然过期的充值权益更新状态为失效
         * 扣费时，查询该用户的充值权益，判断是否有未用完权益余额就过期的权益，如果有则继续扣减余额，直到扣减完余额再将Account中的优惠金额减去该权益的历史总优惠金额
         */
        int discountAmount = 0;
        int totalMoney = chargeOrder.getTotalMoney();
        var userRechargeRightsUpdates = new ArrayList<UserRechargeRights>();

        // 没有用完就过期失效的充值权益
        var userRechargeRightsList = userRechargeRightsService.lambdaQuery()
                // 筛选当前订单所在站点可以用的权益
                .eq(UserRechargeRights::getUserId, chargeOrder.getUserId())
                .eq(UserRechargeRights::getStatus, UserRechargeRights.STATUS_无效)
                .gt(UserRechargeRights::getRightsBalance, 0)
                .orderByAsc(UserRechargeRights::getEndTime)
                .list();

        if (CommUtil.isNotEmptyAndNull(userRechargeRightsList)) {
            for (UserRechargeRights userRechargeRights : userRechargeRightsList) {
                // 权益余额金额足够支付本次订单
                if (userRechargeRights.getRightsBalance() >= totalMoney) {
                    // 这里权益的余额还会二次扣减，按订单金额和权益余额的比例扣减
                    var discountAmountPart = (int) Math.ceil(userRechargeRights.getDiscountAmount() * totalMoney / (userRechargeRights.getRightsBalance() + 0.00));
                    discountAmount += discountAmountPart;
                    userRechargeRights.setDiscountAmount(userRechargeRights.getDiscountAmount() - discountAmountPart);
                    userRechargeRights.setRightsBalance(userRechargeRights.getRightsBalance() - totalMoney);
                    userRechargeRightsUpdates.add(userRechargeRights);
                    break;
                } else {
                    // 权益余额不足以支付本次订单，所以权益本次支付后失效
                    discountAmount += userRechargeRights.getDiscountAmount();
                    totalMoney -= userRechargeRights.getRightsBalance();
                    userRechargeRights.setDiscountAmount(0);
                    userRechargeRights.setRightsBalance(0);
                    userRechargeRightsUpdates.add(userRechargeRights);
                }

            }

            // 更新自然过期的权益余额数据
            userRechargeRightsService.updateBatchById(userRechargeRightsUpdates);
            // 更新账户优惠金额
            var accountDiscountAmount = account.getDiscountAmount() - discountAmount;
            if (accountDiscountAmount < 0) {
                accountDiscountAmount = 0;
                log.error("异常数据：账户优惠余额为负数，进行置零");
            }
            account.setDiscountAmount(accountDiscountAmount);
        }


        chargeOrder.setDiscountAmount(0);
        chargeOrder.setServiceMoneyDiscount(0);
    }


}

