package com.buy507.mall.portal.service.impl;


import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.buy507.mall.mapper.*;
import com.buy507.mall.model.*;
import com.buy507.mall.portal.service.MemberCommissionService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

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

@Slf4j
@Service
public class MemberPointsSplitProfitService{

    @Resource
    private UmsMemberMapper memberMapper;
    /**
     * 会员分成流水
     */
    @Resource
    private UmsMemberAccountTransactionMapper umsMemberAccountTransactionMapper;

    /**
     * 会员上下关系
     */
    @Resource
    private UmsMemberRelationTreeMapper umsMemberRelationTreeMapper;
    /**
     * 会员等级
     */
    @Resource
    private UmsMemberLevelMapper umsMemberLevelMapper;

    @Autowired
    private OmsOrderMapper orderMapper;

    @Value("${becomeVipAmount}")
    private String becomeVipAmount;

    @Value("${sameLevelProfit}")
    private String sameLevelProfit;

    /**
     * 积分分润入口
     * @param order
     */
    public void pointsSplit(OmsOrder order) {

        UmsMember member = memberMapper.selectByPrimaryKey(order.getMemberId());
        //找到上级会员
        UmsMember higherLevelMember = this.findInOrderQueueMember(member.getId());;
        if(higherLevelMember != null){
            //进行订单分润
            this.splitProfitFroMember(member, higherLevelMember, order);
        }
        //计算会员等级
        UmsMemberRelationTree  relationTree = this.getUpLevelRelationTreeById(member.getId());
        if(relationTree == null){
            return;
        }
        //上级为空或者为普通用户
        UmsMember higherMember = memberMapper.selectByPrimaryKey(relationTree.getHigherLevelId());
        if(higherMember == null && higherMember.getMemberLevel().equals(MemberLevel.Member)){
            return;
        }
    }

    /**
     * 为订单上级进行分润
     * @param member
     * @param higherLevelMember
     * @param order
     */
    private void splitProfitFroMember(UmsMember member, UmsMember higherLevelMember, OmsOrder order) {

        //新订单及直属上级分润,返回的分润金额
        Integer revenuePoints = this.newMemberSplitProfit(member, higherLevelMember, order);

        UmsMember moreHigherMember = new UmsMember();
        //如果上级是vip会员
        if(higherLevelMember.getMemberLevel().equals(MemberLevel.Consumer)) {
            moreHigherMember = this.findNextHigherLevelMemberByType(higherLevelMember.getId(), MemberLevel.Consumer);
        }
        //没有更高的上级退出分润
        if(moreHigherMember == null){
            return;
        }
        //给三个级别代理分润
        this.twoLevelSplitProfit(higherLevelMember, moreHigherMember, order, revenuePoints);

        this.threeLevelSplitProfit(higherLevelMember, moreHigherMember, order, revenuePoints);

        this.fourLevelSplitProfit(higherLevelMember, moreHigherMember, order, revenuePoints);
    }


    /**
     * 查询到下一个级别的上级会员
     * @param id
     * @param consumer
     * @return
     */
    private UmsMember findNextHigherLevelMemberByType(Long id, MemberLevel consumer) {
        //找到上级
        UmsMember moreHigherMember = this.findInOrderQueueMember(id);
        if(moreHigherMember == null){
            return null;
        }
        while (moreHigherMember != null){
            if(moreHigherMember.getMemberLevel().getValue() > consumer.getValue()){
                return moreHigherMember;
            }
            moreHigherMember = this.findInOrderQueueMember(moreHigherMember.getId());
            if(moreHigherMember == null){
                return null;
            }
        }
        return moreHigherMember;
    }

    /**
     * 寻找上级
     */
    private UmsMember findInOrderQueueMember(Long id) {
        UmsMemberRelationTree  relationTree = this.getUpLevelRelationTreeById(id);
        if(relationTree == null){
            return null;
        }
        UmsMember higherMember = memberMapper.selectByPrimaryKey(relationTree.getHigherLevelId());
        if(higherMember == null){
            return null;
        }
        return higherMember;
    }

