package com.ruoyi.xq.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.xq.domain.*;
import com.ruoyi.xq.dto.admin.withdraw.UserWithdrawAdminVo;
import com.ruoyi.xq.dto.app.account.WithdrawReq;
import com.ruoyi.xq.dto.app.withdraw.WithdrawListAppVo;
import com.ruoyi.xq.dto.app.withdraw.WithdrawListPageQuery;
import com.ruoyi.xq.enums.account.WithdrawTypeEnum;
import com.ruoyi.xq.enums.common.AuditEnum;
import com.ruoyi.xq.enums.common.OrderTypeEnum;
import com.ruoyi.xq.enums.common.TraceIdEnum;
import com.ruoyi.xq.manager.OrderNoUtil;
import com.ruoyi.xq.manager.TraceIdManager;
import com.ruoyi.xq.mapper.UserWithdrawMapper;
import com.ruoyi.xq.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 用户提现审核Service业务层处理
 *
 * @author 77
 * @date 2024-03-04
 */
@RequiredArgsConstructor
@Service
public class UserWithdrawServiceImpl extends ServiceImpl<UserWithdrawMapper,UserWithdraw> implements UserWithdrawService {

    @Autowired
    private WithdrawSettingService withdrawSettingService;
    @Autowired
    private UserExtendService userExtendService;
    @Autowired
    private UserService userService;
    @Autowired
    private UserBankCardService userBankCardService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveWithdraw(WithdrawReq req) {
        User user = userService.getById(req.getUserId());
        WithdrawSetting withdrawSetting = withdrawSettingService.getById(req.getId());
        if(withdrawSetting == null){
            throw new ServiceException("提现参数错误");
        }
        UserBankCard userBankCard = userBankCardService.getByUserId(req.getUserId());
        if(userBankCard == null){
            throw new ServiceException("提现失败，请补充账户信息");
        }
        if(WithdrawTypeEnum.ALI.getCode().equals(req.getWithdrawType())){
            if(StringUtils.isEmpty(userBankCard.getAliCard()) || StringUtils.isEmpty(userBankCard.getAliName())){
                throw new ServiceException("提现失败，请补充支付宝账户信息");
            }
        } else {
            throw new ServiceException("提现失败，请选择提现方式");
        }
        String traceId = TraceIdManager.gen(TraceIdEnum.WITHDRAW);
        boolean withdraw = userExtendService.withdraw(req.getUserId(), withdrawSetting.getMoney(),traceId);
        if(!withdraw){
            throw new ServiceException("提现失败，余额不足");
        }
        String orderNo = OrderNoUtil.gen(OrderTypeEnum.WITHDRAW);
        UserWithdraw userWithdraw = new UserWithdraw();
        userWithdraw.setUserId(user.getId());
        userWithdraw.setUsercode(user.getUsercode());
        userWithdraw.setTraceId(traceId);
        userWithdraw.setOrderNo(orderNo);
        userWithdraw.setWithdrawType(req.getWithdrawType());
        userWithdraw.setCard(userBankCard.getAliCard());
        userWithdraw.setName(userBankCard.getAliName());
        userWithdraw.setWithdrawMoney(withdrawSetting.getMoney());
        userWithdraw.setRealWithdrawMoney(withdrawSetting.getMoney());
        userWithdraw.setWithdrawFees(BigDecimal.ZERO);
        userWithdraw.setWithdrawFeesCate(BigDecimal.ZERO);
        userWithdraw.setAuditStatus(AuditEnum.AUDITING.getCode());
        this.save(userWithdraw);
    }

    @Override
    public Page<WithdrawListAppVo> pageApp(PageQuery pageQuery, WithdrawListPageQuery query) {
        return baseMapper.pageApp(pageQuery.build(), query);
    }

    @Override
    public Page<UserWithdrawAdminVo> pageAdmin(PageQuery pageQuery, UserWithdrawAdminVo bo) {
        return baseMapper.pageAdmin(pageQuery.build(), bo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditSuccess(Long id, boolean autoTrans) {
        boolean flag = this.update(Wrappers.lambdaUpdate(UserWithdraw.class)
                .eq(UserWithdraw::getId, id)
                .eq(UserWithdraw::getAuditStatus, AuditEnum.AUDITING.getCode())
                .set(UserWithdraw::getAuditStatus, AuditEnum.SUCCESS.getCode())
                .set(UserWithdraw::getAuditIp, ServletUtils.getClientIP())
                .set(UserWithdraw::getAuditOpId, LoginHelper.getUserId())
                .set(UserWithdraw::getAuditOpName, LoginHelper.getUsername())
                .set(UserWithdraw::getAuditTime, LocalDateTime.now())
                .set(UserWithdraw::getAuditRemark, "审核成功"));
        if(flag){
            UserWithdraw userWithdraw = this.getById(id);
            userExtendService.incsWithdrawTotal(userWithdraw.getUserId(), userWithdraw.getWithdrawMoney());
            if(autoTrans){
                // TODO 自动打款
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void auditFail(Long id, String auditRemark) {
        boolean update = this.update(Wrappers.lambdaUpdate(UserWithdraw.class)
                .eq(UserWithdraw::getId, id)
                .eq(UserWithdraw::getAuditStatus, AuditEnum.AUDITING.getCode())
                .set(UserWithdraw::getAuditStatus, AuditEnum.FAIL.getCode())
                .set(UserWithdraw::getAuditIp, ServletUtils.getClientIP())
                .set(UserWithdraw::getAuditOpId, LoginHelper.getUserId())
                .set(UserWithdraw::getAuditOpName, LoginHelper.getUsername())
                .set(UserWithdraw::getAuditTime, LocalDateTime.now())
                .set(UserWithdraw::getAuditRemark, auditRemark));
        if(update){
            UserWithdraw userWithdraw = this.getById(id);
            userExtendService.resetWithdraw(userWithdraw.getUserId(),userWithdraw.getWithdrawMoney(), userWithdraw.getTraceId());
        }
    }
}
