using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Domain.Entities.Members;

namespace Domain.Entities.Notes;

public class Note
{
    [ForeignKey(nameof(SenderMemberID))]
    public virtual Member? Sender { get; private set; }

    [ForeignKey(nameof(ReceiverMemberID))]
    public virtual Member? Receiver { get; private set; }

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

    /// <summary>0 = 시스템 발송</summary>
    public int SenderMemberID { get; private set; }

    public int ReceiverMemberID { get; private set; }

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

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

    public bool IsRead { get; private set; }

    public bool IsDeletedBySender { get; private set; }

    public bool IsDeletedByReceiver { get; private set; }

    public bool IsSystem { get; private set; }

    public string? RelatedType { get; private set; }

    public int? RelatedID { get; private set; }

    public DateTime? ReadAt { get; private set; }

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

    private Note() { }

    public static Note Create(
        int senderMemberID,
        int receiverMemberID,
        string title,
        string content,
        bool isSystem = false,
        string? relatedType = null,
        int? relatedID = null
    )
    {
        if (string.IsNullOrWhiteSpace(title))
        {
            throw new ArgumentException("Title is required.", nameof(title));
        }

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

        return new Note
        {
            SenderMemberID = senderMemberID,
            ReceiverMemberID = receiverMemberID,
            Title = title,
            Content = content,
            IsSystem = isSystem,
            RelatedType = relatedType,
            RelatedID = relatedID
        };
    }

    public static Note CreateSystem(int receiverMemberID, string title, string content, string? relatedType = null, int? relatedID = null)
    {
        return Create(0, receiverMemberID, title, content, true, relatedType, relatedID);
    }

    public void MarkRead()
    {
        if (!IsRead)
        {
            IsRead = true;
            ReadAt = DateTime.UtcNow;
        }
    }

    public void DeleteBySender() => IsDeletedBySender = true;
    public void DeleteByReceiver() => IsDeletedByReceiver = true;
}