package com.buy507.mall.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.buy507.mall.common.util.Constants;
import com.buy507.mall.component.RedisLock;
import com.buy507.mall.mapper.DmsMemberTotalIncomeMapper;
import com.buy507.mall.mapper.DmsMemberTradeRecordMapper;
import com.buy507.mall.mapper.DmsTeamLevelMapper;
import com.buy507.mall.mapper.DmsTeamMemberNumberMapper;
import com.buy507.mall.mapper.DmsTeamTotalConsumeMapper;
import com.buy507.mall.mapper.OmsOrderMapper;
import com.buy507.mall.mapper.UmsMemberMapper;
import com.buy507.mall.model.DmsMemberTotalIncome;
import com.buy507.mall.model.DmsMemberTradeRecord;
import com.buy507.mall.model.DmsTeamLevel;
import com.buy507.mall.model.DmsTeamMemberNumber;
import com.buy507.mall.model.DmsTeamTotalConsume;
import com.buy507.mall.model.ItemType;
import com.buy507.mall.model.MemberLevel;
import com.buy507.mall.model.OmsOrder;
import com.buy507.mall.model.OmsOrderExample;
import com.buy507.mall.model.StoreStatus;
import com.buy507.mall.model.UmsMember;
import com.buy507.mall.service.BackendCommonService;
import com.buy507.mall.service.DistributionService;

@Service
public class DistributionServiceImpl implements DistributionService {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(DistributionServiceImpl.class);
	
	@Autowired
	private UmsMemberMapper memberMapper;
	
	@Autowired
	private OmsOrderMapper orderMapper;
	
	@Autowired
	private DmsTeamLevelMapper teamLevelMapper;
	
	@Autowired
	private DmsMemberTradeRecordMapper memberTradeRecordMapper;
	
	@Autowired
	private DmsMemberTotalIncomeMapper memberTotalIncomeMapper;
	
	@Autowired
	private DmsTeamTotalConsumeMapper teamTotalConsumeMapper;
	
	@Autowired
	private DmsTeamMemberNumberMapper teamMemberNumberMapper;
	
	@Autowired
	private BackendCommonService commonService;
	
	@Autowired
    private RedisLock redisLock;
	
