namespace MissionService.Domain.AggregatesModel.TaskAggregate;

using MissionService.Domain.SeedWork;

/// <summary>
/// EN: Task progress tracking - Value Object
/// VI: Theo dõi tiến độ task - Value Object
/// </summary>
public class TaskProgress : ValueObject
{
    /// <summary>EN: Current value / VI: Giá trị hiện tại</summary>
    public int CurrentValue { get; private set; }
    
    /// <summary>EN: Target value to complete / VI: Giá trị mục tiêu để hoàn thành</summary>
    public int TargetValue { get; private set; }
    
    /// <summary>EN: Last update time / VI: Thời điểm cập nhật cuối</summary>
    public DateTime LastUpdated { get; private set; }
    
    /// <summary>EN: Percentage complete / VI: Phần trăm hoàn thành</summary>
    public decimal PercentComplete => TargetValue > 0 
        ? Math.Min(100, (CurrentValue * 100m) / TargetValue) 
        : 0;
    
    /// <summary>EN: Is the task complete / VI: Task đã hoàn thành chưa</summary>
    public bool IsComplete => CurrentValue >= TargetValue;
    
    // EF Core constructor
    protected TaskProgress() { }
    
    private TaskProgress(int currentValue, int targetValue, DateTime lastUpdated)
    {
        CurrentValue = currentValue;
        TargetValue = targetValue;
        LastUpdated = lastUpdated;
    }
    
    /// <summary>
    /// EN: Create new progress tracker / VI: Tạo bộ theo dõi tiến độ mới
    /// </summary>
    public static TaskProgress Create(int currentValue, int targetValue)
    {
        if (targetValue < 1)
            throw new ArgumentException("Target value must be at least 1", nameof(targetValue));
        if (currentValue < 0)
            throw new ArgumentException("Current value cannot be negative", nameof(currentValue));
            
        return new TaskProgress(currentValue, targetValue, DateTime.UtcNow);
    }
    
    /// <summary>
    /// EN: Create with new current value / VI: Tạo mới với giá trị hiện tại mới
    /// </summary>
    public TaskProgress WithValue(int newValue)
    {
        var clamped = Math.Min(Math.Max(0, newValue), TargetValue);
        return new TaskProgress(clamped, TargetValue, DateTime.UtcNow);
    }
    
    /// <summary>
    /// EN: Increment current value by amount / VI: Tăng giá trị hiện tại
    /// </summary>
    public TaskProgress Increment(int amount = 1)
    {
        return WithValue(CurrentValue + amount);
    }
    
    protected override IEnumerable<object?> GetEqualityComponents()
    {
        yield return CurrentValue;
        yield return TargetValue;
    }
}

/// <summary>
/// EN: Evidence for task verification - Value Object
/// VI: Bằng chứng để xác thực task - Value Object
/// </summary>
public class TaskEvidence : ValueObject
{
    /// <summary>EN: Type of evidence / VI: Loại bằng chứng</summary>
    public EvidenceType Type { get; private set; }
    
    /// <summary>EN: Evidence data (JSON or value) / VI: Dữ liệu bằng chứng</summary>
    public string Data { get; private set; } = string.Empty;
    
    /// <summary>EN: Screenshot URL / VI: URL ảnh chụp màn hình</summary>
    public string? ScreenshotUrl { get; private set; }
    
    /// <summary>EN: Video URL / VI: URL video</summary>
    public string? VideoUrl { get; private set; }
    
    /// <summary>EN: When evidence was captured / VI: Thời điểm thu thập bằng chứng</summary>
    public DateTime CapturedAt { get; private set; }
    
    // EF Core constructor
    protected TaskEvidence() { }
    
    private TaskEvidence(EvidenceType type, string data, string? screenshotUrl, string? videoUrl, DateTime capturedAt)
    {
        Type = type;
        Data = data;
        ScreenshotUrl = screenshotUrl;
        VideoUrl = videoUrl;
        CapturedAt = capturedAt;
    }
    
    /// <summary>
    /// EN: Create watch duration evidence / VI: Tạo bằng chứng thời lượng xem
    /// </summary>
    public static TaskEvidence WatchDuration(int seconds)
        => new(EvidenceType.WatchDuration, seconds.ToString(), null, null, DateTime.UtcNow);
    
    /// <summary>
    /// EN: Create click evidence / VI: Tạo bằng chứng click
    /// </summary>
    public static TaskEvidence Click(string url, string? metadata = null)
        => new(EvidenceType.ClickData, metadata ?? url, null, null, DateTime.UtcNow);
    
