package com.github.wxiaoqi.security.admin.biz;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.wxiaoqi.security.admin.constant.WithDrawStatusEnum;
import com.github.wxiaoqi.security.admin.dto.WalletCathSumDto;
import com.github.wxiaoqi.security.admin.dto.WalletFindDTO;
import com.github.wxiaoqi.security.admin.dto.WalletListDTO;
import com.github.wxiaoqi.security.admin.entity.*;
import com.github.wxiaoqi.security.admin.mapper.MyWalletMapper;
import com.github.wxiaoqi.security.admin.rpc.service.AppPermissionService;
import com.github.wxiaoqi.security.admin.vo.*;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.config.rabbit.RabbitConstant;
import com.github.wxiaoqi.security.common.constant.UserConstant;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.ClientUtil;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.github.wxiaoqi.security.common.vo.PageDataVO;
import com.xxfc.platform.app.entity.vo.WithDrawRuleVo;
import com.xxfc.platform.app.feign.ConfigFeign;
import com.xxfc.platform.universal.vo.FundPayVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author libin
 * @version 1.0
 * @description
 * @data 2019/7/12 9:18
 */
@Transactional
@Service
@Slf4j
public class MyWalletBiz extends BaseBiz<MyWalletMapper, MyWallet> implements InitializingBean {

    @Autowired
    private MyWalletDetailBiz myWalletDetailBiz;

    @Autowired
    private MyWalletCathBiz myWalletCathBiz;

    @Autowired
    private AppPermissionService permissionService;

    @Autowired
    private RedisTemplate userRedisTemplate;

    @Autowired
    private ConfigFeign configFeign;

    @Autowired
    private AppUserDetailBiz appUserDetailBiz;

    @Autowired
    private AppUserLoginBiz appUserLoginBiz;

    @Autowired
    private AppUserAlipayBiz appUserAlipayBiz;

    @Autowired
    private AppUserPositionBiz appUserPositionBiz;

    @Autowired
    RabbitTemplate rabbitTemplate;

    private Snowflake snowflake;

    private DateTimeFormatter dateTimeFormatter;

