package cn.pluss.platform.merchantProfit.impl;

import cn.pluss.platform.constants.Constant;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.enums.BstLevelCode;
import cn.pluss.platform.enums.UserRoleEnum;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.LevelMapper;
import cn.pluss.platform.mapper.MerchantBaseInfoMapper;
import cn.pluss.platform.mapper.MerchantProfitMapper;
import cn.pluss.platform.mapper.UserAppMapper;
import cn.pluss.platform.merchant.MerchantRateNewService;
import cn.pluss.platform.merchantProfit.MerchantProfitService;
import cn.pluss.platform.notice.NoticeService;
import cn.pluss.platform.user.UserLevelService;
import cn.pluss.platform.user.impl.GeneralPushUtil;
import cn.pluss.platform.userAssess.UserAssessService;
import cn.pluss.platform.userRewardFlow.UserRewardFlowService;
import cn.pluss.platform.util.DateUtils;
import cn.pluss.platform.util.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
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.util.*;


@Service
@Slf4j
public class MerchantProfitServiceImpl extends ServiceImpl<MerchantProfitMapper, MerchantProfit> implements MerchantProfitService {


    @Resource
    private UserAppMapper userAppMapper;
    @Resource
    private NoticeService noticeService;

    @Resource
    private UserLevelService userLevelService;

    @Resource
    private UserRewardFlowService userRewardFlowService;

    @Autowired
    private GeneralPushUtil generalPushUtil;

    @Autowired
    private UserAssessService userAssessService;

    @Override
    @Transactional(rollbackFor = RuntimeException.class, propagation = Propagation.NESTED)
    public void batchInsert(Vector<MerchantProfit> profitList) {
        saveBatch(profitList);
    }


    @Override
    public void sendProfitMessage(UserApp userApp, BigDecimal profitMoney, String orderNumber) {
        if (profitMoney.doubleValue() <= 0.0001d) {
            return;
        }
        boolean flag = true;
        String amt = "0.0";
        try {
            //解决通知分润带有科学计数法
            amt = profitMoney.stripTrailingZeros().toPlainString();
            Notice notice = new Notice(0, 6, userApp);

            amt = String.format("%.2f", amt);

            notice.setConrtent("您有一笔" + amt + "元的推广分润");
            notice.setUniqueKey(userApp.getUserId() + orderNumber + "profit");
            noticeService.saveNotice(notice);
        } catch (RuntimeException e) {
            flag = false;
            e.printStackTrace();
        }
        List<String> alias = new ArrayList<>();
        log.info("=========推送人userId======" + userApp.getUserId() + "=========金额=======" + profitMoney);
        alias.add(userApp.getUserId() + "");
        try {
            if (flag) {
                String content = "本次分润金额：" + amt + "元";
                generalPushUtil.sendAllPlatByAlias(alias, "推广分润通知", content, "0");
                log.debug("========================================分润人USERID：{}分润金额：{}推送成功", userApp.getUserId(), amt);
            } else {
                log.debug("========================================分润人USERID：{}分润金额：{}重复推送", userApp.getUserId(), amt);
            }
        } catch (MsgException e) {
            log.debug(e.getMessage());
        }
    }

    /**
     * 分润创建2.0模式
     *
     * @param order:
     * @param type:
     * @date: 2022/1/21 15:16
     */
    @Override
    public void createOrderProfitV2(MerchantOrder order, String type) {
        log.info("【分润V2.0】分润计算开始====================>");
        UserApp userApp = userAppMapper.selectByMerchantCode(order.getMerchantCode());
        if (userApp == null) {
            userApp = userAppMapper.selectByUserId(order.getUserId());
        }
        MsgException.checkNull(userApp, "用户信息为空，分润创建失败");
        log.info("【分润V2.0】当前交易用户ID:{}，交易单号：{},交易用户角色：{}，用户等级：{}", userApp.getUserId(), order.getOrderNumber(), userApp.getRoleCode(), userApp.getLevelCode());
        if (StringUtil.isEmpty(userApp.getRoleCode()) || StringUtil.isEmpty(userApp.getLevelCode())) {
            log.info("【分润V2.0】订单号为：{}当前交易角色为空 创建分润结束", order.getOrderNumber());
            return;
        }
        calcUserProfitV2(userApp, order, type);
    }

