package cn.com.ty.lift.ud.pay.service.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import cn.com.ty.lift.common.model.PushMessage;
import cn.com.ty.lift.common.model.PushUserInfo;
import cn.com.ty.lift.ud.chat.mapper.entity.ChatSessionEntity;
import cn.com.ty.lift.ud.chat.mapper.entity.LiftCaseEntity;
import cn.com.ty.lift.ud.chat.service.IChatSessionService;
import cn.com.ty.lift.ud.chat.service.ILiftCaseService;
import cn.com.ty.lift.ud.neety.task.RoomInfo;
import cn.com.ty.lift.ud.neety.task.UserInfo;
import cn.com.ty.lift.ud.operation.mapper.entity.CommissionSettingEntity;
import cn.com.ty.lift.ud.operation.mapper.entity.UserLevelRuleEntity;
import cn.com.ty.lift.ud.operation.mapper.entity.UserRebateRuleEntity;
import cn.com.ty.lift.ud.operation.mapper.entity.VipFeeSettingEntity;
import cn.com.ty.lift.ud.operation.service.ICommissionSettingService;
import cn.com.ty.lift.ud.operation.service.IUserLevelRuleService;
import cn.com.ty.lift.ud.operation.service.IUserRebateRuleService;
import cn.com.ty.lift.ud.operation.service.IVipFeeSettingService;
import cn.com.ty.lift.ud.pay.controller.req.PassbackParamsDTO;
import cn.com.ty.lift.ud.pay.service.WxpayService;
import cn.com.ty.lift.ud.payment.mapper.entity.TyBillEntity;
import cn.com.ty.lift.ud.payment.mapper.entity.UserBillEntity;
import cn.com.ty.lift.ud.payment.mapper.entity.UserRechargeDetailEntity;
import cn.com.ty.lift.ud.payment.service.ITyBillService;
import cn.com.ty.lift.ud.payment.service.IUserBillService;
import cn.com.ty.lift.ud.payment.service.IUserRechargeDetailService;
import cn.com.ty.lift.ud.question.mapper.QuestionBankMapper;
import cn.com.ty.lift.ud.question.mapper.entity.QuestionBankEntity;
import cn.com.ty.lift.ud.question.mapper.entity.QuestionOperateEntity;
import cn.com.ty.lift.ud.question.service.IQuestionOperateService;
import cn.com.ty.lift.ud.redis.RedisUtil;
import cn.com.ty.lift.ud.schoolVideo.mapper.entity.SchoolVideoEntity;
import cn.com.ty.lift.ud.schoolVideo.mapper.entity.SchoolVideoOperateEntity;
import cn.com.ty.lift.ud.schoolVideo.service.ISchoolVideoOperateService;
import cn.com.ty.lift.ud.schoolVideo.service.ISchoolVideoService;
import cn.com.ty.lift.ud.userAccount.mapper.entity.UserAccount;
import cn.com.ty.lift.ud.userAccount.service.IUserAccountService;
import cn.com.ty.lift.ud.userCoupon.mapper.UserCouponMapper;
import cn.com.ty.lift.ud.userInfo.mapper.UserInfoMapper;
import cn.com.ty.lift.ud.userInfo.mapper.entity.UserInfoEntity;
import cn.com.ty.lift.ud.userInfo.service.IUserInfoService;
import cn.com.ty.lift.ud.userRebate.mapper.entity.UserRebateEntity;
import cn.com.ty.lift.ud.userRebate.service.IUserRebateService;
import cn.com.ty.lift.ud.utils.QrCodeUtil;
import cn.com.ty.lift.ud.utils.UUIDUtil;
import cn.com.xwy.boot.web.dto.RestResponse;
import lombok.extern.slf4j.Slf4j;

@Service
@Transactional
@Slf4j
public class WxpayServiceImpl implements WxpayService {

    private final Logger logger = LoggerFactory.getLogger(AlipayServiceImpl.class);

    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;
    
    private @Autowired ILiftCaseService liftCaseService;

    private @Autowired IChatSessionService chatSessionService;

    private @Autowired IUserBillService userBillService;

    private @Autowired IUserRechargeDetailService userRechargeDetailService;

    private @Autowired IUserInfoService userInfo;

    private @Autowired QuestionBankMapper questionBankMapper;

    private @Autowired IQuestionOperateService iQuestionOperateService;

    private @Autowired ICommissionSettingService iCommissionSettingService;

    private @Autowired ITyBillService iTyBillService;

    private @Autowired ISchoolVideoOperateService schoolVideoOperateService;

    private @Autowired ISchoolVideoService schoolVideoService;

    private @Autowired IVipFeeSettingService vipFeeSettingService;

    private @Autowired IUserRebateService iUserRebateService;

    private @Autowired UserInfoMapper userInfoMapper;

    private @Autowired IUserLevelRuleService iUserLevelRuleService;

