package com.apobates.forum.member;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.apobates.forum.member.entity.ForumScoreRole;
import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.event.elderly.ForumActionEnum;
import com.apobates.forum.member.MemberProfileBean.MemberProfileBuilder;
import com.apobates.forum.member.entity.MemberLevel;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.utils.CommonDoubleBean;
import com.apobates.forum.utils.DoubleBeanFormatter;
/**
 * 会员个人信息处理类
 * 
 * @author xiaofanku
 * @since 20190412
 *
 */
public class MemberProfile {
	private final List<MemberProfileBuilder> data;
	private final static Logger logger = LoggerFactory.getLogger(MemberProfile.class);
	
	private MemberProfile(List<MemberProfileBuilder> data){
		this.data = Collections.unmodifiableList(data);
	}
	
	public static MemberProfile init(long memberId, String memberNickname, MemberGroupEnum memberGroup, MemberRoleEnum memberRole, String label, String signature){
		return new MemberProfile(
				Arrays.asList(
						new MemberProfileBuilder(
								memberId, 
								memberNickname,
								memberGroup.getTitle(), 
								memberRole.getTitle(), 
								label, 
								signature)));
	}
	
	public static MemberProfile init(List<MemberBaseProfile> beans){
		List<MemberProfileBuilder> data = new ArrayList<>();
		for(MemberBaseProfile cb : beans){
			data.add(
					new MemberProfileBuilder(
							cb.getId(), 
							cb.getNickname(),
							cb.getGroupName(), 
							cb.getRoleName(), 
							cb.getLabel(), 
							cb.getSignature()));
		}
		return new MemberProfile(data);
	}
	//多个中改一个呢?
	/**
	 * 计算某会员的积分
	 * @param memberId
	 * @param statsdata
	 * @param scoreRoleSet
	 * @return
	 */
	public Optional<MemberProfile> calcMemberScore(long memberId, Map<ForumActionEnum, Long> statsdata, List<ForumScoreRole> scoreRoleSet){
		if(!isContinue()){
			logger.info("[MP][calcMemberScore]缺少必要的属性: data");
			return Optional.empty();
		}
		MemberProfileBuilder b = null;
		List<MemberProfileBuilder> rs = new ArrayList<>();
		for(MemberProfileBuilder mpb : data){
			if(mpb.getId() != memberId){
				rs.add(mpb);
			}
			if(mpb.getId() == memberId){
				b = mpb;
			}
		}
		if(b!=null){
			rs.add(fill(b, statsdata, scoreRoleSet));
		}
		
		return Optional.of(new MemberProfile(rs));
	}
	/**
	 * 计算会员的积分
	 * @param rawdata
	 * @param scoreRoleSet
	 * @return
	 */
	public Optional<MemberProfile> calcMemberScore(Map<Long, Map<ForumActionEnum, Long>> rawdata, List<ForumScoreRole> scoreRoleSet){
		if(!isContinue()){
			logger.info("[MP][calcMemberScore][Map]缺少必要的属性: data");
			return Optional.empty();
		}
		List<MemberProfileBuilder> rs = new ArrayList<>();
		for(MemberProfileBuilder mpb : data){
			if(rawdata.containsKey(mpb.getId())){
				rs.add(fill(mpb, rawdata.get(mpb.getId()), scoreRoleSet));
			}else{
				rs.add(mpb);
			}
		}
		
		return Optional.of(new MemberProfile(rs));
	}
	