	/**
	 * 会员等级计算
	 * @param memberLevel
	 * @param member
	 * @param order
	 */
	public void computMemberLevel(Long memberId, OmsOrder order) {
		
		UmsMember member = memberMapper.selectByPrimaryKey(memberId);
		
		LOGGER.info("computMemberLevel start: {}", member.getUsername());
		LOGGER.info("computMemberLevel memberId: {}, orderId: {}, totalAmout: {}", member.getId(), order.getId(), order.getTotalAmount());
		
		recursionUpTeamMemberLevel(member, order);
		
		LOGGER.info("computMemberLevel end: {}", member.getUsername());
	}
	
	
	/**
	 * 递归重新计算上级团队人员的等级
	 * @param memberId
	 */
	private void recursionUpTeamMemberLevel(UmsMember member, OmsOrder order) {
		
		MemberLevel memberLevel = member.getMemberLevel();
		
		//查询会员累计消费金额和下级团队累计消费金额
		BigDecimal totalAmount = new BigDecimal(0);
		OmsOrderExample example = new OmsOrderExample();
		example.createCriteria().andMemberIdEqualTo(member.getId());
		List<OmsOrder> orderList = orderMapper.selectByExample(example);
		for(OmsOrder o : orderList) {
			//订单状态：0->待付款；1->待发货；2->已发货；3->已完成；4->已关闭；5->无效订单
			if(o.getStatus() == 1 || o.getStatus() == 2 || o.getStatus() == 3) {
				totalAmount = totalAmount.add(o.getTotalAmount());
			}
		}
		
		//会员累计消费金额+下级团队累计消费金额 
		DmsTeamTotalConsume teamTotalConsume = teamTotalConsumeMapper.selectOneByMemberId(member.getId());
		totalAmount = totalAmount.add(teamTotalConsume.getValue());
		
		boolean becomeConsumerFlag = false; //成为消费商的标志
		boolean becomePartnerFlag = false; //成为经销商的标志
		boolean becomeOneDiamondFlag = false; //成为初级合作商的标志
		boolean becomeTwoDiamondFlag = false; //成为中级合作商的标志
		boolean becomeThreeDiamondFlag = false; //成为高级合作商的标志
		boolean becomeFourDiamondFlag = false; //成为特级合作商的标志
		boolean becomeDiamondFlag = false; //成为合作商的标志
		
		
		//查询自己的下级
		List<DmsTeamLevel> teamLevelList = teamLevelMapper.selectByParentId(member.getId());
		
		BigDecimal money = null;
		//----升级消费商的条件判断
		if(MemberLevel.Member.equals(memberLevel)) {
			String becomeConsumer = commonService.getDictionaryValue(Constants.D_BECOME_CONSUMER);
			money = new BigDecimal(becomeConsumer);
			int flag = totalAmount.compareTo(money);
			
			//flag = -1,表示totalAmount小于money；flag = 0,表示totalAmount等于money；flag = 1,表示totalAmount大于money；
			//设置会员等级为消费商
			if(flag != -1) {
				becomeConsumerFlag = true;
			}
		}
		
		//----升级经销商的条件判断
		if(MemberLevel.Member.equals(memberLevel) || MemberLevel.Consumer.equals(memberLevel)) {
			String becomePartner = commonService.getDictionaryValue(Constants.D_BECOME_PARTNER);
			money = new BigDecimal(becomePartner);
			int flag = totalAmount.compareTo(money);
			//设置会员等级为合伙人
			if(flag != -1) {
				becomePartnerFlag = true;
			}
		}
		
		if(order != null) {
			//----升级合作商的条件判断
			if(MemberLevel.Member.equals(memberLevel) || MemberLevel.Consumer.equals(memberLevel) || MemberLevel.Partner.equals(memberLevel)) {
				String becomeOneDiamond = commonService.getDictionaryValue(Constants.D_BECOME_ONE_DIAMOND_ONE);
				money = new BigDecimal(becomeOneDiamond);
				
				//一次性消费判断，如果满足条件，直接升级
				int otherFlag = order.getTotalAmount().compareTo(money);
				if(otherFlag != -1) {
					becomeDiamondFlag = true;
				}
			}
		}
		
		//当前会员等级为合作商----升级初级合作商的条件判断
		if(MemberLevel.Member.equals(memberLevel) || MemberLevel.Consumer.equals(memberLevel)
				|| MemberLevel.Partner.equals(memberLevel) ||MemberLevel.Diamond.equals(memberLevel)) {
			String becomeOneDiamond = commonService.getDictionaryValue(Constants.D_BECOME_ONE_DIAMOND_ONE);
			money = new BigDecimal(becomeOneDiamond);
			int flag = totalAmount.compareTo(money);
			
			int becomeOneDiamondTwo = Integer.valueOf(commonService.getDictionaryValue(Constants.D_BECOME_ONE_DIAMOND_TWO));
			
			//成为一钻合伙人的第一个条件满足，再判断第二个条件
			//查询自己的下级是否达到3条线，每条线的直接下级是否满足条件
			int level = 2;
			if(flag != -1 && !teamLevelList.isEmpty() && teamLevelList.size() >= becomeOneDiamondTwo) {
				becomeOneDiamondFlag = computePartnerUpgradeCondition(teamLevelList, level, becomeOneDiamondTwo);
			}
			
		}
		
		//当前会员等级为初级合作商----升级中级合作商的条件判断
		if(MemberLevel.OneDiamond.equals(memberLevel)) {
			int becomeTwoDiamond = Integer.valueOf(commonService.getDictionaryValue(Constants.D_BECOME_TWO_DIAMOND));
			int level = 4;
			if(!teamLevelList.isEmpty() && teamLevelList.size() >= becomeTwoDiamond) {
				becomeTwoDiamondFlag = computePartnerUpgradeCondition(teamLevelList, level, becomeTwoDiamond);
			}
		}
		
		//当前会员等级为中级合作商----升级高级合作商的条件判断
		if(MemberLevel.TwoDiamond.equals(memberLevel)) {
			int becomeThreeDiamond = Integer.valueOf(commonService.getDictionaryValue(Constants.D_BECOME_THREE_DIAMOND));
			int level = 5;
			if(!teamLevelList.isEmpty() && teamLevelList.size() >= becomeThreeDiamond) {
				becomeThreeDiamondFlag = computePartnerUpgradeCondition(teamLevelList, level, becomeThreeDiamond);
			}
		}
		
		//当前会员等级为高级合作商----升级特级合作商的条件判断
		if(MemberLevel.ThreeDiamond.equals(memberLevel)) {
			int becomeFourDiamond = Integer.valueOf(commonService.getDictionaryValue(Constants.D_BECOME_FOUR_DIAMOND));
			int level = 6;
			if(!teamLevelList.isEmpty() && teamLevelList.size() >= becomeFourDiamond) {
				becomeFourDiamondFlag = computePartnerUpgradeCondition(teamLevelList, level, becomeFourDiamond);
			}
		}
		
		while(true) {
			long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
			if(redisLock.lock(String.valueOf(member.getId()), String.valueOf(time))) {
				if(becomeConsumerFlag) {
					member.setMemberLevel(MemberLevel.Consumer);
				}
				if(becomePartnerFlag) {
					member.setMemberLevel(MemberLevel.Partner);
				}
				if(becomeDiamondFlag) {
					member.setMemberLevel(MemberLevel.Diamond);
				}
				if(becomeOneDiamondFlag) {
					member.setMemberLevel(MemberLevel.OneDiamond);
				}
				if(becomeTwoDiamondFlag) {
					member.setMemberLevel(MemberLevel.TwoDiamond);
				}
				if(becomeThreeDiamondFlag) {
					member.setMemberLevel(MemberLevel.ThreeDiamond);
				}
				if(becomeFourDiamondFlag) {
					member.setMemberLevel(MemberLevel.FourDiamond);
				}
				
				//保存会员信息
				memberMapper.updateByPrimaryKey(member);
				redisLock.unlock(String.valueOf(member.getId()), String.valueOf(time));
				break;
			}
		}
		
		//重新计算上级团队成员数量
		//更新团队成员数量表
		//判断会员是否已经升级，如果没升级不重新计算
		//会员填写推荐人时也需要更新上级团队成员数量，使用redis分布式锁
		if(!memberLevel.equals(member.getMemberLevel())) {
			while(true) {
				long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
				if(redisLock.lock(Constants.LOCK_TEAM_MEMBER_NUM, String.valueOf(time))) {
					recursionUpTeamMemberNumber(member.getId(), memberLevel, member.getMemberLevel());
					redisLock.unlock(Constants.LOCK_TEAM_MEMBER_NUM, String.valueOf(time));
					break;
				}
			}
		}
		
		DmsTeamLevel teamLevel = teamLevelMapper.selectOneByMemberId(member.getId());
		if(teamLevel == null) {
			return;
		} else {
			UmsMember inviter = memberMapper.selectByPrimaryKey(teamLevel.getParentId());
			//递归重新计算上级团队人员的等级
			recursionUpTeamMemberLevel(inviter, null);
		}
		
	}
	
	
	/**
	 * 递归重新计算上级团队成员数量
	 * @param memberId
	 * @param oldLevel
	 * @param newLevel
	 */
	private void recursionUpTeamMemberNumber(Long memberId, MemberLevel oldLevel, MemberLevel newLevel) {
		DmsTeamLevel teamLevel = teamLevelMapper.selectOneByMemberId(memberId);
		if(teamLevel == null) {
			return;
		} else {
			
			//新的等级向上+1
			DmsTeamMemberNumber memberNumber = teamMemberNumberMapper.selectOneByMemberId(teamLevel.getParentId());
			if(MemberLevel.Consumer.equals(newLevel)) {
				memberNumber.setConsumer(memberNumber.getConsumer() + 1);
			}
			if(MemberLevel.Partner.equals(newLevel)) {
				memberNumber.setPartner(memberNumber.getPartner() + 1);
			}
			if(MemberLevel.OneDiamond.equals(newLevel)) {
				memberNumber.setOneDiamond(memberNumber.getOneDiamond() + 1);
			}
			if(MemberLevel.TwoDiamond.equals(newLevel)) {
				memberNumber.setTwoDiamond(memberNumber.getTwoDiamond() + 1);
			}
			if(MemberLevel.ThreeDiamond.equals(newLevel)) {
				memberNumber.setThreeDiamond(memberNumber.getThreeDiamond() + 1);
			}
			if(MemberLevel.FourDiamond.equals(newLevel)) {
				memberNumber.setFourDiamond(memberNumber.getFourDiamond() + 1);
			}
			
			//旧的等级向下-1
			if(MemberLevel.Consumer.equals(oldLevel)) {
				memberNumber.setConsumer(memberNumber.getConsumer() - 1);
			}
			if(MemberLevel.Partner.equals(oldLevel)) {
				memberNumber.setPartner(memberNumber.getPartner() - 1);
			}
			if(MemberLevel.OneDiamond.equals(oldLevel)) {
				memberNumber.setOneDiamond(memberNumber.getOneDiamond() - 1);
			}
			if(MemberLevel.TwoDiamond.equals(oldLevel)) {
				memberNumber.setTwoDiamond(memberNumber.getTwoDiamond() - 1);
			}
			if(MemberLevel.ThreeDiamond.equals(oldLevel)) {
				memberNumber.setThreeDiamond(memberNumber.getThreeDiamond() - 1);
			}
			
			teamMemberNumberMapper.updateById(memberNumber);
			recursionUpTeamMemberNumber(teamLevel.getParentId(), oldLevel, newLevel);
			
		}
		
	}
	