    @Autowired
    private IUserAccountService iUserAccountService;

    private @Autowired UserCouponMapper userCouponMapper;

    @Autowired
    private IUserRebateRuleService iUserRebateRuleService;

    private @Autowired RedisUtil redis;

    @Override
    public void wxCasePaymentComplete(String outTradeNo, String totalAmount, String tradeNo) {
        LocalDateTime date = LocalDateTime.now();
        // 完善订单状态
        QueryWrapper<LiftCaseEntity> orderWrapper = new QueryWrapper<LiftCaseEntity>();
        orderWrapper.eq("order_no", outTradeNo);
        // 诊单信息
        LiftCaseEntity caseEntity = liftCaseService.getOne(orderWrapper);
        final int orderId = caseEntity.getId().intValue();
        // 发起人ID
        Long userId = caseEntity.getCreateUserId();
        String sessionId = UUIDUtil.getUuidByTime9();
        // 支付完成生成聊天室
        ChatSessionEntity entity = new ChatSessionEntity();
        entity.setSessionid(sessionId);
        entity.setStatuz(1); // 状态1:正常0:屏蔽
        entity.setUserId(caseEntity.getCreateUserId().toString());
        entity.setCreateUserId(caseEntity.getCreateUserId().toString());
        entity.setDataTable(1);// '问诊出诊 1问诊2出诊',
        entity.setDataId(orderId);
        entity.setCreateTime(date);
        List<ChatSessionEntity> sessionList = new ArrayList<>();
        sessionList.add(entity);
        chatSessionService.saveBatch(sessionList);
        // 在redis中创建房间
        RoomInfo roomInfo = new RoomInfo();
        roomInfo.setSessionid(entity.getSessionid());
        roomInfo.setDataTable(entity.getDataTable());
        roomInfo.setLastTime(entity.getCreateTime().toInstant(ZoneOffset.of("+8")).toEpochMilli());
        UserInfo userInfo1 = new UserInfo();
        userInfo1.setUserId(entity.getUserId());
        List<UserInfo> userList = new ArrayList<>();
        userList.add(userInfo1);
        roomInfo.setUserLIst(userList);
        redis.setValue("ROOM:" + entity.getSessionid(), roomInfo);
        // 完善诊单状态
        /**
         * 问诊：0待付款(创建订单） =》 1已付款（待接单）=》 2已接单 =》 3专家确认完成 =》 4用户确认完成(待评价) =》 5待归档（已评价） =》 6已归档 =》 7申诉中 出诊：0待接单(创建订单) =》
         * 1已接单（待报价） =》 2待付款（已报价） =》 3已付款（已付款，专家待确认） =》 4专家确认完成 =》 5用户确认完成（待评价） =》 6已评价（已完成） =》 7申诉中'
         */
        caseEntity.setStatuz(1);
        caseEntity.setSessionId(sessionId);
        caseEntity.setUpdateTime(date);

        caseEntity.setOrderSerialNumber(tradeNo);
        liftCaseService.saveOrUpdate(caseEntity);

        if (caseEntity.getCouponId() != null) {
            // 使用卡券，修改状态
            userCouponMapper.updateOrderIdAndStatusByCouponIdAndUserId(caseEntity.getCouponId(), 2, caseEntity.getId());
        }

        if (caseEntity.getRedEnvelopeId() != null) {
            // 是否使用红包修改状态
            userCouponMapper.updateOrderIdAndStatusByCouponIdAndUserId(caseEntity.getRedEnvelopeId(), 2, caseEntity.getId());
        }

        log.info("--- 微信问诊记录平台流水开始 ---");
        // 记录平台流水
        TyBillEntity tyBill = new TyBillEntity();
        tyBill.setAmount(new BigDecimal(totalAmount).divide(new BigDecimal("100")));
        tyBill.setCreateTime(date);
        tyBill.setUserId(userId);
        tyBill.setFlowNum(tradeNo);
        // '交易类型 1：支出、2：收入
        tyBill.setType(2);
        tyBill.setBusinessType(4);
        tyBill.setDescr("问诊收入");
        BigDecimal balance = iTyBillService.getLatestBalance();
        tyBill.setBalance(balance.add(new BigDecimal(totalAmount).divide(new BigDecimal("100"))));
        iTyBillService.save(tyBill);
        log.info("--- 微信问诊记录平台流水结束 ---");

        log.info("开始记录发起问诊用户流水信息");
        // 发起问诊用户新增流水信息
        UserBillEntity billUpEntity = new UserBillEntity();
        billUpEntity.setCreateTime(date);
        billUpEntity.setUserId(userId);
        billUpEntity.setTargetUserId(caseEntity.getChargerId());
        billUpEntity.setAmount(new BigDecimal(totalAmount).divide(new BigDecimal("100")));
        billUpEntity.setType(1);
        billUpEntity.setBusinessType(4);
        billUpEntity.setDescr("微信支付问诊服务费");
        billUpEntity.setFlowNum(tradeNo);
        // 查询最近一次的余额
        BigDecimal latestBalance = userBillService.getLatestBalance(userId);
        billUpEntity.setBalance(latestBalance);
        userBillService.save(billUpEntity);
        log.info("记录流水完成");

        log.info("交易成功，处理业务代码完成");

    }

