package com.ruoyi.xq.service.impl;

import cn.hutool.core.util.NumberUtil;
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.xq.domain.ConsumeLog;
import com.ruoyi.xq.domain.User;
import com.ruoyi.xq.domain.UserExtend;
import com.ruoyi.xq.domain.WxTransOrder;
import com.ruoyi.xq.dto.admin.user.UserExtendAdminVo;
import com.ruoyi.xq.dto.admin.user.req.UpdateIncomeCoinReq;
import com.ruoyi.xq.dto.admin.user.req.UpdateWxTransNumReq;
import com.ruoyi.xq.enums.account.WxTransLogCateEnum;
import com.ruoyi.xq.enums.common.OrderTypeEnum;
import com.ruoyi.xq.enums.common.SystemConfigEnum;
import com.ruoyi.xq.enums.common.TraceIdEnum;
import com.ruoyi.xq.enums.consumer.ConsumerTypeEnum;
import com.ruoyi.xq.enums.pay.PayStatusEnum;
import com.ruoyi.xq.enums.pay.PlatformTypeEnum;
import com.ruoyi.xq.enums.user.AccountChangeCodeEnum;
import com.ruoyi.xq.enums.account.WxTransSourceEnum;
import com.ruoyi.xq.manager.OrderNoUtil;
import com.ruoyi.xq.manager.SystemConfigManager;
import com.ruoyi.xq.manager.TraceIdManager;
import com.ruoyi.xq.mapper.UserExtendMapper;
import com.ruoyi.xq.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;