	/**
	 * 计算直推和间推的劳务费
	 * 
	 * 只有普通会员购买商品才会计算分享劳务费和服务劳务费
	 * 根据推荐人的等级计算分享劳务费和服务劳务费
	 * @param memberLevel
	 * @param member
	 * @param order
	 */
	public void computeRefereeCharge(Long memberId, OmsOrder order) {
		
		UmsMember member = memberMapper.selectByPrimaryKey(memberId);
		
		LOGGER.info("computeRefereeCharge start: {}", member.getUsername());
		LOGGER.info("computeRefereeCharge memberId: {}, orderId: {}, totalAmout: {}", member.getId(), order.getId(), order.getTotalAmount());
		
		if(MemberLevel.Member.equals(member.getMemberLevel())) {
			
			//查询直接推荐人信息
			DmsTeamLevel directTeamLevel = teamLevelMapper.selectOneByMemberId(order.getMemberId());
			if(directTeamLevel != null) {
				
				UmsMember direct = null;
				while(true) {
					long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
					if(redisLock.lock(String.valueOf(directTeamLevel.getParentId()), String.valueOf(time))) {
						direct = memberMapper.selectByPrimaryKey(directTeamLevel.getParentId());
						if(direct != null && direct.getStatus() == 1) {
							BigDecimal directIncome = null;
							if(MemberLevel.Consumer.equals(direct.getMemberLevel())) {
								double percent = Double.valueOf(commonService.getDictionaryValue(Constants.D_CONSUMER_DIRECT_INCOME)) / 100;
								directIncome = new BigDecimal(percent);
							}
							if(MemberLevel.Partner.equals(direct.getMemberLevel())) {
								double percent = Double.valueOf(commonService.getDictionaryValue(Constants.D_PARTNER_DIRECT_INCOME)) / 100;
								directIncome = new BigDecimal(percent);
							}
							
							if(direct.getMemberLevel().getValue() >= 3) {
								double percent = Double.valueOf(commonService.getDictionaryValue(Constants.D_DIAMOND_DIRECT_INCOME)) / 100;
								directIncome = new BigDecimal(percent);
							}
							if(directIncome != null) {
								directIncome = order.getTotalAmount().multiply(directIncome);
								//记录会员账户交易记录表
								insertMemberTradeRecord(direct.getId(), ItemType.ShareCharge, 0, directIncome, 
										"获得分享劳务费", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());
								
								//会员总收入表
								insertMemberTotalIncome(direct.getId(), ItemType.ShareCharge, directIncome);
								
								//会员积分账户变更
								direct.setBalance(direct.getBalance().add(directIncome));
								memberMapper.updateByPrimaryKey(direct);
							}
						}
						redisLock.unlock(String.valueOf(directTeamLevel.getParentId()), String.valueOf(time));
						break;
					}
				}
				
				if(direct != null) {
					//查询间接推荐人信息
					DmsTeamLevel indirectTeamLevel = teamLevelMapper.selectOneByMemberId(direct.getId());
					if(indirectTeamLevel != null) {
						
						while(true) {
							long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
							if(redisLock.lock(String.valueOf(indirectTeamLevel.getParentId()), String.valueOf(time))) {
								UmsMember indirect = memberMapper.selectByPrimaryKey(indirectTeamLevel.getParentId());
								if(indirect != null && indirect.getStatus() == 1) {
									BigDecimal indirectIncome = null;
									if(MemberLevel.Consumer.equals(indirect.getMemberLevel())) {
										double percent = Double.valueOf(commonService.getDictionaryValue(Constants.D_CONSUMER_INDIRECT_INCOME)) / 100;
										indirectIncome = new BigDecimal(percent);
									}
									if(MemberLevel.Partner.equals(indirect.getMemberLevel())) {
										double percent = Double.valueOf(commonService.getDictionaryValue(Constants.D_PARTNER_INDIRECT_INCOME)) / 100;
										indirectIncome = new BigDecimal(percent);
									}
									
									if(indirect.getMemberLevel().getValue() >= 3) {
										double percent = Double.valueOf(commonService.getDictionaryValue(Constants.D_DIAMOND_INDIRECT_INCOME)) / 100;
										indirectIncome = new BigDecimal(percent);
									}
									if(indirectIncome != null) {
										indirectIncome = order.getTotalAmount().multiply(indirectIncome);
										//记录会员账户交易记录表
										insertMemberTradeRecord(indirect.getId(), ItemType.ServiceCharge, 0, indirectIncome, 
												"获得服务劳务费", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());
										
										//会员总收入表
										insertMemberTotalIncome(indirect.getId(), ItemType.ServiceCharge, indirectIncome);
										
										//会员积分账户变更
										indirect.setBalance(indirect.getBalance().add(indirectIncome));
										memberMapper.updateByPrimaryKey(indirect);
									}
								}
								redisLock.unlock(String.valueOf(indirectTeamLevel.getParentId()), String.valueOf(time));
								break;
							}
							
						}
					}
				}
				
			}
		}
		
		LOGGER.info("computeRefereeCharge end: {}", member.getUsername());
	}
	