    /**
     * 计算分润开始
     *
     * @param userApp:
     * @param orderType:
     * @date: 2022/1/21 15:29
     */
    private void calcUserProfitV2(UserApp userApp, MerchantOrder order, String orderType) {
        //2.0
        Vector<MerchantProfit> profitList = new Vector<MerchantProfit>();
        if (UserRoleEnum.SV2.getCode().equals(userApp.getRoleCode())) {
            createUserSV2Profit(userApp, order, null, userApp, profitList, 1, orderType);
        } else if (UserRoleEnum.ZY_BST.getCode().equals(userApp.getRoleCode())) {
            createUserBstProfit(userApp, userApp, order, profitList, 1, BigDecimal.ZERO, orderType);
        } else {
            log.info("【分润V2.0】交易用户类型位置 创建分润结束", order.getOrderNumber());
            return;
        }
        if (!profitList.isEmpty()) {
            log.info("【分润计算完成】开始批量插入分润数据,生成分润的订单编号：{}，分润条数：{}", order.getOrderNumber(), profitList.size());
            try {
                batchInsert(profitList);
                log.info("【分润插入】插入分润成功！");
            } catch (Exception e) {
                e.printStackTrace();
                log.info("【分润插入】插入分润异常，异常信息:{}", e.getMessage());
            }
            //累计生成分润的总额
            BigDecimal sumProfitMoney = BigDecimal.ZERO;
            for (MerchantProfit p : profitList) {
                sumProfitMoney = sumProfitMoney.add(new BigDecimal(String.valueOf(p.getPrice())));
            }
            order.setProfitShareMoney(sumProfitMoney.setScale(4, BigDecimal.ROUND_DOWN).doubleValue());
            log.info("【分润结算结束】订单号：{}产生的分润总额：{}", order.getOrderNumber(), sumProfitMoney);
        }
    }

    /**
     * 创建2.0分润
     *
     * @param nowUserApp:
     * @param order:
     * @date: 2022/1/21 15:48
     */
    private void createUserSV2Profit(UserApp userApp, MerchantOrder order, BigDecimal nowRate,
                                     UserApp nowUserApp, Vector<MerchantProfit> profitList, Integer type, String orderType) {
        Long parentId = userApp.getParentId();
        if (parentId == null) {
            log.info("【分润V2.0】订单号：{}，分润计算结束,获取分润的条数为：{}", order.getOrderNumber(), profitList.size());
            return;
        }
        if (nowRate == null) {
            nowRate = order.getRate();
        }
        UserApp pUserApp = userAppMapper.selectByUserId(parentId);
        if (pUserApp == null) {
            log.info("【分润V2.0】上级用户Id为空，分润创建结束");
            return;
        }
        UserLevel userLevel = userLevelService.getLevelInfoByRoleLevel(pUserApp.getRoleCode(), pUserApp.getLevelCode());
        if (userLevel == null) {
            log.info("【分润V2.0】用户角色配置异常，分润创建结束");
            return;
        }
        BigDecimal profitRate = BigDecimal.ZERO;
        //缴费通
        if ("2".equals(orderType)) {
            if (nowRate.compareTo(userLevel.getJftRate()) >= 0) {
                profitRate = nowRate.subtract(userLevel.getJftRate());
                nowRate = userLevel.getJftRate();
            }
        } else {
            if (nowRate.compareTo(userLevel.getRate()) >= 0) {
                profitRate = nowRate.subtract(userLevel.getRate());
                nowRate = userLevel.getRate();
            }
        }

        BigDecimal profitAmt = profitRate.divide(BigDecimal.valueOf(10000)).multiply(BigDecimal.valueOf(order.getConsumeFee())).setScale(4, BigDecimal.ROUND_DOWN);
        MerchantProfit profit = new MerchantProfit(nowUserApp, pUserApp, order, profitAmt, profitRate, type.toString(), orderType);
        profitList.add(profit);
        sendProfitMessage(pUserApp, profitAmt, order.getOrderNumber());
        if (type < 2) {
            type = type + 1;
        } else {
            type = 6;
        }
        createUserSV2Profit(pUserApp, order, nowRate, nowUserApp, profitList, type, orderType);
    }