    @Override
    public void wxrechargePay(String outTradeNo, String totalAmount, String tradeNo, PassbackParamsDTO dto) {
        LocalDateTime date = LocalDateTime.now();

        QueryWrapper<UserInfoEntity> queryWrapper = new QueryWrapper<UserInfoEntity>();
        queryWrapper.eq("user_id", dto.getUserId());
        UserInfoEntity user = userInfo.getOne(queryWrapper);

        // 组装用户流水记录
        BigDecimal amount = new BigDecimal(totalAmount).divide(new BigDecimal("100"));
        UserBillEntity entity = new UserBillEntity();
        entity.setAmount(amount);
        entity.setCreateTime(date);
        entity.setUserId(user.getUserId());
        //充值，收款人为平台
        entity.setTargetUserId(1L);
        entity.setFlowNum(tradeNo);
        entity.setType(2);// '交易类型 1：支出、2：收入
        entity.setBusinessType(3); // '业务类型：如：2 打赏，3 充值，1 充值会员',
        entity.setDescr(dto.getMemo());
        entity.setBalance(user.getBalance().add(amount));
        userBillService.save(entity);

        log.info("--- 微信充值记录平台流水开始 ---");
        // 记录平台流水
        TyBillEntity tyBill = new TyBillEntity();
        tyBill.setAmount(amount);
        tyBill.setCreateTime(date);
        tyBill.setUserId(user.getUserId());
        tyBill.setFlowNum(tradeNo);
        tyBill.setType(2);// '交易类型 1：支出、2：收入
        tyBill.setBusinessType(3); // '业务类型：如：2 打赏，3 充值，1 充值会员',
        tyBill.setDescr("用户充值");
        BigDecimal latestBalance = iTyBillService.getLatestBalance();
        tyBill.setBalance(latestBalance.add(amount));
        iTyBillService.save(tyBill);
        log.info("--- 微信充值记录平台流水结束 ---");
        // 完善充值记录信息
        QueryWrapper<UserRechargeDetailEntity> rechargeWrapper = new QueryWrapper<UserRechargeDetailEntity>();
        rechargeWrapper.eq("order_sn", outTradeNo);
        UserRechargeDetailEntity rechargeDetail = userRechargeDetailService.getOne(rechargeWrapper);
        rechargeDetail.setPayTime(new Date());
        rechargeDetail.setPayStatus(2);// 订单支付状态、1待支付2、已支付、3支付失败、4已取消',
        rechargeDetail.setMemo(dto.getMemo());
        rechargeDetail.setProductPrice(amount);
        rechargeDetail.setThirdOrderSn(tradeNo);
        rechargeDetail.setUpdateTime(date);
        userRechargeDetailService.saveOrUpdate(rechargeDetail);

        // 更新用户余额
        userInfo.rechargePayBalance(dto.getUserId(), amount);

        log.info("交易成功，处理业务代码完成");

    }

