package cn.pluss.platform.UserMakerQuota.impl;


import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.pluss.platform.UserMakerQuota.UserMakerQuotaService;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.*;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.userAccount.UserAccountService;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.util.N;
import cn.pluss.platform.vo.UserMakerQuotaVO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.*;

/**
 * @author lyf
 */
@Service
@Slf4j
@Transactional
public class UserMakerQuotaServiceImpl extends ServiceImpl<UserMakerQuotaMapper, UserMakerQuota> implements UserMakerQuotaService {
    @Resource
    private UserMakerQuotaMapper userMakerQuotaMapper;
    @Resource
    private UserAppService userAppService;
    @Resource
    private UserAccountService userAccountService;
    @Resource
    private UserPromotionMapper userPromotionMapper;
    @Resource
    private MerchantBaseInfoService merchantBaseInfoService;
    @Resource
    private UserMakerFlowMapper userMakerFlowMapper;
    @Resource
    private UserAccountFlowMapper userAccountFlowMapper;

    @Override
    public Map<String, BigDecimal> quota() {
        UserApp userApp = userAppService.queryUserAppByToken();
        BigDecimal bigDecimal = userMakerQuotaMapper.sumQuota(userApp.getUserId());
        UserAccount userAccountByUserId = userAccountService.getUserAccountByUserId(userApp.getUserId());

        HashMap<String, BigDecimal> map = new HashMap<>(16);
        map.put("freeQuota",bigDecimal == null?
                new BigDecimal("0.00") : bigDecimal);
        map.put("returnFree",userAccountByUserId == null || userAccountByUserId.getBalance() == null?
                new BigDecimal("0.00") : userAccountByUserId.getBalance().setScale(2, BigDecimal.ROUND_DOWN));
        return map;
    }

    @Override
    public void quotaInfo(MerchantOrder order) {
        this.makerQuota(order);
    }

    @Override
    public List<UserMakerQuotaVO> quotaList(Integer page, Integer size, Integer type) {
        Integer pageSize = size;
        Integer offset = (page-1)*size;
        UserApp userApp = userAppService.queryUserAppByToken();
        switch (type) {
            //额度明细
            case 1:
                List<UserMakerQuotaVO> userMakerFlowsList = userMakerFlowMapper.selectByUserId(userApp.getUserId(), pageSize, offset);
                return userMakerFlowsList;
            //返现明细
            case 2:
                List<UserMakerQuotaVO> userAccountFlowsList = userAccountFlowMapper.selectByUserIdType(userApp.getUserId(),pageSize, offset);
                return userAccountFlowsList;
        }
        return new ArrayList<UserMakerQuotaVO>();
    }

    //增加额度
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void makerQuota(MerchantOrder order){

        //查询自己是否为创客
        MerchantBaseInfo merchantBaseInfoByMerchantCode = merchantBaseInfoService.getMerchantBaseInfoByMerchantCode(order.getMerchantCode());
        if(ObjectUtil.isEmpty(merchantBaseInfoByMerchantCode)){
            log.error("商户信息异常:{}",order.getOrderNumber());
            return;
        }

        UserPromotion userInfo = userPromotionMapper.selectByPrimaryKey(Long.valueOf(merchantBaseInfoByMerchantCode.getUserId()));
        if(ObjectUtil.isEmpty(userInfo)){
            log.error("用户所属关系不存在");
            return;
        }

        if("1".equals(userInfo.getIsExtend())) {
            UserMakerQuota userMakerQuota = userMakerQuotaMapper.selectByUserId(userInfo.getUserId().intValue());
            if (ObjectUtil.isEmpty(userMakerQuota)) {
                giveParentQuota(userInfo,order);
                return;
            }

            BigDecimal havingBalance = userMakerQuota.getAmount().subtract(new BigDecimal(String.valueOf(order.getConsumeFee()))).setScale(2, BigDecimal.ROUND_DOWN);
            if (havingBalance.compareTo(BigDecimal.ZERO) >= 0) {
                BigDecimal profit = new BigDecimal(String.valueOf(order.getConsumeFee())).subtract(new BigDecimal(String.valueOf(order.getEnterFee())));
                BigDecimal bigDecimal = new BigDecimal(order.getConsumeFee().toString());
                //提现金额
                userAccountService.modFunds(userInfo.getUserId().intValue(), "LD", "增加收益", profit, "");
                //额度改变
                modMakerFunds(userInfo.getUserId().intValue(), "LD", "收款消耗", bigDecimal.negate(), "", order.getOrderNumber());
                //
                giveParentQuota(userInfo,order);
                return;
            }
            if (havingBalance.compareTo(BigDecimal.ZERO) < 0) {
                BigDecimal profit = userMakerQuota.getAmount().multiply(new BigDecimal("0.0038")).setScale(6, BigDecimal.ROUND_DOWN);
                //提现金额
                userAccountService.modFunds(userInfo.getUserId().intValue(), "LD", "增加收益", profit.abs(), "");
                modMakerFunds(userInfo.getUserId().intValue(), "LD", "收款消耗", userMakerQuota.getAmount().abs().negate(), "", order.getOrderNumber());
                giveParentQuota(userInfo,order);
                return;
            }
        }
        giveParentQuota(userInfo,order);
    }
    //增加提现金额