	/**
	 * 计算店补
	 * 
	 * 如果消费者本人开了店，店补算给自己
	 * 如果自己没开店，递归向上找到最近的一家店
	 * 找不到就不计算店补
	 * @param member
	 */
	public void computeStoreSubsidy(Long memberId, OmsOrder order) {
		
		UmsMember member = memberMapper.selectByPrimaryKey(memberId);
		
		LOGGER.info("computeStoreSubsidy start: {}", member.getUsername());
		LOGGER.info("computeStoreSubsidy memberId: {}, orderId: {}, totalAmout: {}", member.getId(), order.getId(), order.getTotalAmount());
		
		UmsMember storeMember = recursionFindStore(member);
		if(storeMember != null) {
			
			BigDecimal storeSubsidy = null;
			if(MemberLevel.Partner.equals(storeMember.getMemberLevel())) {
				double percent = Double.valueOf(commonService.getDictionaryValue(Constants.D_PARTNER_STORE_SUBSIDY)) / 100;
				storeSubsidy = new BigDecimal(percent);
				storeSubsidy = order.getTotalAmount().multiply(storeSubsidy);
			}
			
			if(storeMember.getMemberLevel().getValue() >= 3) {
				double percent = Double.valueOf(commonService.getDictionaryValue(Constants.D_DIAMOND_STORE_SUBSIDY)) / 100;
				storeSubsidy = new BigDecimal(percent);
				storeSubsidy = order.getTotalAmount().multiply(storeSubsidy);
			}
			
			if(storeSubsidy != null) {
				
				while(true) {
					long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
					if(redisLock.lock(String.valueOf(storeMember.getId()), String.valueOf(time))) {
						
						//记录会员账户交易记录表
						insertMemberTradeRecord(storeMember.getId(), ItemType.StoreSubsidy, 0, storeSubsidy, 
								"获得店补", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());
						
						storeMember = memberMapper.selectByPrimaryKey(storeMember.getId());
						//会员总收入表
						insertMemberTotalIncome(storeMember.getId(), ItemType.StoreSubsidy, storeSubsidy);				
						//会员积分账户变更
						storeMember.setBalance(storeMember.getBalance().add(storeSubsidy));
						memberMapper.updateByPrimaryKey(storeMember);
						
						redisLock.unlock(String.valueOf(storeMember.getId()), String.valueOf(time));
						break;
					}
				}
			}
		}
		LOGGER.info("computeStoreSubsidy end: {}", member.getUsername());
	}
	