    @Override
    public void wxCallPaymentComplete(String outTradeNo, String totalAmount, String tradeNo) {
        LocalDateTime date = LocalDateTime.now();

        // 完善订单状态
        QueryWrapper<LiftCaseEntity> orderWrapper = new QueryWrapper<LiftCaseEntity>();
        orderWrapper.eq("order_no", outTradeNo);
        // 诊单信息
        LiftCaseEntity caseEntity = liftCaseService.getOne(orderWrapper);

        final int orderId = caseEntity.getId().intValue();
        // 发起人ID
        Long userId = caseEntity.getCreateUserId();

//        String sessionId = UUIDUtil.getUuidByTime9();
//        // 支付完成生成聊天室
//        ChatSessionEntity entity = new ChatSessionEntity();
//        entity.setSessionid(sessionId);
//        entity.setStatuz(1); // 状态1:正常0:屏蔽
//        entity.setUserId(caseEntity.getCreateUserId().toString());
//        entity.setCreateUserId(caseEntity.getCreateUserId().toString());
//        entity.setDataTable(2);// '问诊出诊 1问诊2出诊',
//        entity.setDataId(orderId);
//        entity.setCreateTime(date);
//        List<ChatSessionEntity> sessionList = new ArrayList<>();
//        sessionList.add(entity);
//        chatSessionService.saveBatch(sessionList);
//        // 在redis中创建房间
//        RoomInfo roomInfo = new RoomInfo();
//        roomInfo.setSessionid(entity.getSessionid());
//        roomInfo.setDataTable(entity.getDataTable());
//        roomInfo.setLastTime(entity.getCreateTime().toInstant(ZoneOffset.of("+8")).toEpochMilli());
//        UserInfo userInfo1 = new UserInfo();
//        userInfo1.setUserId(entity.getUserId());
//        List<UserInfo> userList = new ArrayList<>();
//        userList.add(userInfo1);
//        roomInfo.setUserLIst(userList);
//        redis.setValue("ROOM:" + entity.getSessionid(), roomInfo);
        // 完善诊单状态
        /**
         * 问诊：0待付款(创建订单） =》 1已付款（待接单）=》 2已接单 =》 3专家确认完成 =》 4用户确认完成(待评价) =》 5待归档（已评价） =》 6已归档 =》 7申诉中 出诊：0待接单(创建订单)
         * =》1已接单（待报价） =》 2待付款（已报价） =》 3已付款（已付款，专家待确认） =》 4专家确认完成 =》 5用户确认完成（待评价） =》 6已评价（已完成） =》 7申诉中'
         */
        caseEntity.setStatuz(3);
//        caseEntity.setSessionId(sessionId);
        caseEntity.setUpdateTime(date);
        caseEntity.setOrderSerialNumber(tradeNo);
        liftCaseService.saveOrUpdate(caseEntity);

        if (caseEntity.getCouponId() != null) {
            // 使用卡券，修改状态
            userCouponMapper.updateOrderIdAndStatusByCouponIdAndUserId(caseEntity.getCouponId(), 2, caseEntity.getId());
        }

        if (caseEntity.getRedEnvelopeId() != null) {
            // 是否使用红包修改状态
            userCouponMapper.updateOrderIdAndStatusByCouponIdAndUserId(caseEntity.getRedEnvelopeId(), 2, caseEntity.getId());
        }

        log.info("--- 微信出诊记录平台流水开始 ---");
        // 记录平台流水
        TyBillEntity tyBill = new TyBillEntity();
        tyBill.setAmount(new BigDecimal(totalAmount).divide(new BigDecimal("100")));
        tyBill.setCreateTime(date);
        tyBill.setUserId(userId);
        tyBill.setFlowNum(tradeNo);
        // '交易类型 1：支出、2：收入
        tyBill.setType(2);
        tyBill.setBusinessType(4);
        tyBill.setDescr("出诊收入");
        BigDecimal balance = iTyBillService.getLatestBalance();
        tyBill.setBalance(balance.add(new BigDecimal(totalAmount).divide(new BigDecimal("100"))));
        iTyBillService.save(tyBill);
        log.info("--- 微信出诊记录平台流水结束 ---");
        log.info("开始记录发起出诊用户流水信息");

        // 发起问诊用户新增流水信息
        UserBillEntity billUpEntity = new UserBillEntity();
        billUpEntity.setCreateTime(date);
        billUpEntity.setUserId(userId);
        billUpEntity.setTargetUserId(caseEntity.getChargerId());
        billUpEntity.setAmount(new BigDecimal(totalAmount).divide(new BigDecimal("100")));
        billUpEntity.setType(1);
        billUpEntity.setBusinessType(4);
        billUpEntity.setDescr("微信支付出诊服务费");
        billUpEntity.setFlowNum(tradeNo);
        // 查询最近一次的余额
        BigDecimal latestBalance = userBillService.getLatestBalance(userId);
        billUpEntity.setBalance(latestBalance);
        userBillService.save(billUpEntity);

        PushUserInfo pushUserInfo =
            iUserAccountService.getPushUserInfoByUserId(caseEntity.getChargerId().toString());
        PushMessage pushMessage = PushMessage.orderChargeStatus("用戶已付款");
        pushMessage.sendTokenOnPlatform(jmsMessagingTemplate, pushUserInfo);
        log.info("交易成功，处理业务代码完成");

    }

