using System.ComponentModel.DataAnnotations;
namespace Domain.Entities.Chat;
///
/// 채팅 제재 (개미투자 D2) — RoomKey NULL 은 전체 룸 제재, ExpiresAt NULL 은 무기한.
/// 발언(SendMessage)만 차단하고 읽기는 허용한다.
///
public class ChatBan
{
[Key]
public int ID { get; private set; }
/// 제재 대상 회원 (FK Member)
public int MemberID { get; private set; }
/// 제재 룸 키 — NULL 이면 전체 룸
public string? RoomKey { get; private set; }
/// 제재 사유
public string Reason { get; private set; } = default!;
/// 만료 일시 (UTC) — NULL 이면 무기한
public DateTime? ExpiresAt { get; private set; }
/// 제재 등록자 (Admin 계정 표시명)
public string CreatedBy { get; private set; } = default!;
public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
private ChatBan() { }
public static ChatBan Create(int memberID, string? roomKey, string reason, DateTime? expiresAt, string createdBy)
{
if (memberID <= 0)
{
throw new ArgumentOutOfRangeException(nameof(memberID));
}
if (string.IsNullOrWhiteSpace(reason))
{
throw new ArgumentException("reason required", nameof(reason));
}
if (string.IsNullOrWhiteSpace(createdBy))
{
throw new ArgumentException("createdBy required", nameof(createdBy));
}
return new ChatBan
{
MemberID = memberID,
RoomKey = string.IsNullOrWhiteSpace(roomKey) ? null : roomKey.Trim(),
Reason = reason.Trim(),
ExpiresAt = expiresAt,
CreatedBy = createdBy.Trim()
};
}
/// 현재 시각 기준 유효한 제재인지
public bool IsActiveAt(DateTime nowUtc) => ExpiresAt is null || ExpiresAt > nowUtc;
/// 제재 즉시 해제 — 만료 시각을 현재로 당김 (이력 보존)
public void Lift(DateTime nowUtc)
{
if (!IsActiveAt(nowUtc))
{
return;
}
ExpiresAt = nowUtc;
}
}