using Domain.Entities.Members.ValueObject;

namespace Domain.Entities.Members;

/// <summary>
/// 일일 보상 캡 원장 (d3 §③). 복합 PK (MemberID, RewardDate[KST 기준일], ActionType).
/// 액션별 오늘 지급된 횟수/경험치/포인트를 누적하며 RewardService 가 UPSERT(원자적 UPDATE 우선)로 갱신한다.
/// Redis 아닌 DB 로 두어 감사 가능·재시작 안전을 확보한다.
/// </summary>
public class MemberDailyRewardCounter
{
    public int MemberID { get; private set; }

    /// <summary>KST 기준 일자 (date). 일 경계로 캡을 리셋한다.</summary>
    public DateOnly RewardDate { get; private set; }

    public RewardActionType ActionType { get; private set; }

    /// <summary>오늘 이 액션으로 지급된 횟수</summary>
    public int Count { get; private set; }

    /// <summary>오늘 이 액션으로 지급된 경험치 합계</summary>
    public int ExpTotal { get; private set; }

    /// <summary>오늘 이 액션으로 지급된 포인트(토큰) 합계</summary>
    public int PointTotal { get; private set; }

    private MemberDailyRewardCounter() { }

    private MemberDailyRewardCounter(int memberID, DateOnly rewardDate, RewardActionType actionType)
    {
        if (memberID <= 0)
        {
            throw new ArgumentOutOfRangeException(nameof(memberID));
        }

        MemberID = memberID;
        RewardDate = rewardDate;
        ActionType = actionType;
    }

    public static MemberDailyRewardCounter Create(int memberID, DateOnly rewardDate, RewardActionType actionType)
    {
        return new(memberID, rewardDate, actionType);
    }

    /// <summary>지급분을 누적한다 (신규 row 생성 후 첫 지급 반영용).</summary>
    public void Add(int expDelta, int pointDelta)
    {
        Count++;
        ExpTotal += expDelta;
        PointTotal += pointDelta;
    }
}