    private static final Integer WITHDRAW_ONLINE_WAY = 1;
    private static final Integer WITHDRAW_OFFLINE_WAY = 2;

    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12);


    public AppletWalletVo findMyWallet(Integer userId) {

        AppletWalletVo appletWalletVo = new AppletWalletVo();

        Example example = new Example(MyWallet.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        List<MyWallet> wallets = mapper.selectByExample(example);

        MyWallet myWallet = wallets.get(0);
        appletWalletVo.setBalance(myWallet.getBalance() == null ? new BigDecimal(0) : myWallet.getBalance());
        appletWalletVo.setTodayAmount(myWallet.getTodayAmount() == null ? new BigDecimal(0) : myWallet.getTodayAmount());
        appletWalletVo.setTotalAmount(myWallet.getTotalAmount() == null ? new BigDecimal(0) : myWallet.getTotalAmount());
        appletWalletVo.setUnbooked(myWallet.getUnbooked() == null ? new BigDecimal(0) : myWallet.getUnbooked());
        appletWalletVo.setIsFrozen(myWallet.getIsFrozen());
        appletWalletVo.setUserId(myWallet.getUserId());
        return appletWalletVo;
    }

    public PageDataVO<WalletPageVo> listWalletWithPage(WalletFindDTO walletFindDTO) {

        PageDataVO<WalletPageVo> walletPageVo = new PageDataVO<>();
        PageDataVO<WalletListDTO> walletPage = PageDataVO.pageInfo(walletFindDTO.getPage(), walletFindDTO.getLimit(), () -> mapper.selectByPhoneOrUserName(walletFindDTO.getPhone(), walletFindDTO.getUsername()));
        List<WalletListDTO> wallets = walletPage.getData();
        if (CollectionUtils.isEmpty(wallets)) {
            return walletPageVo;
        }

        List<Integer> userIds = wallets.stream().map(WalletListDTO::getUserId).collect(Collectors.toList());
        Map<Integer, BigDecimal> userIdAndTotalConsumptionMap = myWalletDetailBiz.finduserIdAndPersonalTotalConsumptionMapByUserIds(userIds);
        Map<Integer, BigDecimal> userIdAndWithdrawalingMap = myWalletCathBiz.findUserIdAndWithdrawalingMapByUserIds(userIds);
        Map<Integer, AppUserDetail> userdetailMap = appUserDetailBiz.findUserIdAndUserDetailMapByMemberIds(userIds);
        List<WalletPostionVo> allPostions = appUserPositionBiz.findAllPostions();
        Map<Integer, WalletPostionVo> postionMap = allPostions.stream().collect(Collectors.toMap(WalletPostionVo::getId, Function.identity()));
        List<WalletPageVo> walletPageVos = new ArrayList<>();
        WalletPageVo walletpg;
        for (WalletListDTO wallet : wallets) {
            walletpg = new WalletPageVo();
            BeanUtils.copyProperties(wallet, walletpg);
            walletpg.setUsername(StringUtils.isEmpty(wallet.getRealname()) ? wallet.getNickname() : wallet.getRealname());
            walletpg.setPhone(wallet.getUsername());

            BigDecimal totalConsumpution = userIdAndTotalConsumptionMap == null ? new BigDecimal(0) : userIdAndTotalConsumptionMap.get(wallet.getUserId()) == null ? new BigDecimal(0) : userIdAndTotalConsumptionMap.get(wallet.getUserId());
            BigDecimal withDrawaling = userIdAndWithdrawalingMap == null ? new BigDecimal(0) : userIdAndWithdrawalingMap.get(wallet.getUserId()) == null ? new BigDecimal(0) : userIdAndWithdrawalingMap.get(wallet.getUserId());
            walletpg.setWithdrawaling(withDrawaling);
            walletpg.setWithdrawals(walletpg.getWithdrawals() == null ? new BigDecimal(0) : walletpg.getWithdrawals());
            walletpg.setUnbooked(walletpg.getUnbooked() == null ? new BigDecimal(0) : walletpg.getUnbooked());
            walletpg.setTotalAmount(walletpg.getTodayAmount() == null ? new BigDecimal(0) : walletpg.getTotalAmount());
            walletpg.setTotalConsumption(totalConsumpution);
            AppUserDetail appUserDetail = userdetailMap.get(wallet.getUserId());
            if (Objects.nonNull(appUserDetail)){
                WalletPostionVo walletPostionVo = postionMap.get(appUserDetail.getPositionId());
                if (Objects.nonNull(walletPostionVo)){
                    walletpg.setCommissionRate(walletPostionVo.getExtract());
                }
            }
            walletPageVos.add(walletpg);
        }



        walletPageVos.sort(Comparator.comparing(WalletPageVo::getTotalAmount).reversed());
        walletPageVo.setPageNum(walletFindDTO.getPage());
        walletPageVo.setPageSize(walletFindDTO.getLimit());
        walletPageVo.setTotalCount(walletPage.getTotalCount());
        walletPageVo.setTotalPage(walletPage.getTotalPage());
        walletPageVo.setData(walletPageVos);
        return walletPageVo;
    }

    //检查手机号码是否正确
    public ObjectRestResponse checkCode(String phone, String mobilecod) {
        boolean flag = false;
        String key = permissionService.checkCodeByUsername(phone, mobilecod);
        if (StringUtils.isNotBlank(key)) {
            flag = true;
        }
        return ObjectRestResponse.succ(flag);
    }

    //设置密码type 1-设置密码；2-修改密码
    public ObjectRestResponse setPwd(Integer userId, String phone, String mobilecod, String password, Integer type) {
        if (StringUtils.isBlank(phone) || StringUtils.isBlank(mobilecod) || StringUtils.isBlank(password)) {
            return ObjectRestResponse.createFailedResult(ResultCode.NULL_CODE, "参数为空");
        }
        String key = permissionService.checkCodeByUsername(phone, mobilecod);
        if (StringUtils.isBlank(key)) {
            return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "验证码错误");
        }
        userRedisTemplate.delete(key);
        MyWallet myWallet = new MyWallet();
        myWallet.setUserId(userId);
        myWallet = selectOne(myWallet);
        if (myWallet == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.NULL_CODE, "钱包不存在");
        }
        if (type == 1 && StringUtils.isNotBlank(myWallet.getPayPassword())) {
            return ObjectRestResponse.createFailedResult(ResultCode.EXIST_CODE, "密码已存在");
        }
        password = new BCryptPasswordEncoder(UserConstant.PW_ENCORDER_SALT).encode(password);
        myWallet.setPayPassword(password);
        updateSelectiveById(myWallet);
        return ObjectRestResponse.succ();
    }

    //检查用户是否设置过密码
    public ObjectRestResponse checkSetPwd(Integer userId) {
        MyWallet myWallet = new MyWallet();
        myWallet.setUserId(userId);
        myWallet = selectOne(myWallet);
        if (myWallet == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.NULL_CODE, "钱包不存在");
        }
        boolean flag = false;
        if (StringUtils.isNotBlank(myWallet.getPayPassword())) {
            flag = true;
        }
        return ObjectRestResponse.succ(flag);
    }

    //检查提成下一步操作
    public ObjectRestResponse checkAmount(Integer userId, BigDecimal amount, String password) {
        if (amount.compareTo(BigDecimal.ZERO) < 1) {
            return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "提现金额不能小于0");
        }
        MyWallet myWallet = new MyWallet();
        myWallet.setUserId(userId);
        myWallet = selectOne(myWallet);
        if (myWallet == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "钱包不存在");
        }
        if (amount.compareTo(myWallet.getBalance()) > 0) {
            return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "提现金额不能大于钱包金额");
        }
        if (StringUtils.isNotBlank(password) && !encoder.matches(password, myWallet.getPayPassword())) {
            return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "支付密码错误");
        }
        WithDrawRuleVo ruleVo = configFeign.getWithDrawRule();
        BigDecimal proceduReates = BigDecimal.ZERO;
        WalletCathSumDto sumDto = new WalletCathSumDto();
        if (ruleVo != null) {
            proceduReates = ruleVo.getProceduReates();
            //提现次数
            Integer number = 1;
            //最小金额
            BigDecimal mimAmount = ruleVo.getMinAmount();
            if (mimAmount.compareTo(BigDecimal.ZERO) > 0 && amount.compareTo(mimAmount) < 0) {
                return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "提现金额不能小于" + mimAmount + "元");
            }
            //日额度
            BigDecimal amountOfDay = ruleVo.getAmountOfDay();
            //每日次数
            Integer maxNumberOfDay = ruleVo.getMaxNumberOfDay() == null ? 0 : ruleVo.getMaxNumberOfDay();
            //查询当日次数和金额
            sumDto = myWalletCathBiz.sumCathAmount(userId, 1);
            BigDecimal ramount = amount.add(sumDto.getSumAmount());
            if (amountOfDay.compareTo(BigDecimal.ZERO) > 0 && ramount.compareTo(amountOfDay) > 0) {
                return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "提现金额超过日额度" + amountOfDay + "元");
            }
            number += sumDto.getNumber();
            if (maxNumberOfDay > 0 && number > maxNumberOfDay) {
                return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "提现当日次数超过" + maxNumberOfDay + "次");
            }
            number = 1;
            //月额度
            BigDecimal amountOfMonth = ruleVo.getAmountOfMonth();
            //月次数
            Integer maxNumberOfMonth = ruleVo.getMaxNumberOfMonth();

            //查询当月次数和金额
            sumDto = myWalletCathBiz.sumCathAmount(userId, 2);
            BigDecimal yamount = amount.add(sumDto.getSumAmount());
            if (amountOfMonth.compareTo(BigDecimal.ZERO) > 0 && yamount.compareTo(amountOfMonth) > 0) {
                return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "提现金额超过月额度" + amountOfMonth + "元");
            }
            number += sumDto.getNumber();
            if (maxNumberOfMonth > 0 && number > maxNumberOfMonth) {
                return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "提现当月次数超过" + maxNumberOfMonth + "次");
            }

        }
        sumDto.setBalance(myWallet.getBalance());
        sumDto.setProceduReates(proceduReates);
        sumDto.setWalletId(myWallet.getId());
        sumDto.setVersion(myWallet.getVersion());
        return ObjectRestResponse.succ(sumDto);
    }


    //返回提现规则
    public ObjectRestResponse getCathRule() {
        return ObjectRestResponse.succ(configFeign.getWithDrawRule());
    }

    //提现申请
    public ObjectRestResponse applyCath(ApplyCathVo applyCathVo) {
        if (applyCathVo == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.NULL_CODE, "参数不能为空");
        }
        Integer userId = applyCathVo.getUserId();
        BigDecimal amount = applyCathVo.getAmount();
        String password = applyCathVo.getPassword();
        String accountNumber = applyCathVo.getAccountNumber();
        Integer cathType = applyCathVo.getCathType() == null ? 1 : applyCathVo.getCathType();
        if (StringUtils.isBlank(password) || amount.compareTo(BigDecimal.ZERO) < 1) {
            return ObjectRestResponse.createFailedResult(ResultCode.NULL_CODE, "参数不能为空");
        }
        ObjectRestResponse restResponse = checkAmount(userId, amount, password);
        if (restResponse.getStatus() != ResultCode.SUCCESS_CODE) {
            return restResponse;
        }
        String data = JSONObject.toJSONString(restResponse.getData());
        WalletCathSumDto sumDto = JSONUtil.toBean(data, WalletCathSumDto.class);
        if (sumDto == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.NULL_CODE, "参数不能为空");
        }

        MyWalletCath walletCath = new MyWalletCath();
        WithDrawRuleVo withDrawRule = configFeign.getWithDrawRule();
        Integer withdrawWay = withDrawRule.getWithdrawWay();

        BigDecimal commission = amount.multiply(sumDto.getProceduReates()).divide(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP);
        BigDecimal balnece = sumDto.getBalance();
        //到账金额
        BigDecimal realAmount = amount;
        if ((realAmount.add(commission)).compareTo(balnece) > 0) {
            realAmount = balnece.subtract(commission);
        }
        //提现单号
        String orderNo = snowflake.nextIdStr();
        orderNo = String.format("%s%s", dateTimeFormatter.format(LocalDate.now()), orderNo);
        log.info("-----提现申请-----proceduReates===" + sumDto.getProceduReates() + "----commission====" + commission + "---realAmount===" + realAmount);
        walletCath.setCrtTime(Instant.now().toEpochMilli());
        walletCath.setOrderNo(orderNo);
        walletCath.setStauts(WithDrawStatusEnum.AUDIT.getCode());
        walletCath.setUserId(userId);
        walletCath.setBalance(balnece);
        walletCath.setCathType(cathType);
        walletCath.setAccountName(applyCathVo.getAccountName());
        walletCath.setAccountNumber(accountNumber);
        walletCath.setAmount(amount);
        walletCath.setCommission(commission);
        walletCath.setRealAmount(realAmount);
        myWalletCathBiz.insertSelective(walletCath);
        //提现金额
        BigDecimal withdrawals = realAmount.add(commission);
        balnece = balnece.subtract(withdrawals).setScale(2, RoundingMode.HALF_UP);
        log.info("------钱包----withdrawals===" + withdrawals + "----balnece====" + balnece);
        MyWallet myWallet = new MyWallet();
        myWallet.setId(sumDto.getWalletId());
        myWallet.setUserId(userId);
        myWallet.setBalance(balnece);
        myWallet.setWithdrawals(withdrawals);
        myWallet.setVersion(sumDto.getVersion());
        mapper.updMyWater(myWallet);
        //线上自动提现
        if (WITHDRAW_ONLINE_WAY.equals(withdrawWay)) {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String host = StringUtils.defaultIfBlank(request.getHeader("userHost"), ClientUtil.getClientIp(request));
            FundPayVo fundPayVo = FundPayVo.builder()
                    .amount(applyCathVo.getCathType() == 0 ? String.valueOf(realAmount.multiply(new BigDecimal(100)).doubleValue()) : String.format("%.2f", realAmount.doubleValue()))
                    .orderNo(orderNo)
                    .payeeAccount(applyCathVo.getAccountNumber())
                    .payerShowName("欣新房车网络科技（广东）股份有限公司")
                    .remark("提现转账")
                    .type(applyCathVo.getCathType())
                    .creatIp(host)
                    .build();
            //发送提现申请
            sendPayMessage(fundPayVo);
        }
        return ObjectRestResponse.succ(walletCath.getId());
    }


    /**
     * 提现审核
     */
    public ObjectRestResponse verifyCath(Integer cathId, String reason, Integer status) {
        boolean isvalid = status == WithDrawStatusEnum.REJECT.getCode() && StringUtils.isBlank(reason) || cathId == null || cathId == 0;
        if (isvalid) {
            return ObjectRestResponse.createFailedResult(ResultCode.NULL_CODE, "参数不能为空");
        }
        MyWalletCath cath = myWalletCathBiz.selectById(cathId);
        cath.getUserId();
        if (cath == null) {
            return ObjectRestResponse.createFailedResult(ResultCode.NOTEXIST_CODE, "提现记录不存在");
        }

        Integer userId = cath.getUserId();
        MyWallet wallet = new MyWallet();
        wallet.setUserId(userId);
        wallet = selectOne(wallet);
        if (wallet != null) {
            //当时钱包的余额
            BigDecimal realAmount = cath.getRealAmount();
            BigDecimal commission = cath.getCommission();
            if (status == WithDrawStatusEnum.AGREE.getCode()) {

                HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
                String host = StringUtils.defaultIfBlank(request.getHeader("userHost"), ClientUtil.getClientIp(request));
                FundPayVo fundPayVo = FundPayVo.builder()
                        .amount(cath.getCathType() == 0 ? String.valueOf(cath.getRealAmount().multiply(new BigDecimal(100)).doubleValue()) : String.format("%.2f", cath.getRealAmount().doubleValue()))
                        .payeeAccount(cath.getAccountNumber())
                        .orderNo(cath.getOrderNo())
                        .payerShowName("欣新房车网络科技（广东）股份有限公司")
                        .remark("提现转账")
                        .type(cath.getCathType())
                        .creatIp(host)
                        .build();
                sendPayMessage(fundPayVo);
                log.info("发送提现消息成功：【{}】", fundPayVo);
            } else {
                cath.setStauts(status);
                cath.setReason(reason);
                cath.setFinishTime(System.currentTimeMillis());
                myWalletCathBiz.updateSelectiveByIdRe(cath);
                BigDecimal amount = realAmount.add(commission);
                BigDecimal balance = wallet.getBalance().add(amount);
                BigDecimal withdrawals = wallet.getWithdrawals().subtract(amount);
                wallet.setBalance(balance);
                wallet.setWithdrawals(withdrawals);
                mapper.updMyWater(wallet);
            }
        }
        return ObjectRestResponse.succ();
    }

    public void deleteByUserIds(Collection<Integer> userIds) {
        Example example = new Example(MyWallet.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("userId", userIds);
        mapper.deleteByExample(example);
    }


    public List<PayAccountVo> listPayAccountByUserId(Integer userId) {
        List<PayAccountVo> payAccountVos = new ArrayList<>();
        List<AppUserAlipay> alipayAccounts = appUserAlipayBiz.getListByUserId(userId);
        if (CollectionUtils.isNotEmpty(alipayAccounts)) {
            AppUserAlipay appUserAlipay = alipayAccounts.get(0);
            PayAccountVo alipayAccount = PayAccountVo.builder()
                    .account(appUserAlipay.getTxAlipay())
                    .accountType(1)
                    .nickName(appUserAlipay.getNickname())
                    .accountDesc(String.format("%s%s%s", "支付宝余额(", appUserAlipay.getTxAlipay(), ")"))
                    .build();
            payAccountVos.add(alipayAccount);
        }
        AppUserDetail appUserDetail = appUserDetailBiz.getUserByUserid(userId);
        AppUserLogin appUserLogin = appUserLoginBiz.getUserById(userId);
        if (!org.springframework.util.StringUtils.isEmpty(appUserLogin.getOpenid())) {
            PayAccountVo wxAccount = PayAccountVo.builder()
                    .account(appUserLogin.getOpenid())
                    .accountType(2)
                    .nickName(appUserDetail.getWxNickname())
                    .accountDesc(String.format("%s%s%s", "微信零钱(", appUserDetail.getNickname(), ")"))
                    .build();
            payAccountVos.add(wxAccount);
        }
        return payAccountVos;
    }

    public void withDrawProcess(String orderNo, String cono, String reason, Boolean isSuccess) {
        MyWalletCath myWalletCath = myWalletCathBiz.findWalletCatchByOrderNo(orderNo);
        BigDecimal balnece = myWalletCath.getBalance();
        myWalletCath.setCono(cono);
        if (myWalletCath.getStauts() == WithDrawStatusEnum.AUDIT.getCode()) {
            if (isSuccess) {
                myWalletCath.setStauts(WithDrawStatusEnum.SUCCESS.getCode());
                MyWalletDetail detail = new MyWalletDetail();
                detail.setUserId(myWalletCath.getUserId());
                detail.setItype(1);
                //设置提现单号
                detail.setWithDrawOrderNo(orderNo);
                detail.setCono(myWalletCath.getId().intValue());
                detail.setBalance(myWalletCath.getBalance());
                detail.setAmount(myWalletCath.getAmount());
                detail.setSource(10);
                myWalletDetailBiz.insertSelective(detail);
                detail.setId(null);
                detail.setSource(13);
                detail.setBalance(balnece.subtract(myWalletCath.getRealAmount()));
                detail.setAmount(myWalletCath.getCommission());
                myWalletDetailBiz.insertSelective(detail);
            } else {
                MyWallet wallet = new MyWallet();
                wallet.setUserId(myWalletCath.getUserId());
                wallet = selectOne(wallet);
                myWalletCath.setReason(reason);
                myWalletCath.setStauts(WithDrawStatusEnum.FAIL.getCode());
                BigDecimal amount = myWalletCath.getRealAmount().add(myWalletCath.getCommission());
                BigDecimal balance = wallet.getBalance().add(amount);
                BigDecimal withdrawals = wallet.getWithdrawals().subtract(amount).setScale(2, RoundingMode.HALF_UP);
                wallet.setBalance(balance);
                wallet.setWithdrawals(withdrawals);
                mapper.updMyWater(wallet);
            }
            myWalletCath.setFinishTime(Instant.now().toEpochMilli());
            myWalletCathBiz.updateSelectiveByIdRe(myWalletCath);
        }
    }

    private void sendPayMessage(FundPayVo fundPayVo) {
        String json = JSON.toJSONString(fundPayVo);
        Message message = MessageBuilder.withBody(json.getBytes())
                .setContentType(MessageProperties.CONTENT_TYPE_JSON).setContentEncoding("utf-8")
                .setMessageId(UUID.randomUUID() + "")
                .setHeader("x-delay", 2000).build();
        rabbitTemplate.convertAndSend(RabbitConstant.ADMIN_TOPIC, RabbitConstant.KEY_WALLET_WITH_DRAW, message);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        snowflake = new Snowflake(2, 2, false);
        dateTimeFormatter = DateTimeFormatter.ofPattern("YYYYMMdd");
    }


    public void forbiddenWalletById(Integer id, Integer state) {
        mapper.forbiddenWalletById(id,state);
    }
}