	private MemberProfileBuilder fill(MemberProfileBuilder source, Map<ForumActionEnum, Long> statsdata, List<ForumScoreRole> scoreRoleSet){
		if(source == null){
			return null;
		}
		MemberProfileBuilder newMpb = new MemberProfileBuilder(source.getId(), source.getNickname(), source.getGroupNames(), source.getRoleNames(), source.getLabel(), source.getSignature());
		double sv = getMemberScore(statsdata, scoreRoleSet);
		logger.info("[bean]mid: "+newMpb.getId()+", score: "+sv);
		newMpb.setScore(sv);
		try {
			newMpb.setReplies(statsdata.get(ForumActionEnum.POSTS_REPLY));
		} catch (NullPointerException e) {}
		try {
			newMpb.setThreads(statsdata.get(ForumActionEnum.TOPIC_PUBLISH));
		} catch (NullPointerException e) {}
		newMpb.setLevel(source.getLevel(), source.getLevelNo());
		return newMpb;
	}
	/**
	 * 计算会员的等级
	 * @param levelDefines
	 * @return
	 */
	public Optional<MemberProfile> calcMemberLevel(List<CommonDoubleBean> levelDefines){
		if(!isContinue()){
			logger.info("[MP][calcMemberLevel][List]缺少必要的属性: data");
			return Optional.empty();
		}
		List<MemberProfileBuilder> rs = new ArrayList<>();
		for(MemberProfileBuilder mpb : data){
			//logger.info("[Lbean]mid: "+mpb.getId()+", score: "+mpb.getScore());
			MemberLevel l = (mpb.getScore() >= 0)?queryLevel(mpb.getScore(), levelDefines):MemberLevel.empty();
			logger.info("[Lbean]mid: "+mpb.getId()+", score: "+mpb.getScore()+", level: "+l.getNames());
			rs.add(mpb.setLevel(l.getNames(), l.getId()));
		}
		return Optional.of(new MemberProfile(rs));
	}
	
	public boolean isContinue(){
		return data!=null && !data.isEmpty();
	}
	
	public Optional<MemberProfileBean> toResultBean(){
		if(!isContinue()){
			logger.info("[MP][toResultBean]缺少必要的属性: data");
			return Optional.empty();
		}
		MemberProfileBean rs = data.stream().filter(Objects::nonNull).findFirst().map(mb -> mb.build()).orElseGet(null);
		return Optional.ofNullable(rs);
	}
	
	public MemberProfileBean toProfileBean(){
		if(!isContinue()){
			return null;
		}
		MemberProfileBean rs = data.stream().filter(Objects::nonNull).findFirst().map(mb -> mb.build()).orElseGet(null);
		return rs;
	}
	
	public List<MemberProfileBean> toBeanList(){
		if(!isContinue()){
			logger.info("[MP][toBeanList]缺少必要的属性: data");
			return Collections.emptyList();
		}
		return data.stream().filter(Objects::nonNull).map(mb -> mb.build()).collect(Collectors.toList());
	}
	
	/**
	 * 计算积分的方法
	 * 
	 * @param actionStatsData 会员操作统计汇总
	 * @param scoreroles      积分规则
	 * @return
	 */
	public static double getMemberScore(Map<ForumActionEnum, Long> actionStatsData, List<ForumScoreRole> scoreroles) {
		double data = 0;
		for (ForumScoreRole fsr : scoreroles) {
			ForumActionEnum action = fsr.getAction();
			Long operateSize = 0L;
			try {
				operateSize = actionStatsData.get(action);
			} catch (NullPointerException e) {
				continue;
			}
			// 积分和次频
			if (operateSize != null && operateSize > 0 && fsr.getScore() != 0 && fsr.getDegree() >= 1) {
				data += operateSize / fsr.getDegree() * fsr.getScore();
			}
		}
		return data;
	}

	/**
	 * 
	 * 
	 * @param scoreValue         得分值
	 * @param levelScoreDefined  等级定义
	 * @return
	 */
	public static MemberLevel queryLevel(double scoreValue, List<CommonDoubleBean> levelScoreDefined){
		String levelName = new DoubleBeanFormatter(levelScoreDefined).format(scoreValue);
		//从定义中找到是几级
		Optional<CommonDoubleBean> result = levelScoreDefined.stream().filter(cdb -> cdb.getTitle().equals(levelName)).findAny();
		MemberLevel data = new MemberLevel();
		data.setId(result.orElse(CommonDoubleBean.empty()).getId());
		data.setNames(levelName);
		data.setScore(scoreValue);
		data.setStatus(true);
		return data;
	}
}
