package com.iformall.utils;

import com.iformall.domain.po.*;
import com.iformall.mapper.WxLevelConfigMapper;
import com.iformall.service.WxScoreRulesService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.util.Objects;

@Slf4j
public class CreditUtil {

	private static ThreadLocal<Long> isBirthDayScale = new ThreadLocal<>();

	/**
	 * 计算用户积分
	 *
	 * @param creditOrigin        原始积分
	 * @param wxCUser             C端用户信息
	 * @param wxCUserBasicInfo    C端用户信息
	 * @param wxScoreRulesService
	 * @param wxLevelConfigMapper
	 * @return
	 */
	public static int calUserCredit(int creditOrigin, WxCUser wxCUser, WxCUserBasicInfo wxCUserBasicInfo, WxScoreRulesService wxScoreRulesService, WxLevelConfigMapper wxLevelConfigMapper) {
		Long userId = null;
		Integer score = null;
		String tenantId = null;
		Integer levelScaleConfig = WxLevelConfig.DEFAULT_SCALE ;
		if (Objects.nonNull(wxCUser)) {
			userId = wxCUser.getId();
			score = wxCUser.getScore();
			tenantId = wxCUser.getTenantId();
		}
		if (Objects.isNull(userId)) {
			userId = wxCUserBasicInfo.getId();
		}

		if (Objects.isNull(score)) {
			score = wxCUserBasicInfo.getPoins();
		}

		if (StringUtils.isBlank(tenantId)) {
			tenantId = wxCUserBasicInfo.getTenantId();
		}
		levelScaleConfig = wxLevelConfigMapper.getScale(tenantId, score) ;
		// 获取等级积分倍率，
		int levelScale = getLevelScale(score, levelScaleConfig);

		// 获取生日积分倍率:
		int birthdayScale = getBirthdayScale(wxCUserBasicInfo, wxScoreRulesService);

		int creditNew = new BigDecimal(creditOrigin)
				.multiply(new BigDecimal(levelScale))
				.multiply(new BigDecimal(birthdayScale))
				.divide(new BigDecimal(WxScoreRules.DEFAULT_SCALE))
				.divide(new BigDecimal(WxLevelConfig.DEFAULT_SCALE)
						, BigDecimal.ROUND_HALF_UP).intValue();

		log.info("积分倍率计算, 用户:{},成长值:{}，等级积分倍率:{},生日积分倍率:{},原积分:{},新积分:{}", userId, score, levelScale, birthdayScale, creditOrigin, creditNew);
		return creditNew;
	}

	/**
	 * 根据会员信息获取等级积分倍率
	 *
	 * @param levelScaleConfig
	 * @return
	 */
	private static int getLevelScale(Integer score, Integer levelScaleConfig) {
		int levelScale = WxLevelConfig.DEFAULT_SCALE;

		//积分不为空时进行计算
		if (Objects.nonNull(score)) {
			//等级积分配置存在时进行计算
			if (Objects.nonNull(levelScaleConfig)) {
				levelScale = levelScaleConfig;
			} else {
				//log.info("积分倍率计算：等级积分倍率配置=null");
			}
		}
		log.info("积分倍率计算：会员等级积分倍率配置={}", levelScale);
		return levelScale;
	}

	/**
	 * 根据会员信息获取倍率
	 *
	 * @param wxCUserBasicInfo
	 * @param wxScoreRulesService
	 * @return
	 */
	private static int getBirthdayScale(WxCUserBasicInfo wxCUserBasicInfo, WxScoreRulesService wxScoreRulesService) {
		int birthdayScale = WxScoreRules.DEFAULT_SCALE;
		if (Objects.isNull(wxCUserBasicInfo) || StringUtils.isBlank(wxCUserBasicInfo.getPhone())) {
			return 0;
		}
		//判断是否生日当天,一年一天有效
		//没有发过生日券的用户或者没有享受过生日积分倍率的用户
		if(Objects.isNull(wxCUserBasicInfo.getScoreDate())) {
			//设置过生日的用户
			if (Objects.nonNull(wxCUserBasicInfo.getBirthdate()) && DateUtils.birthdaysBetween(wxCUserBasicInfo.getBirthdate()) == 0) {
				birthdayScale = getBirthdayScoreScale(wxCUserBasicInfo.getTenantId(), wxScoreRulesService);
			} else {
				log.info("积分倍率计算：未设置生日或生日条件未匹配={}", wxCUserBasicInfo.getScoreDate());
			}
		} else {
			//发过生日券的用户或者享受过生日积分倍率的用户
			if (Objects.nonNull(wxCUserBasicInfo.getScoreDate()) && DateUtils.birthdaysBetween(wxCUserBasicInfo.getScoreDate()) == 0) {
				birthdayScale = getBirthdayScoreScale(wxCUserBasicInfo.getTenantId(), wxScoreRulesService);
			}
		}

		//配置了生日积分倍率，保存到上下文
		if (!Objects.equals(birthdayScale, WxScoreRules.DEFAULT_SCALE)) {
			isBirthDayScale.set(wxCUserBasicInfo.getId());
		}
		return birthdayScale;
	}

	/**
	 * 获取生日积分倍率
	 *
	 * @param tenantId
	 * @param wxScoreRulesService
	 * @return
	 */
	public static int getBirthdayScoreScale(String tenantId, WxScoreRulesService wxScoreRulesService) {
		int birthdayScale = WxScoreRules.DEFAULT_SCALE;
		WxScoreRules rules = wxScoreRulesService.getCreditRules(tenantId);
		if (Objects.nonNull(rules) && Objects.nonNull(rules.getScale())) {
			//规则存使用积分倍率
			birthdayScale = rules.getScale();
		} else {
			//没有配置积分规则
			//log.info("积分倍率计算：会员生日积分倍率配置=null");
		}
		log.info("会员生日积分倍率配置：{}", birthdayScale);
		return birthdayScale;
	}

	public static Long getIsBirthDayScale() {
		return isBirthDayScale.get();
	}

	public static void clear() {
		CreditUtil.isBirthDayScale.remove();
	}
}
