namespace MissionService.Domain.AggregatesModel.MissionAggregate;

using MissionService.Domain.SeedWork;

/// <summary>
/// EN: Mission aggregate root - defines a gamification mission
/// VI: Aggregate root Mission - định nghĩa một nhiệm vụ gamification
/// </summary>
public class Mission : Entity, IAggregateRoot
{
    // EN: Unique code for the mission / VI: Mã duy nhất cho mission
    public string Code { get; private set; } = string.Empty;
    
    // EN: Localized title / VI: Tiêu đề đa ngôn ngữ
    public string TitleEn { get; private set; } = string.Empty;
    public string TitleVi { get; private set; } = string.Empty;
    
    // EN: Localized description / VI: Mô tả đa ngôn ngữ
    public string? DescriptionEn { get; private set; }
    public string? DescriptionVi { get; private set; }
    
    // EN: Mission type / VI: Loại mission
    public MissionType Type { get; private set; }
    
    // EN: Mission category / VI: Danh mục mission
    public MissionCategory Category { get; private set; }
    
    // EN: Reward configuration / VI: Cấu hình phần thưởng
    public MissionReward Reward { get; private set; } = null!;
    
    // EN: How often can this mission be completed / VI: Tần suất hoàn thành
    public FrequencyType Frequency { get; private set; }
    
    // EN: Max times a user can complete / VI: Số lần tối đa user có thể hoàn thành
    public int MaxCompletions { get; private set; }
    
    // EN: Mission availability window / VI: Khung thời gian mission
    public DateTime StartDate { get; private set; }
    public DateTime? EndDate { get; private set; }
    
    // EN: Current status / VI: Trạng thái hiện tại
    public MissionStatus Status { get; private set; }
    
    // EN: Display priority / VI: Độ ưu tiên hiển thị
    public int Priority { get; private set; }
    
    // EN: Mission rules / VI: Các quy tắc mission
    private readonly List<MissionRule> _rules = new();
    public IReadOnlyCollection<MissionRule> Rules => _rules.AsReadOnly();
    
    // EF Core constructor
    protected Mission()
    {
        Type = null!;
        Category = null!;
        Frequency = null!;
        Status = null!;
    }
    
    /// <summary>
    /// EN: Create a new mission / VI: Tạo mission mới
    /// </summary>
    public Mission(
        string code,
        string titleEn,
        string titleVi,
        MissionType type,
        MissionCategory category,
        MissionReward reward,
        FrequencyType frequency,
        int maxCompletions,
        DateTime startDate,
        DateTime? endDate = null,
        int priority = 0)
    {
        if (string.IsNullOrWhiteSpace(code))
            throw new ArgumentException("Mission code is required", nameof(code));
        if (string.IsNullOrWhiteSpace(titleEn))
            throw new ArgumentException("English title is required", nameof(titleEn));
        if (maxCompletions < 1)
            throw new ArgumentException("Max completions must be at least 1", nameof(maxCompletions));
            
        Code = code;
        TitleEn = titleEn;
        TitleVi = titleVi;
        Type = type;
        Category = category;
        Reward = reward ?? throw new ArgumentNullException(nameof(reward));
        Frequency = frequency;
        MaxCompletions = maxCompletions;
        StartDate = startDate;
        EndDate = endDate;
        Status = MissionStatus.Draft;
        Priority = priority;
    }
    
    /// <summary>
    /// EN: Activate the mission / VI: Kích hoạt mission
    /// </summary>
    public void Activate()
    {
        if (Status != MissionStatus.Draft && Status != MissionStatus.Paused)
            throw new InvalidOperationException("Can only activate draft or paused missions");
            
        Status = MissionStatus.Active;
    }
    
    /// <summary>
    /// EN: Pause the mission / VI: Tạm dừng mission
    /// </summary>
    public void Pause()
    {
        if (Status != MissionStatus.Active)
            throw new InvalidOperationException("Can only pause active missions");
            
        Status = MissionStatus.Paused;
    }
    
    /// <summary>
    /// EN: Archive the mission / VI: Lưu trữ mission
    /// </summary>
    public void Archive()
    {
        Status = MissionStatus.Archived;
    }
    
    /// <summary>
    /// EN: Add a rule to the mission / VI: Thêm quy tắc cho mission
    /// </summary>
    public void AddRule(MissionRule rule)
    {
        ArgumentNullException.ThrowIfNull(rule);
        _rules.Add(rule);
    }
    
    /// <summary>
    /// EN: Check if mission is available now / VI: Kiểm tra mission có khả dụng không
    /// </summary>
    public bool IsAvailable()
    {
        var now = DateTime.UtcNow;
        return Status == MissionStatus.Active 
            && now >= StartDate 
            && (EndDate == null || now <= EndDate);
    }
    
    /// <summary>
    /// EN: Update mission details / VI: Cập nhật thông tin mission
    /// </summary>
    public void UpdateDetails(
        string titleEn,
        string titleVi,
        string? descriptionEn,
        string? descriptionVi,
        int priority)
    {
        TitleEn = titleEn;
        TitleVi = titleVi;
        DescriptionEn = descriptionEn;
        DescriptionVi = descriptionVi;
        Priority = priority;
    }
}