    /**
     * 会员分润
     * @param currentMember
     * @param higherLevelMember
     * @param order
     */
    private Integer newMemberSplitProfit(UmsMember currentMember, UmsMember higherLevelMember, OmsOrder order){

        //直推会员分润比例
        String ratio = "0."+ 3;

        Integer revenuePoints = order.getPayAmount().multiply(new BigDecimal(ratio)).intValue();
        UmsMemberAccountTransaction accountTransaction = new UmsMemberAccountTransaction();
        accountTransaction.setMemberId(higherLevelMember.getId());
        accountTransaction.setOrderId(order.getId());
        accountTransaction.setRemarks("直推VIP积分分润");
        accountTransaction.setTransactionState(UmsMemberAccountTransaction.TRANSACTION_STATE_YES);
        accountTransaction.setRevenuePoints(revenuePoints);
        accountTransaction.setTransferPaymentTime(DateUtil.date());
        accountTransaction.setFlowType(2);
        umsMemberAccountTransactionMapper.insert(accountTransaction);
        log.info("new Account Transaction {}" , JSONUtil.toJsonStr(accountTransaction));

        //会员积分到账
        higherLevelMember.setIntegration(revenuePoints + (higherLevelMember.getIntegration() == null ? 0 : higherLevelMember.getIntegration()));
        memberMapper.updateByPrimaryKey(higherLevelMember);


        return revenuePoints;
    }


    /**
     * 二级店长分润
     * @param lowerMember
     * @param higherMember
     * @param order
     */
    private void twoLevelSplitProfit(UmsMember lowerMember, UmsMember higherMember, OmsOrder order,
                                     Integer revenuePoints){
        //先判断是否为店长
        if(higherMember.getMemberLevel().equals(MemberLevel.Partner)){
            //上下级关系
            if(higherMember.getMemberLevel().getValue() > lowerMember.getMemberLevel().getValue()){

                UmsMemberLevel lowerLevel = umsMemberLevelMapper.selectByPrimaryKey(lowerMember.getMemberLevelId());
                UmsMemberLevel higherLevel = umsMemberLevelMapper.selectByPrimaryKey(higherMember.getMemberLevelId());

                Integer profitRatio = 0;
                if(higherLevel.getPointsRatio() != null && lowerLevel.getPointsRatio() != null){
                    profitRatio = higherLevel.getPointsRatio() - lowerLevel.getPointsRatio();
                }
                String ratioStr = profitRatio < 10 ? "0.0" + profitRatio : "0."+profitRatio;
                //计算上级的分积分分润
                Integer pointsCommission = order.getPayAmount().multiply(new BigDecimal(ratioStr)).intValue();

                UmsMemberAccountTransaction accountTransaction = new UmsMemberAccountTransaction();
                accountTransaction.setCommissionRatio(profitRatio);
                accountTransaction.setMemberId(higherMember.getId());
                accountTransaction.setOrderId(order.getId());
                accountTransaction.setRemarks("二级店长上级积分分润");
                accountTransaction.setRevenuePoints(pointsCommission);
                //即时到账
                accountTransaction.setTransferPaymentTime(DateUtil.date());
                accountTransaction.setFlowType(2);
                umsMemberAccountTransactionMapper.insert(accountTransaction);

                //会员金额到账
                higherMember.setIntegration(pointsCommission + (higherMember.getIntegration() == null ? 0 : higherMember.getIntegration()));
                memberMapper.updateByPrimaryKeySelective(higherMember);

                //查询上级
                UmsMember next = this.findInOrderQueueMember(higherMember.getId());

                if(next != null){
                    if (next.getMemberLevel().equals(higherMember.getMemberLevel())){
                        twoLevelSplitProfit(higherMember, next, order, pointsCommission);
                    }else {
                        threeLevelSplitProfit(higherMember, next, order, pointsCommission);
                        fourLevelSplitProfit(higherMember, next, order, pointsCommission);
                    }
                }
                //平级关系
            }else if(lowerMember.getMemberLevel().equals(lowerMember.getMemberLevel())){
                Integer pointsCommission = revenuePoints * (new BigDecimal("0."+sameLevelProfit)).intValue();

                UmsMemberAccountTransaction accountTransaction = new UmsMemberAccountTransaction();
                accountTransaction.setCommissionRatio(Integer.valueOf(sameLevelProfit));
                accountTransaction.setMemberId(higherMember.getId());
                accountTransaction.setOrderId(order.getId());
                accountTransaction.setRemarks("二级店长平级积分分润");
                accountTransaction.setRevenuePoints(pointsCommission);
                //即时到账
                accountTransaction.setTransferPaymentTime(DateUtil.date());
                accountTransaction.setFlowType(2);
                umsMemberAccountTransactionMapper.insert(accountTransaction);

                //会员金额到账
                higherMember.setIntegration(pointsCommission + (higherMember.getIntegration() == null ? 0 : higherMember.getIntegration()));
                memberMapper.updateByPrimaryKeySelective(higherMember);

                //查询比当前级别大的会员
                UmsMember next = this.findNextHigherLevelMemberByType(higherMember.getId(), MemberLevel.Partner);
                if(next != null){
                    threeLevelSplitProfit(higherMember, next, order, pointsCommission);
                    fourLevelSplitProfit(higherMember, next, order, pointsCommission);
                }
            }
        }
    }