    /**
     * 创建直营倍斯特分润
     *
     * @param userApp:
     * @param order:
     * @date: 2022/1/21 15:48
     */
    private void createUserBstProfit(UserApp userApp, UserApp nowUserApp, MerchantOrder order, Vector<MerchantProfit> profitList,
                                     Integer type, BigDecimal useRate, String orderType) {
        Long parentId = userApp.getParentId();
        if (type >= 3) {
            if (parentId != null) {
                UserApp pUser = userAppMapper.selectByUserId(parentId);
                if (pUser != null) {
                    if (UserRoleEnum.ZY_BST.getCode().equals(pUser.getRoleCode())) {
                        if (BstLevelCode.T2.getCode().equals(pUser.getLevelCode()) || BstLevelCode.T3.getCode().equals(pUser.getLevelCode())) {
                            UserRewardFlow rewardFlow = new UserRewardFlow(pUser, order, UserRewardFlow.TYPE_DIRE);
                            userRewardFlowService.save(rewardFlow);
                        }
                        Long p2Parent = pUser.getParentId();
                        if (p2Parent != null) {
                            UserApp p2User = userAppMapper.selectByUserId(p2Parent);
                            if (p2User != null && BstLevelCode.T3.getCode().equals(p2User.getLevelCode())) {
                                UserRewardFlow rewardFlow = new UserRewardFlow(p2User, order, UserRewardFlow.TYPE_INRE);
                                userRewardFlowService.save(rewardFlow);
                            }
                        }
                    }
                }
            }
            //获取倍斯特顶级分润
            String roleCode = userApp.getRoleCode() == null ? UserRoleEnum.ZY_BST.getCode() : userApp.getRoleCode();
            UserApp boosApp = userAppMapper.getRoleCodeAndLevelCode(roleCode, BstLevelCode.T4.getCode());
            if (userApp == null) {
                log.info("【倍斯特分润计算】订单号：{}，分润计算结束,未配置boss账号无法获取顶级分润：{}", order.getOrderNumber(), profitList.size());
            }
            BigDecimal pRate = boosApp.getRate() == null ? Constant.MIX_SETTLE_RATE : boosApp.getRate();
            if ("2".equals(orderType)) {
                pRate = Constant.JFT_MIX_SETTLE_RATE;
            }
            BigDecimal profitRate = order.getRate().subtract(pRate).subtract(useRate);
            BigDecimal profitAmt = profitRate.divide(BigDecimal.valueOf(10000)).multiply(BigDecimal.valueOf(order.getConsumeFee())).setScale(4, BigDecimal.ROUND_DOWN);
            MerchantProfit profit = new MerchantProfit(nowUserApp, boosApp, order, profitAmt, profitRate, type + "", orderType);
            sendProfitMessage(boosApp, profitAmt, order.getOrderNumber());
            profitList.add(profit);
            log.info("【倍斯特分润计算】订单号：{}，分润计算结束,获取分润的条数为：{}", order.getOrderNumber(), profitList.size());
            return;
        }
        UserApp pUserApp = userAppMapper.selectByUserId(parentId);
        if (pUserApp == null || !UserRoleEnum.ZY_BST.getCode().equals(pUserApp.getRoleCode())) {
            log.info("【倍斯特分润计算】上级用户Id为空或者当前用户上级角色异常，分润创建结束");
            return;
        }
        UserLevel userLevel = userLevelService.getLevelInfoByRoleLevel(pUserApp.getRoleCode(), pUserApp.getLevelCode());
        if (userLevel == null) {
            log.info("【倍斯特分润计算】用户角色配置异常，分润创建结束");
            return;
        }
        //判断用户是否在考核期间之内
//        boolean flag = userAssessService.getUserValid(parentId,pUserApp);
//        if(flag){
        if (BstLevelCode.T4.getCode().equals(userLevel.getLevelCode())) {
            BigDecimal t4Rate = userLevel.getRate() == null ? Constant.MIX_SETTLE_RATE : userLevel.getRate();
            if ("2".equals(orderType)) {
                t4Rate = userLevel.getJftRate() == null ? Constant.JFT_MIX_SETTLE_RATE : userLevel.getJftRate();
            }
            BigDecimal profitRate = order.getRate().subtract(t4Rate).subtract(useRate);
            if (profitRate.compareTo(BigDecimal.ZERO) <= 0) {
                profitRate = BigDecimal.ZERO;
            }
            BigDecimal profitAmt = profitRate.divide(BigDecimal.valueOf(10000)).multiply(BigDecimal.valueOf(order.getConsumeFee())).setScale(4, BigDecimal.ROUND_DOWN);
            MerchantProfit profit = new MerchantProfit(nowUserApp, pUserApp, order, profitAmt, profitRate, type.toString(), orderType);
            profitList.add(profit);
            sendProfitMessage(pUserApp, profitAmt, order.getOrderNumber());
            return;
        } else {
            BigDecimal profitRate = type == 1 ? userLevel.getDirectRate() : userLevel.getIndirectRate();
            BigDecimal profitAmt = profitRate.divide(BigDecimal.valueOf(10000)).multiply(BigDecimal.valueOf(order.getConsumeFee())).setScale(4, BigDecimal.ROUND_DOWN);
            MerchantProfit profit = new MerchantProfit(nowUserApp, pUserApp, order, profitAmt, profitRate, type.toString(), orderType);
            profitList.add(profit);
            type = type + 1;
            useRate = useRate.add(profitRate);
            sendProfitMessage(pUserApp, profitAmt, order.getOrderNumber());
            createUserBstProfit(pUserApp, nowUserApp, order, profitList, type, useRate, orderType);
        }
//        }else{
//
//        }
    }

    @Override
    public Map<String, BigDecimal> getProfitAmtCount(MerchantProfit condition) {
        return baseMapper.getProfitAmtCount(condition);
    }
}

