using Domain.Entities.Members.ValueObject;
using Domain.Entities.Wallets;
using NanoidDotNet;

/// <summary>
/// 사용자단 일반 회원 정보
/// </summary>
namespace Domain.Entities.Members
{
    public class Member
    {
        public int ID { get; private set; }

        // 회원 등급 정보
        public virtual MemberGrade? MemberGrade { get; private set; }

        // 알림/약관 동의 여부
        public virtual MemberApprove MemberApprove { get; private set; } = null!;

        // 회원 집계 정보
        public virtual MemberStats MemberStats { get; private set; } = null!;

        // 지갑
        public virtual Wallet? Wallet { get; private set; }

        // 채널
        public virtual Channel? Channel { get; private set; }

        public int? MemberGradeID { get; private set; }

        public string SID { get; private set; } = Nanoid.Generate(size: 8); // 무작위 문자열

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

        public string? Name { get; private set; }

        public string? FullName { get; private set; }

        public string? FirstName { get; private set; }

        public string? LastName { get; private set; }

        public string? Password { get; private set; } = string.Empty; // 관리자 수정 시 필요

        public string? Intro { get; private set; }

        public string? Summary { get; private set; }

        public string? Phone { get; private set; }

        public DateOnly? Birthday { get; private set; }

        public Gender? Gender { get; private set; }

        public string? Thumb { get; private set; }

        public string? Icon { get; private set; }

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

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

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

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

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

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

        public string? DeviceInfo { get; private set; }

        public string? SignupIP { get; private set; }

        public string? LastLoginIp { get; private set; }

        public string? IpAddress { get; private set; }

        public string? UserAgent { get; private set; }

        public DateTime? LastLoginAt { get; private set; }

        public DateTime? LastEmailChangedAt { get; private set; }

        public DateTime? LastNameChangedAt { get; private set; }

        public DateTime? LastSummaryChangedAt { get; private set; }

        public DateTime? LastIntroChangedAt { get; private set; }

        public DateTime? EmailVerifiedAt { get; private set; }

        public DateTime? AuthCertifiedAt { get; private set; }

        public DateTime PasswordUpdatedAt { get; private set; }

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

        public DateTime? UpdatedAt { get; private set; }

        public DateTime? DeletedAt { get; private set; }

        public DateTime? DeniedAt { get; private set; }

        private Member() { }

        private Member(string email)
        {
            if (string.IsNullOrWhiteSpace(email))
            {
                throw new ArgumentException("Email is required.", nameof(email));
            }

            if (email.Length > 60)
            {
                throw new ArgumentOutOfRangeException(nameof(email));
            }

            Email = email;
            PasswordUpdatedAt = DateTime.UtcNow;
        }

        public static Member Create(string email)
        {
            return new(email);
        }
    }
}