using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Domain.Entities.Members;

namespace Domain.Entities.Donations;

public class Crew
{
    [ForeignKey(nameof(ChannelID))]
    public virtual Channel? Channel { get; private set; }

    [ForeignKey(nameof(MemberID))]
    public virtual Member? Member { get; private set; }

    private readonly List<CrewMember> _members = [];
    public IReadOnlyCollection<CrewMember> Members => _members;

    private readonly List<CrewSession> _sessions = [];
    public IReadOnlyCollection<CrewSession> Sessions => _sessions;

    [Key]
    public int ID { get; private set; }

    public int ChannelID { get; private set; }

    public int MemberID { get; private set; }

    public string Name { get; private set; } = default!;

    public string? Description { get; private set; }

    public int? MinAmount { get; private set; }

    public bool IsActive { get; private set; } = true;

    public string? InviteCode { get; private set; }

    public DateTime? UpdatedAt { get; private set; }

    public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;

    private Crew() { }

    public static Crew Create(int channelID, int memberID, string name, string? description = null, int? minAmount = null)
    {
        if (string.IsNullOrWhiteSpace(name))
        {
            throw new ArgumentException("Name is required.", nameof(name));
        }

        return new Crew
        {
            ChannelID = channelID,
            MemberID = memberID,
            Name = name,
            Description = description,
            MinAmount = minAmount
        };
    }

    public void Update(string name, string? description, int? minAmount, bool isActive)
    {
        Name = name;
        Description = description;
        MinAmount = minAmount;
        IsActive = isActive;
        UpdatedAt = DateTime.UtcNow;
    }

    public string GenerateInviteCode()
    {
        InviteCode = Guid.NewGuid().ToString("N")[..8].ToUpperInvariant();
        UpdatedAt = DateTime.UtcNow;
        return InviteCode;
    }
}