    @Override
    public void wxQuestionPaymentComplete(Long questionId, Long userId, String tradeNo, String totalAmount,
        Integer payType) {
        // 赏金
        BigDecimal reward = new BigDecimal(totalAmount).divide(new BigDecimal("100"));
        BigDecimal amount = BigDecimal.ZERO;
        // 记录行为 question_operate
        QuestionOperateEntity operateEntity = new QuestionOperateEntity();
        operateEntity.setUserId(userId);
        operateEntity.setDataId(questionId);
        operateEntity.setType(4);
        operateEntity.setOrderSerialNumber(tradeNo);
        iQuestionOperateService.save(operateEntity);
        // 查询抽成设置中的题库抽成服务费
        RestResponse latestVersion = iCommissionSettingService.getLatestVersion();
        if (null != latestVersion) {
            CommissionSettingEntity data = (CommissionSettingEntity)latestVersion.getData();
            if (null != data) {
                BigDecimal questionCommission = data.getQuestionCommission();
                BigDecimal subtract = new BigDecimal("100").subtract(questionCommission);
                amount = reward.multiply(subtract).divide(new BigDecimal("100"));
            }
        }
        // 打赏数量加 1
        questionBankMapper.updateReward(questionId, BigDecimal.ZERO);
        // 新增专家账户流水
        QuestionBankEntity questionBankEntity = questionBankMapper.getById(questionId);
        // 新增专家流水记录
        UserBillEntity userBillEntity = new UserBillEntity();
        userBillEntity.setAmount(amount);
        userBillEntity.setUserId(questionBankEntity.getExpert());
        userBillEntity.setTargetUserId(userId);
        userBillEntity.setType(2);
        userBillEntity.setDescr("用户题库打赏");
        userBillEntity.setBusinessType(2);
        userBillEntity.setFlowNum(tradeNo);
        // 查询最近一次的余额
        BigDecimal latestBalance = userBillService.getLatestBalance(questionBankEntity.getExpert());
        if (null != latestBalance) {
            userBillEntity.setBalance(latestBalance.add(amount));
        }
        userBillService.save(userBillEntity);
        // 修改余额
        userInfoMapper.rechargePayBalance(questionBankEntity.getExpert(), amount);

        // 用户自己也要记录流水
        UserBillEntity billEntity = new UserBillEntity();
        billEntity.setAmount(reward);
        billEntity.setUserId(userId);
        billEntity.setTargetUserId(questionBankEntity.getExpert());
        billEntity.setType(1);
        billEntity.setBusinessType(2);
        billEntity.setFlowNum(tradeNo);
        // 查询最近一次的余额
        BigDecimal ba = userBillService.getLatestBalance(userId);
        if (payType == 1) {
            billEntity.setDescr("微信题库打赏");
            billEntity.setBalance(ba);
        } else {
            billEntity.setDescr("余额题库打赏");
            billEntity.setBalance(ba.subtract(reward));
            // 减少余额
            userInfoMapper.updateUserBalance(userId, reward);
        }

        userBillService.save(billEntity);

        if (payType == 1) {
            log.info("--- 微信题库打赏记录平台流水开始 ---");
            // 记录平台流水
            TyBillEntity tyBill = new TyBillEntity();
            tyBill.setAmount(reward);
            tyBill.setCreateTime(LocalDateTime.now());
            tyBill.setUserId(userId);
            tyBill.setFlowNum(tradeNo);
            tyBill.setType(2);// '交易类型 1：支出、2：收入
            tyBill.setBusinessType(2);
            tyBill.setDescr("用户题库打赏");
            BigDecimal balance = iTyBillService.getLatestBalance();
            tyBill.setBalance(balance.add(reward));
            iTyBillService.save(tyBill);
            log.info("--- 微信题库打赏记录平台流水结束 ---");
        }

    }

    @Override
    public void wxVideoPaymentComplete(Long videoId, Long userId, String tradeNo, String totalAmount, Integer payType) {
        // 赏金
        BigDecimal reward = new BigDecimal(totalAmount).divide(new BigDecimal("100"));
        BigDecimal amount = BigDecimal.ZERO;
        // 记录行为 question_operate
        SchoolVideoOperateEntity videoOperateEntity = new SchoolVideoOperateEntity();
        videoOperateEntity.setUserId(userId);
        videoOperateEntity.setDataId(videoId);
        videoOperateEntity.setType(4);
        videoOperateEntity.setThirdOrderSn(tradeNo);
        schoolVideoOperateService.save(videoOperateEntity);
        // 查询抽成设置中的题库抽成服务费
        RestResponse latestVersion = iCommissionSettingService.getLatestVersion();
        if (null != latestVersion) {
            CommissionSettingEntity data = (CommissionSettingEntity)latestVersion.getData();
            if (null != data) {
                BigDecimal videoCommission = data.getSchoolCommission();
                BigDecimal subtract = new BigDecimal("100").subtract(videoCommission);
                amount = reward.multiply(subtract).divide(new BigDecimal("100"));
            }
        }
        // 打赏数量加 1
        schoolVideoService.updateReward(videoId);
        // 新增专家账户流水
        SchoolVideoEntity videoEntity = schoolVideoService.getById(videoId);

        // 新增专家流水记录
        UserBillEntity userBillEntity = new UserBillEntity();
        userBillEntity.setAmount(amount);
        userBillEntity.setUserId(videoEntity.getUserId());
        userBillEntity.setTargetUserId(userId);
        userBillEntity.setType(2);
        userBillEntity.setDescr("用户视频打赏");
        userBillEntity.setBusinessType(2);
        userBillEntity.setFlowNum(tradeNo);
        // 查询最近一次的余额
        BigDecimal latestBalance = userBillService.getLatestBalance(videoEntity.getUserId());
        if (null != latestBalance) {
            userBillEntity.setBalance(latestBalance.add(amount));
        }
        userBillService.save(userBillEntity);
        // 修改余额
        userInfoMapper.rechargePayBalance(videoEntity.getUserId(), amount);

        // 用户自己也要记录流水
        UserBillEntity billEntity = new UserBillEntity();
        billEntity.setAmount(reward);
        billEntity.setUserId(userId);
        billEntity.setTargetUserId(videoEntity.getUserId());
        billEntity.setType(1);
        billEntity.setBusinessType(2);
        billEntity.setFlowNum(tradeNo);
        // 查询最近一次的余额
        BigDecimal ba = userBillService.getLatestBalance(userId);
        if (payType == 1) {
            billEntity.setDescr("微信视频打赏");
            billEntity.setBalance(ba);
        } else {
            billEntity.setDescr("余额视频打赏");
            billEntity.setBalance(ba.subtract(reward));
            // 减少余额
            userInfoMapper.updateUserBalance(userId, reward);
        }
        userBillService.save(billEntity);

        if (payType == 1) {
            log.info("--- 微信视频记录平台流水开始 ---");
            // 记录平台流水
            TyBillEntity tyBill = new TyBillEntity();
            tyBill.setAmount(reward);
            tyBill.setCreateTime(LocalDateTime.now());
            tyBill.setUserId(userId);
            tyBill.setFlowNum(tradeNo);
            tyBill.setType(2);// '交易类型 1：支出、2：收入
            tyBill.setBusinessType(2);
            tyBill.setDescr("用户视频打赏");
            BigDecimal balance = iTyBillService.getLatestBalance();
            tyBill.setBalance(balance.add(reward));
            iTyBillService.save(tyBill);
            log.info("--- 微信视频记录平台流水结束 ---");
        }

    }