/**
 * 用户邀请Service业务层处理
 *
 * @author 77
 * @date 2024-03-04
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class UserExtendServiceImpl extends ServiceImpl<UserExtendMapper,UserExtend> implements UserExtendService {
    @Autowired
    private UserService userService;
    @Autowired
    private WxTransOrderService wxTransOrderService;
    @Autowired
    private SystemConfigManager systemConfigManager;
    @Autowired
    private AccountChangeLogService accountChangeLogService;
    @Autowired
    private WxTransLogService wxTransLogService;

    @Override
    public boolean withdraw(Long userId, BigDecimal withdrawPrice,String traceId){
        boolean success = baseMapper.decrIncome(userId, withdrawPrice);
        if(success){
            accountChangeLogService.saveLogNoAdmin(userId, AccountChangeCodeEnum.WITHDRAW, withdrawPrice, traceId);
        }
        return success;
    }

    @Override
    public void resetWithdraw(Long userId, BigDecimal withdrawMoney, String traceId) {
        boolean success = baseMapper.incrIncome(userId, withdrawMoney);
        if(success){
            accountChangeLogService.saveLogNoAdmin(userId, AccountChangeCodeEnum.WITHDRAW_FAIL, withdrawMoney, traceId);
        }
    }

    /**
     * 新增提现统计
     * @param userId
     * @param withdrawMonty
     */
    @Override
    public boolean incsWithdrawTotal(Long userId, BigDecimal withdrawMonty){
        return baseMapper.incsWithdrawCount(userId,withdrawMonty);
    }

    @Override
    public boolean incsConsumeTotal(Long userId, BigDecimal consumeMonty) {
        return baseMapper.incsConsumeTotal(userId,consumeMonty);
    }


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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateIncomeCoin(UpdateIncomeCoinReq bo) {
        User user = userService.getByUsercode(bo.getUsercode());
        if(user == null){
            throw new ServiceException("用户不存在");
        }
        boolean income = baseMapper.incrIncome(user.getId(), bo.getRechargeCoin());
        if(!income){
            throw new ServiceException("调整失败，请保证调整后金额不为负数");
        }
        if(bo.getRechargeCoin().doubleValue() > 0){ // 正数
            accountChangeLogService.saveLogAdminOfSystem(user, AccountChangeCodeEnum.SYSTEM_INCOME_COIN_INCS, bo,LoginHelper.getLoginUser());
        }else if(bo.getRechargeCoin().doubleValue() < 0){ // 负数
            accountChangeLogService.saveLogAdminOfSystem(user, AccountChangeCodeEnum.SYSTEM_INCOME_COIN_INCS, bo,LoginHelper.getLoginUser());
        }
    }

    @Override
    public boolean distribution(ConsumeLog consumer, Long userId, BigDecimal amount, AccountChangeCodeEnum changeCodeEnum) {
        User user = userService.getById(userId);
        UserExtend userExtend = this.getByUserId(userId);
        if(userExtend == null || user == null){
            log.error("分销失败,无效账号 userId={}",userId);
            return false;
        }
        if(amount == null || changeCodeEnum == null){
            log.error("分销失败，参数错误 amount={},accountChangeEnum={}",amount,changeCodeEnum);
            return false;
        }
        baseMapper.incrIncome(userId, amount);
        if(ConsumerTypeEnum.VIP.getCode().equals(consumer.getType())){
            accountChangeLogService.saveLogNoAdminOfConsumer(user, changeCodeEnum,amount,consumer.getTraceId(), consumer.getSourceUserId());
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWxTransNum(UpdateWxTransNumReq bo) {
        User user = userService.getByUsercode(bo.getUsercode());
        if(user == null){
            throw new ServiceException("用户不存在");
        }
        if(bo.getNumber() == null || bo.getNumber() == 0){
            throw new ServiceException("请填写微信调整次数");
        }
        boolean wxTransNum = baseMapper.incrWxTransNum(user.getId(), bo.getNumber());
        if(!wxTransNum){
            throw new ServiceException("调整失败，请保证调整后交换次数不为负数");
        }
        BigDecimal price = systemConfigManager.getSystemConfigOfBigDecimal(SystemConfigEnum.WX_TRANS_PRICE);
        String orderNo = OrderNoUtil.gen(OrderTypeEnum.WX_TRANS);
        String traceId = TraceIdManager.gen(TraceIdEnum.WX_TRANS);
        WxTransOrder wxTransOrder = new WxTransOrder();
        wxTransOrder.setUserId(user.getId());
        wxTransOrder.setUsercode(user.getUsercode());
        wxTransOrder.setWxNum(bo.getNumber());
        wxTransOrder.setWxPrice(NumberUtil.mul(price,bo.getNumber()));
        wxTransOrder.setOrderName(String.format("管理员新增%s个微信交换",bo.getNumber()));
        wxTransOrder.setOrderNo(orderNo);
        wxTransOrder.setPlatformType(PlatformTypeEnum.ADMIN.getCode());
        wxTransOrder.setPayStatus(PayStatusEnum.NO_PAY.getCode());
        wxTransOrder.setSource(WxTransSourceEnum.ADMIN.getCode());
        wxTransOrder.setAdminId(LoginHelper.getUserId());
        wxTransOrder.setTraceId(traceId);
        wxTransOrderService.save(wxTransOrder);
        wxTransLogService.saveLogAdmin(user, bo.getNumber(),traceId);
    }

    @Override
    public boolean consumeWxTrans(Long sponsorUserId, User receiveUser, String traceId) {
        boolean success = baseMapper.incsWxTransNum(sponsorUserId, -1);
        if(success){
            wxTransLogService.consumerSaveLog(sponsorUserId, traceId,receiveUser);
        }
        return success;
    }

    @Override
    public boolean incsWxTrans(Long userId, Integer wxTransNum, WxTransLogCateEnum cateEnum, String traceId, String remark) {
        boolean success = baseMapper.incsWxTransNum(userId, wxTransNum);
        if(success){
            wxTransLogService.saveLog(userId, wxTransNum,cateEnum,traceId,remark);
        }
        return success;
    }

    @Override
    public UserExtend getByUserId(Long userId) {
        return this.getOne(Wrappers.lambdaQuery(UserExtend.class).eq(UserExtend::getUserId, userId).last("limit 1"));
    }
    @Override
    public UserExtend getByUserCode(String usercode) {
        return this.getOne(Wrappers.lambdaQuery(UserExtend.class).eq(UserExtend::getUsercode, usercode).last("limit 1"));
    }

}