	/**
	 * 计算团队服务劳务费 上级的收益
	 * 递归向上查询所有推荐人信息，如果会员等级是初级、中级、高级合作商，将获得团队服务劳务费
	 * 初级对其体系以下服务产生的营业额按10%计
	 * 中级对其初级体系以外的体系服务产生的营业额按14%计，对其初级体系以内的体系服务产生的营业额拿差额4%
	 * 高级对其无合作商的体系服务产生的营业额按16%计，对其中级体系以内的体系服务产生的营业额拿差额2%，对其初级体系以内的体系服务产生的营业额拿差额6%
	 * @param member
	 * @param order
	 */
	public void computeTeamIncome(Long memberId, OmsOrder order) {
		//先判断复消，如果是自己消费，且自己是初级，中级，高级就先算自己的，再向上算差额
		UmsMember member = memberMapper.selectByPrimaryKey(memberId);
		LOGGER.info("computeTeamIncome start: {}", member.getUsername());
		LOGGER.info("computeTeamIncome memberId: {}, orderId: {}, totalAmout: {}", member.getId(), order.getId(), order.getTotalAmount());
		
		double oneDiamondPercent = Double.valueOf(commonService.getDictionaryValue(Constants.D_ONE_DIAMOND_TEAM_INCOME)) / 100;
		double twoDiamondPercent = Double.valueOf(commonService.getDictionaryValue(Constants.D_TWO_DIAMOND_TEAM_INCOME)) / 100;
		double threeDiamondPercent = Double.valueOf(commonService.getDictionaryValue(Constants.D_THREE_DIAMOND_TEAM_INCOME)) / 100;
		BigDecimal oneDiamondBig = new BigDecimal(oneDiamondPercent);
		BigDecimal twoDiamondBig = new BigDecimal(twoDiamondPercent);
		BigDecimal threeDiamondBig = new BigDecimal(threeDiamondPercent);
		BigDecimal oneDiamondIncome = null;
		BigDecimal twoDiamondIncome = null;
		BigDecimal threeDiamondIncome = null;
		BigDecimal temp = null;
		
		UmsMember twoDiamond = null;
		UmsMember threeDiamond = null;
		
		//先计算自己达到获得团队服务费等级的情况
		//------------------自己 start------
		//如果自己是高级，不再向上算差额
		if(MemberLevel.ThreeDiamond.equals(member.getMemberLevel())) {
			//高级全额16%
			threeDiamondIncome = order.getTotalAmount().multiply(threeDiamondBig);
			
			saveMemberTeamIncome(member, member.getNickname(), order, threeDiamondIncome);
			
		} else if(MemberLevel.TwoDiamond.equals(member.getMemberLevel())) {
			//如果自己是中级，向上计算高级的差额
			//中级全额14%
			twoDiamondIncome = order.getTotalAmount().multiply(twoDiamondBig);
			
			saveMemberTeamIncome(member, member.getNickname(), order, twoDiamondIncome);
			
			//向上查找第一个高级
			threeDiamond = recursionFindAllParent(member, MemberLevel.ThreeDiamond);
			if(threeDiamond != null) {
				//高级拿差额2%
				temp = threeDiamondBig.subtract(twoDiamondBig);
				threeDiamondIncome = order.getTotalAmount().multiply(temp);
				
				saveMemberTeamIncome(threeDiamond, member.getNickname(), order, threeDiamondIncome);
				
			}
			
			
		} else if(MemberLevel.OneDiamond.equals(member.getMemberLevel())) {
			//如果自己是初级，向上计算中级的差额和高级的差额
			//初级拿全额10%
			oneDiamondIncome = order.getTotalAmount().multiply(oneDiamondBig);
			
			saveMemberTeamIncome(member, member.getNickname(), order, oneDiamondIncome);
			
			//中级拿差额4%
			twoDiamond = recursionFindAllParent(member, MemberLevel.TwoDiamond);
			if(twoDiamond != null) {
				temp = twoDiamondBig.subtract(oneDiamondBig);
				twoDiamondIncome = order.getTotalAmount().multiply(temp);
				
				saveMemberTeamIncome(twoDiamond, member.getNickname(), order, twoDiamondIncome);
				
				threeDiamond = recursionFindAllParent(member, MemberLevel.ThreeDiamond);
				if(threeDiamond != null) {
					//高级拿差额2%
					temp = threeDiamondBig.subtract(twoDiamondBig);
					threeDiamondIncome = order.getTotalAmount().multiply(temp);
					
					saveMemberTeamIncome(threeDiamond, member.getNickname(), order, threeDiamondIncome);
					
				}
				
				
			} else {
				//如果中级不存在，高级拿差额6%
				threeDiamond = recursionFindAllParent(member, MemberLevel.ThreeDiamond);
				if(threeDiamond != null) {
					temp = threeDiamondBig.subtract(oneDiamondBig);
					threeDiamondIncome = order.getTotalAmount().multiply(temp);
					
					saveMemberTeamIncome(threeDiamond, member.getNickname(), order, threeDiamondIncome);
				}
				
			}
			
			//------------------自己 end------
		} else {
			
			//------------------上级start------
			//自己没有达到计算团队收益的等级，向上找到第一个达到初级或者中级或者高级的人
			UmsMember parent = recursionFindAllParent(member);
			if(parent != null) {
				
				////如果上级是高级，不再向上算差额，高级直接拿16%
				if(MemberLevel.ThreeDiamond.equals(parent.getMemberLevel())) {
					//高级全额16%
					threeDiamondIncome = order.getTotalAmount().multiply(threeDiamondBig);
					
					saveMemberTeamIncome(parent, member.getNickname(), order, threeDiamondIncome);
				} else if(MemberLevel.TwoDiamond.equals(parent.getMemberLevel())) {
					//如果上级是中级，向上计算高级的差额
					//中级全额14%
					twoDiamondIncome = order.getTotalAmount().multiply(twoDiamondBig);
					
					saveMemberTeamIncome(parent, member.getNickname(), order, twoDiamondIncome);
					
					//向上查找第一个高级
					threeDiamond = recursionFindAllParent(member, MemberLevel.ThreeDiamond);
					if(threeDiamond != null) {
						//高级拿差额2%
						temp = threeDiamondBig.subtract(twoDiamondBig);
						threeDiamondIncome = order.getTotalAmount().multiply(temp);
						
						saveMemberTeamIncome(threeDiamond, member.getNickname(), order, threeDiamondIncome);
						
					}
					
					
				} else if(MemberLevel.OneDiamond.equals(parent.getMemberLevel())) {
					//如果自己是初级，向上计算中级的差额和高级的差额
					//初级拿全额10%
					oneDiamondIncome = order.getTotalAmount().multiply(oneDiamondBig);
					
					saveMemberTeamIncome(parent, member.getNickname(), order, oneDiamondIncome);
					
					//中级拿差额4%
					twoDiamond = recursionFindAllParent(member, MemberLevel.TwoDiamond);
					if(twoDiamond != null) {
						temp = twoDiamondBig.subtract(oneDiamondBig);
						twoDiamondIncome = order.getTotalAmount().multiply(temp);
						
						saveMemberTeamIncome(twoDiamond, member.getNickname(), order, twoDiamondIncome);
						
						threeDiamond = recursionFindAllParent(member, MemberLevel.ThreeDiamond);
						if(threeDiamond != null) {
							//高级拿差额2%
							temp = threeDiamondBig.subtract(twoDiamondBig);
							threeDiamondIncome = order.getTotalAmount().multiply(temp);
							
							saveMemberTeamIncome(threeDiamond, member.getNickname(), order, threeDiamondIncome);
							
						}
						
						
					} else {
						//如果中级不存在，高级拿差额6%
						threeDiamond = recursionFindAllParent(member, MemberLevel.ThreeDiamond);
						if(threeDiamond != null) {
							temp = threeDiamondBig.subtract(oneDiamondBig);
							threeDiamondIncome = order.getTotalAmount().multiply(temp);
							
							saveMemberTeamIncome(threeDiamond, member.getNickname(), order, threeDiamondIncome);
						}
						
					}
				} 
				
			}
			
			//------------------上级end------
			
		}
		
		
	}
	
