namespace MissionService.Domain.AggregatesModel.TaskAggregate;

using MissionService.Domain.SeedWork;

/// <summary>
/// EN: User task aggregate root - tracks a user's progress on a mission
/// VI: UserTask aggregate root - theo dõi tiến độ của user trên một mission
/// </summary>
public class UserTask : Entity, IAggregateRoot
{
    /// <summary>EN: User ID / VI: ID người dùng</summary>
    public Guid UserId { get; private set; }
    
    /// <summary>EN: Mission ID / VI: ID nhiệm vụ</summary>
    public Guid MissionId { get; private set; }
    
    /// <summary>EN: Current task status / VI: Trạng thái task hiện tại</summary>
    public TaskStatus Status { get; private set; }
    
    /// <summary>EN: Progress tracking / VI: Theo dõi tiến độ</summary>
    public TaskProgress Progress { get; private set; } = null!;
    
    /// <summary>EN: Evidence for verification / VI: Bằng chứng để xác thực</summary>
    public TaskEvidence? Evidence { get; private set; }
    
    /// <summary>EN: Verification result / VI: Kết quả xác thực</summary>
    public VerificationResult? Verification { get; private set; }
    
    /// <summary>EN: Whether reward has been claimed / VI: Đã nhận thưởng chưa</summary>
    public bool RewardClaimed { get; private set; }
    
    /// <summary>EN: When task was started / VI: Thời điểm bắt đầu task</summary>
    public DateTime StartedAt { get; private set; }
    
    /// <summary>EN: When task was completed / VI: Thời điểm hoàn thành</summary>
    public DateTime? CompletedAt { get; private set; }
    
    /// <summary>EN: When reward was claimed / VI: Thời điểm nhận thưởng</summary>
    public DateTime? ClaimedAt { get; private set; }
    
    // EF Core constructor
    protected UserTask()
    {
        Status = null!;
    }
    
    /// <summary>
    /// EN: Start a new task for a mission / VI: Bắt đầu task mới cho một mission
    /// </summary>
    public UserTask(Guid userId, Guid missionId, int targetValue = 1)
    {
        if (userId == Guid.Empty)
            throw new ArgumentException("User ID is required", nameof(userId));
        if (missionId == Guid.Empty)
            throw new ArgumentException("Mission ID is required", nameof(missionId));
            
        UserId = userId;
        MissionId = missionId;
        Status = TaskStatus.InProgress;
        Progress = TaskProgress.Create(0, targetValue);
        RewardClaimed = false;
        StartedAt = DateTime.UtcNow;
    }
    
    /// <summary>
    /// EN: Update task progress / VI: Cập nhật tiến độ task
    /// </summary>
    public void UpdateProgress(int currentValue)
    {
        if (Status != TaskStatus.InProgress)
            throw new InvalidOperationException("Can only update progress for in-progress tasks");
            
        Progress = Progress.WithValue(currentValue);
        
        if (Progress.IsComplete)
        {
            Status = TaskStatus.PendingVerification;
        }
    }
    
    /// <summary>
    /// EN: Submit evidence for verification / VI: Nộp bằng chứng để xác thực
    /// </summary>
    public void SubmitEvidence(TaskEvidence evidence)
    {
        ArgumentNullException.ThrowIfNull(evidence);
        
        if (Status != TaskStatus.InProgress && Status != TaskStatus.PendingVerification)
            throw new InvalidOperationException("Cannot submit evidence at this stage");
            
        Evidence = evidence;
        Status = TaskStatus.PendingVerification;
    }
    
    /// <summary>
    /// EN: Complete the task after verification / VI: Hoàn thành task sau khi xác thực
    /// </summary>
    public void Complete(VerificationResult verification)
    {
        ArgumentNullException.ThrowIfNull(verification);
        
        Verification = verification;
        
        if (verification.IsValid)
        {
            Status = TaskStatus.Completed;
            CompletedAt = DateTime.UtcNow;
        }
        else
        {
            Status = TaskStatus.Rejected;
        }
    }
    
    /// <summary>
    /// EN: Auto-complete without verification / VI: Tự động hoàn thành không cần xác thực
    /// </summary>
    public void AutoComplete()
    {
        if (!Progress.IsComplete)
            throw new InvalidOperationException("Cannot auto-complete: progress not complete");
            
        Verification = VerificationResult.AutoApproved();
        Status = TaskStatus.Completed;
        CompletedAt = DateTime.UtcNow;
    }
    
    /// <summary>
    /// EN: Claim the reward / VI: Nhận thưởng
    /// </summary>
    public void ClaimReward()
    {
        if (Status != TaskStatus.Completed)
            throw new InvalidOperationException("Can only claim reward for completed tasks");
        if (RewardClaimed)
            throw new InvalidOperationException("Reward already claimed");
            
        RewardClaimed = true;
        ClaimedAt = DateTime.UtcNow;
    }
    
    /// <summary>
    /// EN: Cancel the task / VI: Hủy task
    /// </summary>
    public void Cancel()
    {
        if (RewardClaimed)
            throw new InvalidOperationException("Cannot cancel: reward already claimed");
            
        Status = TaskStatus.Cancelled;
    }
}
