package com.qs.mp.channel.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.qs.mp.channel.domain.Channel;
import com.qs.mp.channel.domain.ChannelBankCard;
import com.qs.mp.channel.domain.ChannelMoneyLog;
import com.qs.mp.channel.domain.ChannelWithdraw;
import com.qs.mp.channel.domain.vo.ChannelWithdrawVO;
import com.qs.mp.channel.mapper.ChannelWithdrawMapper;
import com.qs.mp.channel.service.IChannelBankCardService;
import com.qs.mp.channel.service.IChannelMoneyLogService;
import com.qs.mp.channel.service.IChannelService;
import com.qs.mp.channel.service.IChannelWithdrawService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qs.mp.common.enums.ChannelMoneyEnum;
import com.qs.mp.common.enums.ChannelWithdrawStatusEnum;
import com.qs.mp.common.utils.LogUtil;
import com.qs.mp.common.utils.WebhookService;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

/**
 * <p>
 * 渠道提现表 服务实现类
 * </p>
 *
 * @author quanshu
 * @since 2022-03-04
 */
@Service
public class ChannelWithdrawServiceImpl extends ServiceImpl<ChannelWithdrawMapper, ChannelWithdraw> implements IChannelWithdrawService {

  @Autowired
  private IChannelBankCardService channelBankCardService;

  @Autowired
  private IChannelService channelService;

  @Autowired
  private IChannelMoneyLogService channelMoneyLogService;

  @Override
  @Transactional
  public boolean apply(Channel channel, ChannelWithdraw channelWithdraw) {

    // 更新用户的银行卡信息
    ChannelBankCard bankCard = channelBankCardService.getOne(new LambdaQueryWrapper<ChannelBankCard>()
        .eq(ChannelBankCard::getChannelId, channel.getChannelId()));
    if (null == bankCard) {
      bankCard = new ChannelBankCard();
      bankCard.setChannelId(channel.getChannelId());
      bankCard.setCardNo(channelWithdraw.getCardNo());
      bankCard.setBankName(channelWithdraw.getBankName());
      bankCard.setBranchName(channelWithdraw.getBranchName());
      bankCard.setUserName(channelWithdraw.getUserName());
      channelBankCardService.save(bankCard);
    } else {
      bankCard.setCardNo(channelWithdraw.getCardNo());
      bankCard.setBankName(channelWithdraw.getBankName());
      bankCard.setBranchName(channelWithdraw.getBranchName());
      bankCard.setUserName(channelWithdraw.getUserName());
      channelBankCardService.updateById(bankCard);
    }
    boolean rst = save(channelWithdraw);

    ChannelMoneyLog moneyLog = new ChannelMoneyLog();
    moneyLog.setChannelId(channel.getChannelId());
    moneyLog.setType(ChannelMoneyEnum.WITHDRAW);
    moneyLog.setLogMoney(channelWithdraw.getMoney());
    moneyLog.setBizTime(new Date());
    moneyLog.setRefId(String.valueOf(channelWithdraw.getId()));
    moneyLog.setLogText("银行卡尾号 " + channelWithdraw.getCardNo().substring(channelWithdraw.getCardNo().length() - 4));
    channelMoneyLogService.changeMoney(moneyLog);

    if (channelWithdraw.getChargeAmt() > 0) {
      // 手续费
      ChannelMoneyLog feeMoneyLog = new ChannelMoneyLog();
      feeMoneyLog.setChannelId(channel.getChannelId());
      feeMoneyLog.setType(ChannelMoneyEnum.WITHDRAW_FEE);
      feeMoneyLog.setLogMoney(channelWithdraw.getChargeAmt());
      feeMoneyLog.setBizTime(new Date());
      feeMoneyLog.setRefId(String.valueOf(channelWithdraw.getId()));
      channelMoneyLogService.changeMoney(feeMoneyLog);
    }
    StringBuilder sb = new StringBuilder();
    sb.append("提现申请\n");
    sb.append("申请人：").append(channel.getName()).append("\n");
    sb.append("提现金额：").append(new BigDecimal(channelWithdraw.getMoney()).divide(new BigDecimal(100), 2, RoundingMode.DOWN)).append("元\n");
    WebhookService.sendBizData(sb.toString());
    // 创建提现记录
    return rst;
  }