	private void saveMemberTeamIncome(UmsMember parent, String buyerNickname, OmsOrder order, BigDecimal teamIncome) {
		while(true) {
			long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
			if(redisLock.lock(String.valueOf(parent.getId()), String.valueOf(time))) {
				parent = memberMapper.selectByPrimaryKey(parent.getId());
				
				//记录会员账户交易记录表
				insertMemberTradeRecord(parent.getId(), ItemType.TeamServiceCharge, 0, teamIncome, 
						"获得团队服务劳务费", "会员[" + buyerNickname + "]购买商品", order.getMemberId(), order.getId());
				
				//会员总收入表
				insertMemberTotalIncome(parent.getId(), ItemType.TeamServiceCharge, teamIncome);
				
				//会员积分账户变更
				parent.setBalance(parent.getBalance().add(teamIncome));
				memberMapper.updateByPrimaryKey(parent);
				
				redisLock.unlock(String.valueOf(parent.getId()), String.valueOf(time));
				break;
			}
		}
	}
	
	//递归找到第一个达到初级或者中级或者高级的人
	private UmsMember recursionFindAllParent(UmsMember member) {
		DmsTeamLevel teamLevel = teamLevelMapper.selectOneByMemberId(member.getId());
		if(teamLevel == null) {
			return null;
		}
		
		UmsMember parent = memberMapper.selectByPrimaryKey(teamLevel.getParentId());
		
		//判断上级是否满足条件，如果满足就返回，不满足继续递归
		if(MemberLevel.OneDiamond.equals(parent.getMemberLevel())
				|| MemberLevel.TwoDiamond.equals(parent.getMemberLevel())
				|| MemberLevel.ThreeDiamond.equals(parent.getMemberLevel())) {
			return parent;
		} else {
			return recursionFindAllParent(parent);
		}
		
	}
	
