using System.ComponentModel.DataAnnotations;

namespace Domain.Entities.Crypto
{
    public class CoinCategory
    {
        public virtual List<CoinCategoryMap> CoinCategoryMap { get; private set; } = [];

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

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

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

        public short Order { get; private set; } = 0;

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

        public DateTime? UpdatedAt { get; private set; }

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

        private CoinCategory() { }

        private CoinCategory(string code, string name, short order, bool isActive)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                throw new ArgumentException("Code is required.", nameof(code));
            }

            if (code.Length > 30)
            {
                throw new ArgumentOutOfRangeException(nameof(code));
            }

            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("Name is required.", nameof(name));
            }

            if (name.Length > 100)
            {
                throw new ArgumentOutOfRangeException(nameof(name));
            }

            if (order < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(order));
            }

            Code = code;
            Name = name;
            Order = order;
            IsActive = isActive;
        }

        public static CoinCategory Create(string code, string name, short order = 0, bool isActive = false)
        {
            return new(code, name, order, isActive);
        }

        public void Update(string code, string name, short order, bool isActive)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                throw new ArgumentException("Code is required.", nameof(code));
            }

            if (code.Length > 30)
            {
                throw new ArgumentOutOfRangeException(nameof(code));
            }

            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("Name is required.", nameof(name));
            }

            if (name.Length > 100)
            {
                throw new ArgumentOutOfRangeException(nameof(name));
            }

            if (order < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(order));
            }

            Code = code;
            Name = name;
            Order = order;
            IsActive = isActive;
            UpdatedAt = DateTime.UtcNow;
        }
    }
}