package com.sqx.modules.member.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.Constant;
import com.sqx.modules.app.bo.UpdateMoneyBO;
import com.sqx.modules.app.entity.UserEntity;
import com.sqx.modules.app.service.UserMoneyService;
import com.sqx.modules.app.service.UserService;
import com.sqx.modules.common.entity.CommonInfo;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.coupon.service.TbCouponUserService;
import com.sqx.modules.goods.entity.GoodsShop;
import com.sqx.modules.goods.service.GoodsShopService;
import com.sqx.modules.member.VipPromotionUtil;
import com.sqx.modules.member.dto.VipPromoRecordDTO;
import com.sqx.modules.member.entity.VipPromoCode;
import com.sqx.modules.member.service.VipPromoCodeService;
import com.sqx.modules.member.service.VipPromoRecordService;
import com.sqx.modules.member.service.VipService;
import com.sqx.modules.member.vo.VipReduceVO;
import com.sqx.modules.order.entity.TbOrder;
import com.sqx.modules.order.service.AppOrderService;
import com.sqx.modules.pay.dto.GetPayParamDTO;
import com.sqx.modules.pay.entity.PayDetails;
import com.sqx.modules.pay.enums.PayChannelEnum;
import com.sqx.modules.pay.enums.PaySceneEnum;
import com.sqx.modules.pay.service.NewPayService;
import com.sqx.modules.pay.vo.PayTransactionsVO;
import com.sqx.modules.utils.VipExpirationUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * vip服务
 * @author codingliang
 * @date 2025-11-12
 */
@Service
@RequiredArgsConstructor
public class VipServiceImpl implements VipService {

    private final NewPayService newPayService;
    private final UserService userService;
    private final CommonInfoService commonInfoService;
    private final TbCouponUserService tbCouponUserService;
    private final VipPromoCodeService vipPromoCodeService;
    private final VipPromoRecordService vipPromoRecordService;
    private final UserMoneyService userMoneyService;
    private final GoodsShopService goodsShopService;
    private final AppOrderService orderService;
    private final AppOrderService appOrderService;


    @Override
    public PayTransactionsVO getPayParam(Long userId, String promoCode) {
        UserEntity user = userService.getById(userId);
        beforePay(user, promoCode);

        // 查询会员价格
        CommonInfo one = commonInfoService.findOne(313);
        BigDecimal vipPrice = BigDecimal.valueOf(Double.valueOf(one.getValue()));

        // 构建获取支付参数dto
        GetPayParamDTO dto = GetPayParamDTO.builder()
                .orderNo(IdWorker.getTimeId())
                .orderDesc("墨轩商场会员")
                .amount(vipPrice.setScale(2, RoundingMode.HALF_UP))
                .userId(userId)
                .userThirdId(user.getOpenId())
                .payChannel(PayChannelEnum.WECHAT_JS_API)
                .paySceneEnum(PaySceneEnum.VIP_PAY)
                .extra(promoCode)
                .build();

        return newPayService.getWechatTransactionsParamVO(dto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void paySuccess(PayDetails payDetails) {
        Long userId = payDetails.getUserId();
        UserEntity user = userService.getById(userId);
        VipPromoRecordDTO recordDTO = VipPromoRecordDTO.builder()
                .userId(userId)
                .userName(user.getNickName())
                .userPhone(user.getPhone())
                .payType("1")
                .promoCode(payDetails.getExtra())
                .payAmount(payDetails.getMoney())
                .payRelId(payDetails.getOrderId())
                .build();
        vipPromoRecordService.add(recordDTO);

        // 更新用户为会员
        afterPaySuccess(payDetails.getUserId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void balancePay(Long userId, String promoCode) {
        UserEntity user = userService.getById(userId);
        beforePay(user, promoCode);

        // 会员价格
        CommonInfo vipPrice = commonInfoService.findOne(313);

        // 扣减用户余额
        UpdateMoneyBO updateMoneyBO = UpdateMoneyBO.builder()
                .type(2)
                .classify(3)
                .userId(userId)
                .amount(new BigDecimal(vipPrice.getValue()))
                .title("购买会员")
                .build();
        userMoneyService.updateUserMoney(updateMoneyBO);

        // 新增会员充值记录
        VipPromoRecordDTO recordDTO = VipPromoRecordDTO.builder()
                .userId(userId)
                .userName(user.getNickName())
                .userPhone(user.getPhone())
                .payType("2")
                .promoCode(promoCode)
                .payAmount(Double.valueOf(vipPrice.getValue()))
                .payRelId("")
                .build();
        vipPromoRecordService.add(recordDTO);

        // 更新用户为会员
        afterPaySuccess(userId);
    }

    private void beforePay(UserEntity user, String promoCode) {
        if(ObjectUtil.isNotNull(user.getIsVip()) && user.getIsVip() == 1 && VipExpirationUtil.isVipValid(user.getVipExpirationTime())) {
            throw new SqxException("已经是会员，不能重复购买！");
        }

        VipPromoCode vipPromoCode = vipPromoCodeService.getByCode(promoCode);
        if (ObjectUtil.isNull(vipPromoCode)) {
            throw new SqxException("无效的推广码！");
        }
    }

    @Override
    public VipReduceVO getVipReduceInfo(Long userId, Long orderId) {
        TbOrder order = orderService.getByIdWithGoods(orderId);
        UserEntity user = userService.getById(userId);
        GoodsShop goodsShop = goodsShopService.getById(order.getShopId());

        VipPromotionUtil vipPromotionUtil = new VipPromotionUtil(appOrderService, commonInfoService);
        return vipPromotionUtil.getCanReduce(order, goodsShop, user);
    }

    private void afterPaySuccess(Long userId) {
        // 会员期限（天）
        CommonInfo vipExpirationDays = commonInfoService.findOne(314);
        Integer vipExpirationDaysValue = Integer.valueOf(vipExpirationDays.getValue());

        // 会员赠送红包数量
        CommonInfo vipRedPacketNum = commonInfoService.findOne(315);

        // 会员赠送红包金额
        CommonInfo vipRedPacketMoney = commonInfoService.findOne(316);

        // 会员失效时间
        String expirationTime = VipExpirationUtil.getFutureTimeWithDays(vipExpirationDaysValue);

        // 更新用户为会员
        userService.updateUserToVip(userId, expirationTime);

        // 新增会员专属优惠券
        for(int i = 0; i<Integer.valueOf(vipRedPacketNum.getValue()); i++){
            tbCouponUserService.addAfterVipBuySuccess(userId, new BigDecimal(vipRedPacketMoney.getValue()), vipExpirationDays.getValue(), expirationTime);
        }
    }
}