    /**
     * 三级代理分润
     * @param lowerMember
     * @param higherMember
     * @param order
     */
    private void threeLevelSplitProfit(UmsMember lowerMember, UmsMember higherMember, OmsOrder order, Integer revenuePoints){
        if(higherMember.getMemberLevel().equals(MemberLevel.Diamond)){
            //上下级关系
            if(higherMember.getMemberLevel().getValue() > lowerMember.getMemberLevel().getValue()){

                UmsMemberLevel lowerLevel = umsMemberLevelMapper.selectByPrimaryKey(lowerMember.getMemberLevelId());
                UmsMemberLevel higherLevel = umsMemberLevelMapper.selectByPrimaryKey(higherMember.getMemberLevelId());

                Integer profitRatio = 0;
                if(higherLevel.getPointsRatio() != null && lowerLevel.getPointsRatio() != null){
                    profitRatio = higherLevel.getPointsRatio() - lowerLevel.getPointsRatio();
                }

                String ratioStr = profitRatio < 10 ? "0.0" + profitRatio : "0."+profitRatio;
                //计算上级的分积分分润
                Integer pointsCommission = order.getPayAmount().multiply(new BigDecimal(ratioStr)).intValue();
                UmsMemberAccountTransaction accountTransaction = new UmsMemberAccountTransaction();
                accountTransaction.setCommissionRatio(profitRatio);
                accountTransaction.setMemberId(higherMember.getId());
                accountTransaction.setOrderId(order.getId());
                accountTransaction.setRemarks("三级代理上级积分分润");
                accountTransaction.setRevenuePoints(pointsCommission);
                accountTransaction.setTransferPaymentTime(DateUtil.date());
                accountTransaction.setFlowType(2);
                umsMemberAccountTransactionMapper.insert(accountTransaction);

                //会员金额到账
                higherMember.setIntegration(pointsCommission + (higherMember.getIntegration() == null ? 0 : higherMember.getIntegration()));
                memberMapper.updateByPrimaryKeySelective(higherMember);

                //查询上级
                UmsMember next = this.findInOrderQueueMember(higherMember.getId());

                if(next != null){
                    if (next.getMemberLevel().equals(higherMember.getMemberLevel())){
                        threeLevelSplitProfit(higherMember, next, order, pointsCommission);
                    }else {
                        fourLevelSplitProfit(higherMember, next, order, pointsCommission);
                    }
                }
                //平级关系
            }else if(lowerMember.getMemberLevel().equals(lowerMember.getMemberLevel())){
                Integer pointsCommission = revenuePoints * (new BigDecimal("0."+sameLevelProfit)).intValue();
                UmsMemberAccountTransaction accountTransaction = new UmsMemberAccountTransaction();
                accountTransaction.setCommissionRatio(Integer.valueOf(sameLevelProfit));
                accountTransaction.setMemberId(higherMember.getId());
                accountTransaction.setOrderId(order.getId());
                accountTransaction.setRemarks("三级代理平级积分分润");
                accountTransaction.setRevenuePoints(pointsCommission);
                //24小时后到账
                accountTransaction.setTransferPaymentTime(DateUtil.tomorrow());
                accountTransaction.setFlowType(2);
                umsMemberAccountTransactionMapper.insert(accountTransaction);

                //会员金额到账
                higherMember.setIntegration(pointsCommission + (higherMember.getIntegration() == null ? 0 : higherMember.getIntegration()));
                memberMapper.updateByPrimaryKeySelective(higherMember);

                UmsMember next = this.findNextHigherLevelMemberByType(higherMember.getId(), MemberLevel.Diamond);
                if(next != null){
                    fourLevelSplitProfit(higherMember, next, order, pointsCommission);
                }
            }
        }

    }
    /**
     * 四级市代分润
     * @param lowerMember
     * @param higherMember
     * @param order
     */
    private void fourLevelSplitProfit(UmsMember lowerMember, UmsMember higherMember, OmsOrder order, Integer revenuePoints){
        if(higherMember.getMemberLevel().equals(MemberLevel.OneDiamond)){
            //上下级关系
            if(higherMember.getMemberLevel().getValue() > lowerMember.getMemberLevel().getValue()){

                UmsMemberLevel lowerLevel = umsMemberLevelMapper.selectByPrimaryKey(lowerMember.getMemberLevelId());
                UmsMemberLevel higherLevel = umsMemberLevelMapper.selectByPrimaryKey(higherMember.getMemberLevelId());

                Integer profitRatio = 0;
                if(higherLevel.getPointsRatio() != null && lowerLevel.getPointsRatio() != null){
                    profitRatio = higherLevel.getPointsRatio() - lowerLevel.getPointsRatio();
                }
                String ratioStr = profitRatio < 10 ? "0.0" + profitRatio : "0."+profitRatio;
                //计算上级的分积分分润
                Integer pointsCommission = order.getPayAmount().multiply(new BigDecimal(ratioStr)).intValue();
                UmsMemberAccountTransaction accountTransaction = new UmsMemberAccountTransaction();
                accountTransaction.setCommissionRatio(profitRatio);
                accountTransaction.setMemberId(higherMember.getId());
                accountTransaction.setOrderId(order.getId());
                accountTransaction.setRemarks("四级市代理上级积分分润");
                accountTransaction.setRevenuePoints(pointsCommission);
                //24小时后到账
                accountTransaction.setTransferPaymentTime(DateUtil.date());
                accountTransaction.setFlowType(2);
                umsMemberAccountTransactionMapper.insert(accountTransaction);

                //会员金额到账
                higherMember.setIntegration(pointsCommission + (higherMember.getIntegration() == null ? 0 : higherMember.getIntegration()));
                memberMapper.updateByPrimaryKeySelective(higherMember);

                //查询上级
                UmsMember next = this.findInOrderQueueMember(higherMember.getId());

                if(next != null && next.getMemberLevel().equals(higherMember.getMemberLevel())){
                    fourLevelSplitProfit(higherMember, next, order, pointsCommission);
                }
                //平级关系
            }else if(lowerMember.getMemberLevel().equals(lowerMember.getMemberLevel())){
                Integer pointsCommission = revenuePoints * (new BigDecimal("0."+sameLevelProfit)).intValue();
                UmsMemberAccountTransaction accountTransaction = new UmsMemberAccountTransaction();
                accountTransaction.setCommissionRatio(Integer.valueOf(sameLevelProfit));
                accountTransaction.setMemberId(higherMember.getId());
                accountTransaction.setOrderId(order.getId());
                accountTransaction.setRemarks("四级市代理平级积分分润");
                accountTransaction.setFlowType(2);
                accountTransaction.setRevenuePoints(pointsCommission);

                //会员金额到账
                higherMember.setIntegration(pointsCommission + (higherMember.getIntegration() == null ? 0 : higherMember.getIntegration()));
                memberMapper.updateByPrimaryKeySelective(higherMember);

                //24小时后到账
                accountTransaction.setTransferPaymentTime(DateUtil.tomorrow());
                umsMemberAccountTransactionMapper.insert(accountTransaction);
            }
        }
    }

    /**
     * 获取会员的上级关系
     * @param id
     * @return
     */
    private UmsMemberRelationTree getUpLevelRelationTreeById(Long id) {
        UmsMemberRelationTree relationTree = null;
        UmsMemberRelationTreeExample relationTreeExample = new UmsMemberRelationTreeExample();
        relationTreeExample.createCriteria().andMemberIdEqualTo(id);
        List<UmsMemberRelationTree> relationTreeList =  umsMemberRelationTreeMapper.selectByExample(relationTreeExample);
        if(!relationTreeList.isEmpty()) {
            //找到上级关系
            relationTree = relationTreeList.get(0);
        }
        return relationTree;
    }
}