	/*
	public void computeTeamIncome(Long memberId, OmsOrder order) {
		
		UmsMember member = memberMapper.selectByPrimaryKey(memberId);
		
		LOGGER.info("computeTeamIncome start: {}", member.getUsername());
		LOGGER.info("computeTeamIncome memberId: {}, orderId: {}, totalAmout: {}", member.getId(), order.getId(), order.getTotalAmount());
		
		UmsMember oneDiamond = recursionFindAllParent(member, MemberLevel.OneDiamond);
		UmsMember twoDiamond = recursionFindAllParent(member, MemberLevel.TwoDiamond);
		UmsMember threeDiamond = recursionFindAllParent(member, MemberLevel.ThreeDiamond);
		
		double oneDiamondPercent = Double.valueOf(commonService.getDictionaryValue(Constants.D_ONE_DIAMOND_TEAM_INCOME)) / 100;
		double twoDiamondPercent = Double.valueOf(commonService.getDictionaryValue(Constants.D_TWO_DIAMOND_TEAM_INCOME)) / 100;
		double threeDiamondPercent = Double.valueOf(commonService.getDictionaryValue(Constants.D_THREE_DIAMOND_TEAM_INCOME)) / 100;
		BigDecimal oneDiamondBig = new BigDecimal(oneDiamondPercent);
		BigDecimal twoDiamondBig = new BigDecimal(twoDiamondPercent);
		BigDecimal threeDiamondBig = new BigDecimal(threeDiamondPercent);
		BigDecimal oneDiamondIncome = null;
		BigDecimal twoDiamondIncome = null;
		BigDecimal threeDiamondIncome = null;
		BigDecimal temp = null;
		
		if(oneDiamond != null) {
			//初级合作商永远拿全额10%
			oneDiamondIncome = order.getTotalAmount().multiply(oneDiamondBig);
			
			while(true) {
				long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
				if(redisLock.lock(String.valueOf(oneDiamond.getId()), String.valueOf(time))) {
					oneDiamond = memberMapper.selectByPrimaryKey(oneDiamond.getId());
					
					//记录会员账户交易记录表
					insertMemberTradeRecord(oneDiamond.getId(), ItemType.TeamServiceCharge, 0, oneDiamondIncome, 
							"获得团队服务劳务费", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());
					
					//会员总收入表
					insertMemberTotalIncome(oneDiamond.getId(), ItemType.TeamServiceCharge, oneDiamondIncome);
					
					//会员积分账户变更
					oneDiamond.setBalance(oneDiamond.getBalance().add(oneDiamondIncome));
					memberMapper.updateByPrimaryKey(oneDiamond);
					
					redisLock.unlock(String.valueOf(oneDiamond.getId()), String.valueOf(time));
					break;
				}
			}
			
			if(twoDiamond != null) {
				//中级拿差额4%
				temp = twoDiamondBig.subtract(oneDiamondBig);
				twoDiamondIncome = order.getTotalAmount().multiply(temp);
				
				while(true) {
					long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
					if(redisLock.lock(String.valueOf(twoDiamond.getId()), String.valueOf(time))) {
						twoDiamond = memberMapper.selectByPrimaryKey(twoDiamond.getId());
						
						//记录会员账户交易记录表
						insertMemberTradeRecord(twoDiamond.getId(), ItemType.TeamServiceCharge, 0, twoDiamondIncome, 
								"获得团队服务劳务费", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());
						
						//会员总收入表
						insertMemberTotalIncome(twoDiamond.getId(), ItemType.TeamServiceCharge, twoDiamondIncome);
						
						//会员积分账户变更
						twoDiamond.setBalance(twoDiamond.getBalance().add(twoDiamondIncome));
						memberMapper.updateByPrimaryKey(twoDiamond);
						
						redisLock.unlock(String.valueOf(twoDiamond.getId()), String.valueOf(time));
						break;
					}
				}
				
				if(threeDiamond != null) {
					//高级拿差额2%
					temp = threeDiamondBig.subtract(twoDiamondBig);
					threeDiamondIncome = order.getTotalAmount().multiply(temp);
					
					while(true) {
						long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
						if(redisLock.lock(String.valueOf(threeDiamond.getId()), String.valueOf(time))) {
							threeDiamond = memberMapper.selectByPrimaryKey(threeDiamond.getId());
							
							//记录会员账户交易记录表
							insertMemberTradeRecord(threeDiamond.getId(), ItemType.TeamServiceCharge, 0, threeDiamondIncome, 
									"获得团队服务劳务费", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());
							
							//会员总收入表
							insertMemberTotalIncome(threeDiamond.getId(), ItemType.TeamServiceCharge, threeDiamondIncome);
							
							//会员积分账户变更
							threeDiamond.setBalance(threeDiamond.getBalance().add(threeDiamondIncome));
							memberMapper.updateByPrimaryKey(threeDiamond);
							
							redisLock.unlock(String.valueOf(threeDiamond.getId()), String.valueOf(time));
							break;
						}
					}
					
				}
			} else {
				if(threeDiamond != null) {
					//高级拿差额6%
					temp = threeDiamondBig.subtract(oneDiamondBig);
					threeDiamondIncome = order.getTotalAmount().multiply(temp);
					
					while(true) {
						long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
						if(redisLock.lock(String.valueOf(threeDiamond.getId()), String.valueOf(time))) {
							threeDiamond = memberMapper.selectByPrimaryKey(threeDiamond.getId());
							
							//记录会员账户交易记录表
							insertMemberTradeRecord(threeDiamond.getId(), ItemType.TeamServiceCharge, 0, threeDiamondIncome, 
									"获得团队服务劳务费", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());
							
							//会员总收入表
							insertMemberTotalIncome(threeDiamond.getId(), ItemType.TeamServiceCharge, threeDiamondIncome);
							
							//会员积分账户变更
							threeDiamond.setBalance(threeDiamond.getBalance().add(threeDiamondIncome));
							memberMapper.updateByPrimaryKey(threeDiamond);
							
							redisLock.unlock(String.valueOf(threeDiamond.getId()), String.valueOf(time));
							break;
						}
					}
					
				}
			}
			
		} else if(twoDiamond != null) {
			//中级全额14%
			twoDiamondIncome = order.getTotalAmount().multiply(twoDiamondBig);
			
			while(true) {
				long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
				if(redisLock.lock(String.valueOf(twoDiamond.getId()), String.valueOf(time))) {
					twoDiamond = memberMapper.selectByPrimaryKey(twoDiamond.getId());
					
					//记录会员账户交易记录表
					insertMemberTradeRecord(twoDiamond.getId(), ItemType.TeamServiceCharge, 0, twoDiamondIncome, 
							"获得团队服务劳务费", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());

					//会员总收入表
					insertMemberTotalIncome(twoDiamond.getId(), ItemType.TeamServiceCharge, twoDiamondIncome);
					
					//会员积分账户变更
					twoDiamond.setBalance(twoDiamond.getBalance().add(twoDiamondIncome));
					memberMapper.updateByPrimaryKey(twoDiamond);
					
					redisLock.unlock(String.valueOf(twoDiamond.getId()), String.valueOf(time));
					break;
				}
			}
			
			if(threeDiamond != null) {
				//高级拿差额2%
				temp = threeDiamondBig.subtract(twoDiamondBig);
				threeDiamondIncome = order.getTotalAmount().multiply(temp);
				
				while(true) {
					long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
					if(redisLock.lock(String.valueOf(threeDiamond.getId()), String.valueOf(time))) {
						threeDiamond = memberMapper.selectByPrimaryKey(threeDiamond.getId());
						
						//记录会员账户交易记录表
						insertMemberTradeRecord(threeDiamond.getId(), ItemType.TeamServiceCharge, 0, threeDiamondIncome, 
								"获得团队服务劳务费", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());
						
						//会员总收入表
						insertMemberTotalIncome(threeDiamond.getId(), ItemType.TeamServiceCharge, threeDiamondIncome);
						
						//会员积分账户变更
						threeDiamond.setBalance(threeDiamond.getBalance().add(threeDiamondIncome));
						memberMapper.updateByPrimaryKey(threeDiamond);
						
						redisLock.unlock(String.valueOf(threeDiamond.getId()), String.valueOf(time));
						break;
					}
				}
				
			}
			
		} else if(threeDiamond != null) {
			//高级全额16%
			threeDiamondIncome = order.getTotalAmount().multiply(threeDiamondBig);
				
			while(true) {
				long time = System.currentTimeMillis() + RedisLock.TIMEOUT;
				if(redisLock.lock(String.valueOf(threeDiamond.getId()), String.valueOf(time))) {
					threeDiamond = memberMapper.selectByPrimaryKey(threeDiamond.getId());
					
					//记录会员账户交易记录表
					insertMemberTradeRecord(threeDiamond.getId(), ItemType.TeamServiceCharge, 0, threeDiamondIncome, 
							"获得团队服务劳务费", "会员[" + member.getNickname() + "]购买商品", order.getMemberId(), order.getId());
					
					//会员总收入表
					insertMemberTotalIncome(threeDiamond.getId(), ItemType.TeamServiceCharge, threeDiamondIncome);
					
					//会员积分账户变更
					threeDiamond.setBalance(threeDiamond.getBalance().add(threeDiamondIncome));
					memberMapper.updateByPrimaryKey(threeDiamond);
					
					redisLock.unlock(String.valueOf(threeDiamond.getId()), String.valueOf(time));
					break;
				}
			}
				
		}
		
		
		LOGGER.info("computeTeamIncome end: {}", member.getUsername());
	}
	*/
	