  @Override
  public List<ChannelWithdrawVO> listWithdrawVO(Wrapper<ChannelWithdraw> queryWrapper) {
    return getBaseMapper().listWithdrawVO(queryWrapper);
  }

  @Override
  @Transactional
  public boolean verify(ChannelWithdraw withdraw, ChannelWithdrawStatusEnum status, String verifyContent) {
    if (status == ChannelWithdrawStatusEnum.FINISHED) {
      boolean rtn = update(new LambdaUpdateWrapper<ChannelWithdraw>()
          .set(ChannelWithdraw::getStatus, status)
          .set(ChannelWithdraw::getTransferTime, new Date())
          .eq(ChannelWithdraw::getId, withdraw.getId())
          .eq(ChannelWithdraw::getStatus, ChannelWithdrawStatusEnum.WITHDRAWING));
      Assert.isTrue(rtn, "提现申请审核通过，更新提现申请状态失败。id:" + withdraw.getId());

      // 更新冻结金额
      Channel channel = channelService.getById(withdraw.getChannelId());
      Assert.isTrue(channel.getFrozenMoney() >= withdraw.getMoney() + withdraw.getChargeAmt(),
          "提现申请审核通过，更新冻结金额时冻结金额为:" + channel.getFrozenMoney() + ",本次要释放冻结金额为：" + withdraw.getMoney() + withdraw.getChargeAmt());

      boolean updateRtn = channelService.update(new LambdaUpdateWrapper<Channel>()
          .set(Channel::getFrozenMoney, channel.getFrozenMoney() - withdraw.getMoney() - withdraw.getChargeAmt())
          .eq(Channel::getChannelId, withdraw.getChannelId())
          .eq(Channel::getFrozenMoney, channel.getFrozenMoney()));
      Assert.isTrue(updateRtn, "提现申请审核通过，更新账号冻结金额。channelId:" + channel.getChannelId());
    } else if (status == ChannelWithdrawStatusEnum.FAILED) {
      boolean rtn = update(new LambdaUpdateWrapper<ChannelWithdraw>()
          .set(ChannelWithdraw::getStatus, status)
          .set(ChannelWithdraw::getVerifyContent, verifyContent)
          .eq(ChannelWithdraw::getId, withdraw.getId())
          .eq(ChannelWithdraw::getStatus, ChannelWithdrawStatusEnum.WITHDRAWING));
      Assert.isTrue(rtn, "提现申请审核不通过，更新提现申请状态失败。id:" + withdraw.getId());

      // 退回冻结金额
      Channel channel = channelService.getById(withdraw.getChannelId());
      Assert.isTrue(channel.getFrozenMoney() >= withdraw.getMoney() + withdraw.getChargeAmt(),
          "提现申请审核不通过，解冻冻结金额时冻结金额为:" + channel.getFrozenMoney() + ",本次要解冻金额为：" + withdraw.getMoney() + withdraw.getChargeAmt());
      ChannelMoneyLog moneyLog = new ChannelMoneyLog();
      moneyLog.setChannelId(channel.getChannelId());
      moneyLog.setType(ChannelMoneyEnum.WITHDRAW_BACK);
      moneyLog.setLogMoney(withdraw.getMoney() + withdraw.getChargeAmt());
      moneyLog.setBizTime(new Date());
      moneyLog.setRefId(String.valueOf(withdraw.getId()));
      moneyLog.setLogText(null);
      channelMoneyLogService.changeMoney(moneyLog);
    }
    return true;
  }
}
