using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace Domain.Entities.Members { public class Channel { [ForeignKey(nameof(MemberID))] public virtual Member Member { get; private set; } = null!; [Key] public int ID { get; private set; } public int MemberID { get; private set; } public string SID { get; private set; } = default!; public string Name { get; private set; } = default!; public string? Handle { get; private set; } public string YouTubeUrl { get; private set; } = default!; public string? YouTubeChannelID { get; private set; } public string? Description { get; private set; } public string? ThumbnailUrl { get; private set; } public string? BannerUrl { get; private set; } public long SubscriberCount { get; private set; } public long VideoCount { get; private set; } public long ViewCount { get; private set; } public string? Email { get; private set; } public DateTime? YouTubePublishedAt { get; private set; } public decimal PlatformFeeRate { get; private set; } = 0; public bool IsVerified { get; private set; } = false; public bool IsActive { get; private set; } = true; public string WidgetToken { get; private set; } = GenerateWidgetToken(); public DateTime? UpdatedAt { get; private set; } public DateTime CreatedAt { get; private set; } = DateTime.UtcNow; private Channel() { } private Channel(int memberID, string sid, string name, string youtubeUrl) { if (memberID <= 0) { throw new ArgumentOutOfRangeException(nameof(memberID)); } if (string.IsNullOrWhiteSpace(sid)) { throw new ArgumentException("SID is required.", nameof(sid)); } if (sid.Length != 24) { throw new ArgumentOutOfRangeException(nameof(sid)); } if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Name is required.", nameof(name)); } if (name.Length > 200) { throw new ArgumentOutOfRangeException(nameof(name)); } if (string.IsNullOrWhiteSpace(youtubeUrl)) { throw new ArgumentException("YouTubeUrl is required.", nameof(youtubeUrl)); } if (youtubeUrl.Length > 255) { throw new ArgumentOutOfRangeException(nameof(youtubeUrl)); } MemberID = memberID; SID = sid; Name = name; YouTubeUrl = youtubeUrl; } public static Channel Create(int memberID, string sid, string name, string youtubeUrl) { return new(memberID, sid, name, youtubeUrl); } public void Update(string name, string? handle, string youtubeUrl, decimal platformFeeRate, bool isVerified, bool isActive) { if (string.IsNullOrWhiteSpace(name)) { throw new ArgumentException("Name is required.", nameof(name)); } if (name.Length > 200) { throw new ArgumentOutOfRangeException(nameof(name)); } if (handle is not null && handle.Length > 30) { throw new ArgumentOutOfRangeException(nameof(handle)); } if (string.IsNullOrWhiteSpace(youtubeUrl)) { throw new ArgumentException("YouTubeUrl is required.", nameof(youtubeUrl)); } if (youtubeUrl.Length > 255) { throw new ArgumentOutOfRangeException(nameof(youtubeUrl)); } if (platformFeeRate < 0 || platformFeeRate > 100) { throw new ArgumentOutOfRangeException(nameof(platformFeeRate)); } Name = name; Handle = handle; YouTubeUrl = youtubeUrl; PlatformFeeRate = platformFeeRate; IsVerified = isVerified; IsActive = isActive; UpdatedAt = DateTime.UtcNow; } public void UpdateYouTubeInfo( string youtubeChannelID, string name, string? handle, string? description, string? thumbnailUrl, string? bannerUrl, long subscriberCount, long videoCount, long viewCount, string? email, DateTime? youtubePublishedAt ) { YouTubeChannelID = youtubeChannelID; Name = name; Handle = handle; Description = description; ThumbnailUrl = thumbnailUrl; BannerUrl = bannerUrl; SubscriberCount = subscriberCount; VideoCount = videoCount; ViewCount = viewCount; Email = email; IsActive = true; YouTubePublishedAt = youtubePublishedAt; UpdatedAt = DateTime.UtcNow; } public void Deactivate() { IsActive = false; UpdatedAt = DateTime.UtcNow; } public void ResetWidgetToken() { WidgetToken = GenerateWidgetToken(); UpdatedAt = DateTime.UtcNow; } private static string GenerateWidgetToken() { return Guid.NewGuid().ToString("N"); } } }