	/**
	 * 递归向下查询是否有满足条件的数据
	 * @param memberId
	 * @param level
	 * @return
	 */
	private boolean recursionLevelPartner(Long memberId, int level) {
		//先判断自己是否满足条件，如果不满足，再依次递归下级
		UmsMember member = memberMapper.selectByPrimaryKey(memberId);
		if(member.getMemberLevel().getValue() >= level) {
			return true;
		}
		
		//找不到下级结束递归
		List<DmsTeamLevel> teamLevelList = teamLevelMapper.selectByParentId(member.getId());
		if(teamLevelList.isEmpty()) {
			return false;
		}
		
		for(DmsTeamLevel teamLevel : teamLevelList) {
			return recursionLevelPartner(teamLevel.getMemberId(), level);
		}
		
		return false;
	}
	
	/**
	 * 计算会员升级条件
	 * @param teamLevelList
	 * @param level
	 * @param conditionNum
	 * @return
	 */
	private boolean computePartnerUpgradeCondition(List<DmsTeamLevel> teamLevelList, int level, int conditionNum) {
		UmsMember lower = null;
		int partnerNum = 0;
		for(DmsTeamLevel teamLevel : teamLevelList) {
			lower = memberMapper.selectByPrimaryKey(teamLevel.getMemberId());
			if(lower.getMemberLevel().getValue() >= level) {
				partnerNum += 1;
			}
		}
		//先判断直接下级是否满足条件，如果不满足再递归查询
		if(partnerNum >= conditionNum) {
			return true;
		}
		
		/*
		//需求变动，必须是直接下级，所以不再递归
		//递归查询每一条线是否有合伙人
		partnerNum = 0;
		for(DmsTeamLevel teamLevel : teamLevelList) {
			boolean temp = recursionLevelPartner(teamLevel.getMemberId(), level);
			if(temp) {
				partnerNum += 1;
			}
		}
		
		//第二次计算满足
		if(partnerNum >= conditionNum) {
			return true;
		}
		*/
		
		return false;
	}
	
	/**
	 * 写入会员总收入表
	 * @param memberId
	 * @param itemType
	 * @param value
	 */
	private void insertMemberTotalIncome(Long memberId, ItemType itemType, BigDecimal value) {
		DmsMemberTotalIncome totalIncome = memberTotalIncomeMapper.selectOneByMemberIdAndItemType(memberId, itemType.getValue());
		if(totalIncome == null) {
			totalIncome = new DmsMemberTotalIncome();
			totalIncome.setMemberId(memberId);
			totalIncome.setItemType(itemType);
			totalIncome.setValue(value);
			memberTotalIncomeMapper.insert(totalIncome);
		} else {
			value = totalIncome.getValue().add(value);
			totalIncome.setValue(value);
			memberTotalIncomeMapper.updateById(totalIncome);
		}
	}
	
	/**
	 * @param memberId 会员ID
	 * @param itemType 项目类型
	 * @param type 收支类型（0->收入；1->支出）
	 * @param value 值
	 * @param title 标题
	 * @param note 备注
	 * @param customerId 消费者会员ID
	 * @param orderId 订单ID
	 */
	private void insertMemberTradeRecord(Long memberId, ItemType itemType, int type, BigDecimal value, 
			String title, String note, Long customerId, Long orderId) {
		DmsMemberTradeRecord tradeRecord = new DmsMemberTradeRecord();
		tradeRecord.setMemberId(memberId);
		tradeRecord.setItemType(itemType);
		tradeRecord.setType(type); 
		tradeRecord.setValue(value);
		tradeRecord.setTitle(title);
		tradeRecord.setNote(note);
		tradeRecord.setCustomerId(customerId);
		tradeRecord.setOrderId(orderId);
		tradeRecord.setCreateTime(new Date());
		memberTradeRecordMapper.insert(tradeRecord);
	}
	
	/**
	 * 递归向上查询最近的一家店，计算店补时用到
	 * @param memberId
	 * @return
	 */
	private UmsMember recursionFindStore(UmsMember member) {
		if(StoreStatus.Yes.equals(member.getStoreStatus())) {
			return member;
		}
		
		//查询直接推荐人信息
		DmsTeamLevel teamLevel = teamLevelMapper.selectOneByMemberId(member.getId());
		if(teamLevel != null) {
			return recursionFindStore(memberMapper.selectByPrimaryKey(teamLevel.getParentId()));
		}
		
		return null;
	}
	
	/**
	 * 递归向上查找所有上级
	 * @param memberId
	 * @return
	 */
	private UmsMember recursionFindAllParent(UmsMember member, MemberLevel memberLevel) {
		DmsTeamLevel teamLevel = teamLevelMapper.selectOneByMemberId(member.getId());
		if(teamLevel == null) {
			return null;
		}
		
		UmsMember parent = memberMapper.selectByPrimaryKey(teamLevel.getParentId());
		
		//判断上级是否满足条件，如果满足就返回，不满足继续递归
		if(parent.getMemberLevel().equals(memberLevel)) {
			return parent;
		} else {
			return recursionFindAllParent(parent, memberLevel);
		}
		
	}
	
	/**
	 * 重新计算团队累计消费
	 * @param member
	 * @param order
	 */
	public void computeTeamTotalConsume(Long memberId, OmsOrder order) {
		recursionUpdateUpTeamTotalConsume(memberId, order.getTotalAmount());
	}
	
	/**
	 * 递归重新计算团队累计消费
	 * @param memberId
	 * @param value
	 */
	private void recursionUpdateUpTeamTotalConsume(Long memberId, BigDecimal value) {
		DmsTeamLevel teamLevel = teamLevelMapper.selectOneByMemberId(memberId);
		if(teamLevel == null) {
			return;
		} else {
			DmsTeamTotalConsume teamTotalConsume = teamTotalConsumeMapper.selectOneByMemberId(teamLevel.getParentId());
			teamTotalConsume.setValue(teamTotalConsume.getValue().add(value));
			teamTotalConsumeMapper.updateById(teamTotalConsume);
			recursionUpdateUpTeamTotalConsume(teamLevel.getParentId(), value);
		}
		
	}

}