    @Override
    public void wxToVIPPaymentComplete(Long vipFeeSetting, Long userId, String tradeNo, String totalAmount) {
        QueryWrapper<VipFeeSettingEntity> queryWrapper = new QueryWrapper<VipFeeSettingEntity>();
        queryWrapper.eq("id", vipFeeSetting);
        VipFeeSettingEntity entity = vipFeeSettingService.getOne(queryWrapper);
        UserInfoEntity userInfoEntity = userInfoMapper.getByUserId(userId);
        if (null == userInfoEntity) {
            log.error("当前用户不存在");
        } else {
            // 根据有效期查询会费
            BigDecimal fee = entity.getPrice();
            UserLevelRuleEntity userLevelRole = iUserLevelRuleService.getById(entity.getUserLevelId());
            if (null == userLevelRole) {
                log.error("当前会员角色等级不存在，请检查");
            }
            // 升级为会员，同时生成唯一的6位数字邀请码,同时修改会员相关的三个字段
            int code = (int)(((Math.random() * 9) + 1) * 100000);
            LocalDateTime vipStartTime = LocalDateTime.now();
            LocalDateTime vipEndTime = LocalDateTime.now();

            if (null != userInfoEntity.getVipStartTime()) {
                vipStartTime = userInfoEntity.getVipStartTime();
            }

            if (null != userInfoEntity.getVipEndTime() && userInfoEntity.getVipFlag() == 2) {
                vipEndTime = userInfoEntity.getVipEndTime().plusMonths(entity.getPeriod());
            } else {
                vipEndTime = vipEndTime.plusMonths(entity.getPeriod());
            }

            int month = monthDiff(LocalDateTime.now(), vipEndTime);
            // 获取VIP的等级
            int level = 1;
            if (month >= 1 && month < 3) {
                level = 1;
            } else if (month >= 3 && month < 12) {
                level = 3;
            } else if (month >= 12) {
                level = 12;
            }
            UserAccount userAccount = iUserAccountService.getOneById(userId);
            UserLevelRuleEntity expert = iUserLevelRuleService.getByCode("EXPERT");
            if (null != userAccount && userAccount.getExpertFlag() == 1) {
                // 专家,如果是专家，user_level_name 显示专家，user_level 保存会员角色ID
                userInfoMapper.toVip(userLevelRole.getId(), expert.getName(), code, vipStartTime, vipEndTime,
                    month > 0 ? month : 0, entity.getId(), userId);
            } else {
                // 不是专家
                userInfoMapper.toVip(userLevelRole.getId(), userLevelRole.getName(), code, vipStartTime, vipEndTime,
                    month > 0 ? month : 0, entity.getId(), userId);
            }

            // 如果是第一次成为会员，或者不是后台直接升级成会员的(是vip但是没有邀请码)
            // user_rebate 中修改此人的会费信息,并且给他的上级返利
            // 判断是否是第一次充值成为会员
            UserBillEntity userBill = userBillService.getByUserIdAndBusinessType(userId, 1);
            if (null == userBill && userInfoEntity.getRequestCode() == null) {
                // 第一次成为会员
                // 如果他有上级，上级的user_bill中加入流水信息，余额增加
                UserRebateEntity upUser = iUserRebateService.getUpUser(userId);
                if (null != upUser) {
                    // 查不到上级信息就不给他红利
                    UserInfoEntity userInfo = userInfoMapper.getByUserId(upUser.getUserId());
                    if (null != userInfo) {
                        // 如果他有上级，给上级返利，并保存记录
                        BigDecimal vipFee = saveUpUserRebateInfo(userInfo, upUser, fee, userId, tradeNo);
                        // 如果他有上上级，上上级的user_bill中加入流水信息，余额增加
                        UserRebateEntity upUpUser = iUserRebateService.getUpUser(userInfo.getUserId());
                        if (null != upUpUser) {
                            // 查不到上上级信息就不给他红利
                            UserInfoEntity upUserInfo = userInfoMapper.getByUserId(upUpUser.getUserId());
                            if (null != upUserInfo) {
                                // 给上上级返利，并保存记录
                                saveUpUpUserRebateInfo(upUserInfo, upUpUser, fee, userId, vipFee, userInfo.getUserId(),
                                    tradeNo);
                            }
                        }
                    }
                }
            }
            // ----------------- 充值的人自己也要加上流水信息,余额不变
            BigDecimal latestUserBalance = userBillService.getLatestBalance(userId);
            UserBillEntity uBillEntity = new UserBillEntity();
            uBillEntity.setCreateTime(LocalDateTime.now());
            uBillEntity.setUserId(userId);
            uBillEntity.setTargetUserId(1L);
            uBillEntity.setAmount(fee);
            uBillEntity.setType(1);
            uBillEntity.setDescr("充值vip会员");
            uBillEntity.setBusinessType(1);
            uBillEntity.setBalance(latestUserBalance);
            uBillEntity.setFlowNum(tradeNo);
            userBillService.save(uBillEntity);

            log.info("--- 充值vip会员记录平台流水开始 ---");
            // 记录平台流水
            TyBillEntity tyBill = new TyBillEntity();
            tyBill.setAmount(fee);
            tyBill.setCreateTime(LocalDateTime.now());
            tyBill.setUserId(userId);
            tyBill.setFlowNum(tradeNo);
            tyBill.setType(2);// '交易类型 1：支出、2：收入
            tyBill.setBusinessType(1);
            tyBill.setDescr("充值vip会员");
            BigDecimal balance = iTyBillService.getLatestBalance();
            tyBill.setBalance(balance.add(fee));
            iTyBillService.save(tyBill);
            log.info("--- 充值vip会员记录平台流水结束 ---");

            // 后台生成二维码，流化后上传到阿里云服务器
            try {
                String qrCodeurl = QrCodeUtil.getQrCode(userId, "/wode/vip");
                // todo 二维码
                UserInfoEntity userInfo = new UserInfoEntity();
                userInfo.setUserId(userId);
                userInfo.setQrCodeUrl(qrCodeurl);
                userInfoMapper.updateUserInfo(userInfo);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

    /**
     * 给上级返利，并保存记录
     *
     * @param userInfo
     * @param upUser
     * @param fee
     * @param userId
     */
    public BigDecimal saveUpUserRebateInfo(UserInfoEntity userInfo, UserRebateEntity upUser, BigDecimal fee,
        Long userId, String tradeNo) {
        // 询上级获取的返利金额,上级为专家时，userLevel 对应的不是 user_level_rule 里面的专家主键ID
        // 同时为专家和vip时，返利比率以专家为准
        UserRebateRuleEntity userRebateInfo = null;
        if (userInfo.getUserLevel() != null) {
            UserAccount userAccount = iUserAccountService.getOneById(upUser.getUserId());
            if (userAccount.getExpertFlag() == 1) {
                // 是专家
                UserLevelRuleEntity expert = iUserLevelRuleService.getByCode("EXPERT");
                userRebateInfo = iUserRebateRuleService.getRebateByUserLevel(expert.getId());
            } else {
                userRebateInfo = iUserRebateRuleService.getRebateByUserLevel(userInfo.getUserLevel());
            }
            BigDecimal rebate1 = userRebateInfo.getRebate1();
            // 有上级，上级获得返利
            UserBillEntity billUpEntity = new UserBillEntity();
            billUpEntity.setCreateTime(LocalDateTime.now());
            billUpEntity.setUserId(upUser.getUserId());
            //下级用户id
            billUpEntity.setTargetUserId(upUser.getLowerUserId());
            billUpEntity.setAmount(fee.multiply(rebate1));
            billUpEntity.setType(2);
            billUpEntity.setBusinessType(11);
            billUpEntity.setDescr("一级下线返利");
            billUpEntity.setFlowNum(tradeNo);
            // 查询最近一次的余额
            BigDecimal latestBalance = userBillService.getLatestBalance(upUser.getUserId());
            billUpEntity.setBalance(latestBalance.add(fee.multiply(rebate1)));
            userBillService.save(billUpEntity);
            // 上一级的 user_info 余额增加
            UserInfoEntity uiEntity = new UserInfoEntity();
            uiEntity.setUserId(userInfo.getUserId());
            uiEntity.setBalance(latestBalance.add(fee.multiply(rebate1)));
            log.info("上级现在的余额是" + latestBalance.add(fee.multiply(rebate1)));
            userInfoMapper.updateUserInfo(uiEntity);
            // user_rebate 中修改此人的上级返利信息
            UserRebateEntity ubEntity = new UserRebateEntity();
            ubEntity.setVipFee(fee.multiply(rebate1));
            ubEntity.setLowerUserId(userId);
            ubEntity.setUserId(upUser.getUserId());
            iUserRebateService.updateByTwoId(ubEntity);
            return fee.multiply(rebate1);
        }

        return new BigDecimal("0");

    }

    /**
     * 给上上级返利，并保存记录
     *
     * @param upUserInfo
     *            上上级用户信息
     * @param upUpUser
     *            上上级用户
     * @param fee
     * @param userId
     * @param upUserId
     *            上级ID
     */
    public void saveUpUpUserRebateInfo(UserInfoEntity upUserInfo, UserRebateEntity upUpUser, BigDecimal fee,
        Long userId, BigDecimal vipFee, Long upUserId, String tradeNo) {
        // 询上级获取的返利金额,上级为专家时，userLevel 对应的不是 user_level_rule 里面的专家主键ID
        // 同时为专家和vip时，返利比率以专家为准
        UserRebateRuleEntity userRebateInfo = null;
        if (upUserInfo.getUserLevel() != null) {
            UserAccount userAccount = iUserAccountService.getOneById(upUpUser.getUserId());
            if (userAccount.getExpertFlag() == 1) {
                // 是专家
                UserLevelRuleEntity expert = iUserLevelRuleService.getByCode("EXPERT");
                userRebateInfo = iUserRebateRuleService.getRebateByUserLevel(expert.getId());
            } else {
                userRebateInfo = iUserRebateRuleService.getRebateByUserLevel(upUserInfo.getUserLevel());
            }
            BigDecimal rebate2 = userRebateInfo.getRebate2();
            // 有上上级，上级获得返利
            UserBillEntity billUpEntity = new UserBillEntity();
            billUpEntity.setCreateTime(LocalDateTime.now());
            billUpEntity.setUserId(upUpUser.getUserId());
            //下级用户
            billUpEntity.setTargetUserId(upUpUser.getLowerUserId());
            billUpEntity.setAmount(fee.multiply(rebate2));
            billUpEntity.setType(2);
            billUpEntity.setBusinessType(11);
            billUpEntity.setDescr("二级下线返利");
            billUpEntity.setFlowNum(tradeNo);
            // 查询最近一次的余额
            BigDecimal latestBalance = userBillService.getLatestBalance(upUpUser.getUserId());
            billUpEntity.setBalance(latestBalance.add(fee.multiply(rebate2)));
            userBillService.save(billUpEntity);
            // 上上级的 user_info 余额增加
            UserInfoEntity uiEntity = new UserInfoEntity();
            uiEntity.setUserId(upUserInfo.getUserId());
            uiEntity.setBalance(latestBalance.add(fee.multiply(rebate2)));
            userInfoMapper.updateUserInfo(uiEntity);
            log.info("上上级现在的余额是" + latestBalance.add(fee.multiply(rebate2)));
            // user_rebate 中修改此人的上上级返利信息
            UserRebateEntity ubEntity = new UserRebateEntity();
            ubEntity.setVipFeeUp(fee.multiply(rebate2));
            ubEntity.setLowerUserId(userId);
            ubEntity.setUserId(upUserId);
            ubEntity.setVipFee(vipFee);
            iUserRebateService.updateByTwoId(ubEntity);
            // todo 给上上级发送消息
        }

    }

    /**
     * 获取两个时间点的月份差
     *
     * @param dt1
     *            第一个时间点,小的那个时间
     * @param dt2
     *            第二个时间点，大的那个时间
     * @return int，即需求的月数差
     */
    public static int monthDiff(LocalDateTime dt1, LocalDateTime dt2) {
        // 获取第一个时间点的月份
        int month1 = dt1.getMonthValue();
        // 获取第一个时间点的年份
        int year1 = dt1.getYear();
        // 获取第一个时间点的月份
        int month2 = dt2.getMonthValue();
        // 获取第一个时间点的年份
        int year2 = dt2.getYear();
        // 返回两个时间点的月数差
        return (year2 - year1) * 12 + (month2 - month1);
    }

}
