package com.jeesharp.business.modules.member.application.support;

import com.jeesharp.business.modules.member.entity.Member;
import com.jeesharp.business.modules.member.entity.MemberLevel;
import com.jeesharp.business.modules.member.entity.MemberPointsRule;
import com.jeesharp.business.modules.member.entity.MemberPointsRuleLevel;
import com.jeesharp.business.modules.member.enums.MemberPointsCalcTypeEnum;
import com.jeesharp.business.modules.member.enums.MemberPointsSceneEnum;
import com.jeesharp.business.modules.member.enums.MemberSignInStreakBonusEnum;
import com.jeesharp.business.modules.member.service.MemberLevelService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;

/**
 * 签到场景积分计算器：基础分 × 等级倍率 + 连签里程碑奖励。
 *
 * @author jeesharp
 * @since 2026-06-23
 */
@Component
@AllArgsConstructor
public class SignInMemberPointsSceneHandler implements MemberPointsSceneHandler {

    private final MemberLevelService memberLevelService;

    @Override
    public String sceneCode() {
        return MemberPointsSceneEnum.SIGN_IN.getCode();
    }

    @Override
    public int calculate(Member member, MemberPointsRule rule, MemberPointsRuleLevel levelDetail, Map<String, Object> context) {
        int base = rule.getBasePoints() != null ? rule.getBasePoints() : 0;
        BigDecimal levelRate = resolveLevelRate(member);
        BigDecimal extra = levelDetail != null && levelDetail.getExtraMultiplier() != null
                ? levelDetail.getExtraMultiplier() : BigDecimal.ONE;
        int baseWithRate = BigDecimal.valueOf(base).multiply(levelRate).multiply(extra)
                .setScale(0, RoundingMode.FLOOR).intValue();

        Integer continuousDays = null;
        if (context != null && context.get("continuousDays") != null) {
            Object v = context.get("continuousDays");
            if (v instanceof Number n) {
                continuousDays = n.intValue();
            }
        }
        int streakBonus = MemberSignInStreakBonusEnum.resolveBonusPoints(continuousDays);
        return Math.max(0, baseWithRate + streakBonus);
    }

    private BigDecimal resolveLevelRate(Member member) {
        MemberLevel level = resolveMemberLevel(member);
        if (level != null && level.getPointsRate() != null) {
            return level.getPointsRate();
        }
        return BigDecimal.ONE;
    }

    private MemberLevel resolveMemberLevel(Member member) {
        if (member.getLevelId() != null) {
            MemberLevel byId = memberLevelService.get(member.getLevelId());
            if (byId != null) {
                return byId;
            }
        }
        if (member.getLevelCode() != null) {
            return memberLevelService.getByLevelCode(member.getLevelCode());
        }
        return memberLevelService.getByLevelCode("NORMAL");
    }
}