    /// <summary>
    /// EN: Create upload evidence / VI: Tạo bằng chứng tải lên
    /// </summary>
    public static TaskEvidence Upload(string fileUrl, bool isImage)
        => new(EvidenceType.UploadedContent, fileUrl, 
            isImage ? fileUrl : null, 
            isImage ? null : fileUrl, 
            DateTime.UtcNow);
    
    /// <summary>
    /// EN: Create social proof evidence / VI: Tạo bằng chứng hành động xã hội
    /// </summary>
    public static TaskEvidence SocialProof(string screenshotUrl, string? actionData = null)
        => new(EvidenceType.SocialProof, actionData ?? string.Empty, screenshotUrl, null, DateTime.UtcNow);
    
    /// <summary>
    /// EN: Create invite code evidence / VI: Tạo bằng chứng mã mời
    /// </summary>
    public static TaskEvidence InviteCode(string code)
        => new(EvidenceType.InviteCode, code, null, null, DateTime.UtcNow);
    
    protected override IEnumerable<object?> GetEqualityComponents()
    {
        yield return Type;
        yield return Data;
        yield return ScreenshotUrl;
        yield return VideoUrl;
    }
}

/// <summary>
/// EN: Evidence types / VI: Các loại bằng chứng
/// </summary>
public enum EvidenceType
{
    /// <summary>EN: Video watch duration / VI: Thời lượng xem video</summary>
    WatchDuration = 1,
    
    /// <summary>EN: Click data / VI: Dữ liệu click</summary>
    ClickData = 2,
    
    /// <summary>EN: Uploaded content URL / VI: URL nội dung tải lên</summary>
    UploadedContent = 3,
    
    /// <summary>EN: Screenshot of social action / VI: Ảnh chụp hành động xã hội</summary>
    SocialProof = 4,
    
    /// <summary>EN: Used invite code / VI: Mã mời đã sử dụng</summary>
    InviteCode = 5
}

/// <summary>
/// EN: Task verification result - Value Object
/// VI: Kết quả xác thực task - Value Object
/// </summary>
public class VerificationResult : ValueObject
{
    /// <summary>EN: Is the verification valid / VI: Xác thực có hợp lệ không</summary>
    public bool IsValid { get; private set; }
    
    /// <summary>EN: Reason for failure / VI: Lý do thất bại</summary>
    public string? FailureReason { get; private set; }
    
    /// <summary>EN: Verification method used / VI: Phương thức xác thực</summary>
    public VerificationMethod Method { get; private set; }
    
    /// <summary>EN: Who verified (for manual) / VI: Ai đã xác thực (với manual)</summary>
    public Guid? VerifiedBy { get; private set; }
    
    /// <summary>EN: When verified / VI: Thời điểm xác thực</summary>
    public DateTime VerifiedAt { get; private set; }
    
    // EF Core constructor
    protected VerificationResult() { }
    
    private VerificationResult(bool isValid, string? failureReason, VerificationMethod method, Guid? verifiedBy)
    {
        IsValid = isValid;
        FailureReason = failureReason;
        Method = method;
        VerifiedBy = verifiedBy;
        VerifiedAt = DateTime.UtcNow;
    }
    
    /// <summary>
    /// EN: Auto-approved result / VI: Kết quả tự động duyệt
    /// </summary>
    public static VerificationResult AutoApproved()
        => new(true, null, VerificationMethod.Automatic, null);
    
    /// <summary>
    /// EN: AI approved result / VI: Kết quả AI duyệt
    /// </summary>
    public static VerificationResult AiApproved()
        => new(true, null, VerificationMethod.AI, null);
    
    /// <summary>
    /// EN: Manually approved / VI: Duyệt thủ công
    /// </summary>
    public static VerificationResult ManualApproved(Guid adminId)
        => new(true, null, VerificationMethod.Manual, adminId);
    
    /// <summary>
    /// EN: Rejected result / VI: Kết quả từ chối
    /// </summary>
    public static VerificationResult Rejected(string reason, VerificationMethod method, Guid? adminId = null)
        => new(false, reason, method, adminId);
    
    protected override IEnumerable<object?> GetEqualityComponents()
    {
        yield return IsValid;
        yield return Method;
        yield return VerifiedBy;
    }
}

/// <summary>
/// EN: Verification methods / VI: Phương thức xác thực
/// </summary>
public enum VerificationMethod
{
    /// <summary>EN: Automatic (no review needed) / VI: Tự động (không cần review)</summary>
    Automatic = 1,
    
    /// <summary>EN: AI-based verification / VI: Xác thực bằng AI</summary>
    AI = 2,
    
    /// <summary>EN: Manual human review / VI: Xem xét thủ công bởi người</summary>
    Manual = 3
}