    public void profit(UserPromotion userInfo,BigDecimal consumeFee,MerchantOrder order){
        UserMakerQuota userMakerQuota = userMakerQuotaMapper.selectByUserId(userInfo.getUserId().intValue());
        if (userMakerQuota != null) {
            BigDecimal sumbigDecimal = userMakerQuota.getAmount();
            if (sumbigDecimal != null && sumbigDecimal.compareTo(consumeFee) >= 0) {
                BigDecimal profit = consumeFee.multiply(new BigDecimal("0.0038")).setScale(2, BigDecimal.ROUND_DOWN);
                sumbigDecimal = sumbigDecimal.subtract(consumeFee);
                String s = String.valueOf(userInfo.getUserId());
                Integer integer = Integer.valueOf(s);
                BigDecimal bigDecimal = new BigDecimal(order.getConsumeFee().toString());
                //提现金额
                userAccountService.modFunds(integer, "LD", "免提现额度", profit, "");
                //额度改变
                modMakerFunds(integer, "LD", "收款消耗", bigDecimal, "",order.getOrderNumber());
            } else {
                BigDecimal profit = sumbigDecimal.multiply(new BigDecimal("0.0038")).setScale(2, BigDecimal.ROUND_DOWN);
                String s = String.valueOf(userInfo.getUserId());
                Integer integer = Integer.valueOf(s);
                //提现金额
                userAccountService.modFunds(integer, "LD", "收款消耗", profit, "");
                //额度改变
                modMakerFunds(integer, "LD", "收款消耗", BigDecimal.ZERO, "",order.getOrderNumber());
            }
        }

    }

    /**
     * 给上级额度
     * @param userInfo
     * @param order
     */
    @Transactional(rollbackFor = Exception.class)
    public void giveParentQuota( UserPromotion userInfo,MerchantOrder order){

        UserPromotion userParent = userPromotionMapper.selectByUserIdMC(Long.valueOf(userInfo.getParentUserId()));
        if (userParent == null){
            log.error("不存在的用户关系:{}",userInfo.getParentUserId());
            return;
        }
        if (!"1".equals(userParent.getIsExtend())){
            log.error("商户用户类型异常:{},{}",userParent.getUserId(),userParent.getIsExtend());
            return;
        }
        BigDecimal profit = new BigDecimal(order.getConsumeFee()).multiply(new BigDecimal("0.5")).setScale(2, BigDecimal.ROUND_DOWN);
        String s = String.valueOf(userParent.getUserId());
        Integer integer = Integer.valueOf(s);
        this.modMakerFunds(integer, "SD", "免费额度", profit, "", order.getOrderNumber());
    }
    /**
     * 创客额度相关
     * @param userId
     * @param bizCode
     * @param bizName
     * @param difference
     * @param remark
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.MANDATORY)
    public void modMakerFunds(Integer userId, String bizCode, String bizName, BigDecimal difference, String remark,String orderNumber) {
        Assert.notNull(userId, "NOt Null");
        Assert.notNull(bizCode, "Not Null");
        Assert.notNull(bizName, "Not Null");
        Assert.notNull(difference, "Not Null");

        UserMakerQuota userMakerQuota= initUserMaker(userId);
        if(N.gt(BigDecimal.ZERO,difference)){
            difference=difference.abs().negate();
        }
        if(N.gt(difference,BigDecimal.ZERO)){
            difference=difference.abs();
        }
        userMakerQuotaMapper.updateMakerFreeze(userId,difference);

        UserMakerFlow flow=new UserMakerFlow();
        flow.setUserId(userId);
        flow.setBizCode(bizCode);
        flow.setBizName(bizName);
        flow.setAmount(difference.abs());
        flow.setBalance(userMakerQuota.getAmount());
        flow.setCreateTime(new Date());
        flow.setOrderNumber(orderNumber);
        userMakerFlowMapper.insert(flow);
    }
    private UserMakerQuota initUserMaker(Integer userId){
        Assert.notNull(userId, "NOt Null");
        synchronized (this){
            UserMakerQuota userMakerQuota = userMakerQuotaMapper.selectByUserId(userId);
            if(ObjectUtil.isEmpty(userMakerQuota)){
                userMakerQuota=new UserMakerQuota();
                userMakerQuota.setUserId(Long.valueOf(userId));
                userMakerQuota.setAmount(BigDecimal.ZERO);
                userMakerQuota.setCreateTime(new Date());
                int result=baseMapper.insert(userMakerQuota);
                if(result<1){
                    MsgException.checkNull(null,"账户信息不存在");
                }
            }

            return userMakerQuota;
        }
    }
    public UserMakerQuota getUserAccountByUserId(Integer userId) {
        return baseMapper.selectById(userId);
    }

}
