using System.ComponentModel.DataAnnotations;

namespace Domain.Entities.Members
{
    public class MemberGrade
    {
        [Key]
        public int ID { get; private set; }

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

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

        public string? Description { get; private set; }

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

        public string? Image { get; private set; }

        public string? TextColor { get; private set; }

        public int RequiredExp { get; private set; } = 0;

        public long RequiredAttendance { 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 MemberGrade() { }

        private MemberGrade(string korName, string engName, short order, bool isActive)
        {
            if (string.IsNullOrWhiteSpace(korName))
            {
                throw new ArgumentException("KorName is required.", nameof(korName));
            }

            if (korName.Length > 240)
            {
                throw new ArgumentOutOfRangeException(nameof(korName));
            }

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

            if (engName.Length > 120)
            {
                throw new ArgumentOutOfRangeException(nameof(engName));
            }

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

            KorName = korName;
            EngName = engName;
            Order = order;
            IsActive = isActive;
        }

        public static MemberGrade Create(string korName, string engName, short order = 0, bool isActive = false)
        {
            return new(korName, engName, order, isActive);
        }

        public void Update(string korName, string engName, string? description, short order, string? image, string? textColor, int requiredExp, long requiredAttendance, bool isActive)
        {
            if (string.IsNullOrWhiteSpace(korName))
            {
                throw new ArgumentException("KorName is required.", nameof(korName));
            }

            if (korName.Length > 240)
            {
                throw new ArgumentOutOfRangeException(nameof(korName));
            }

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

            if (engName.Length > 120)
            {
                throw new ArgumentOutOfRangeException(nameof(engName));
            }

            if (description is not null && description.Length > 1000)
            {
                throw new ArgumentOutOfRangeException(nameof(description));
            }

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

            if (image is not null && image.Length > 1000)
            {
                throw new ArgumentOutOfRangeException(nameof(image));
            }

            if (textColor is not null && textColor.Length > 7)
            {
                throw new ArgumentOutOfRangeException(nameof(textColor));
            }

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

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

            KorName = korName;
            EngName = engName;
            Description = description;
            Order = order;
            Image = image;
            TextColor = textColor;
            RequiredExp = requiredExp;
            RequiredAttendance = requiredAttendance;
            IsActive = isActive;
            UpdatedAt = DateTime.UtcNow;
        }
    }
}
