namespace Baya.Domain.Common;

public interface IEntity
{
}

public interface ITimeModification
{
    DateTimeOffset CreatedAt { get; set; }
    DateTimeOffset? ModifiedAt { get; set; }
}

/// <summary>
/// An entity whose create/modify timestamps and the acting user are stamped automatically by the
/// SaveChanges audit interceptor — handlers must never set these fields themselves.
/// </summary>
public interface IAuditableEntity : ITimeModification
{
    int? CreatedById { get; set; }
    int? ModifiedById { get; set; }
}

public abstract class BaseEntity<TKey> : IEntity, IAuditableEntity
{
    public TKey Id { get; protected set; }

    public override bool Equals(object obj)
    {
        if (!(obj is BaseEntity<TKey> other))
            return false;

        if (ReferenceEquals(this, other))
            return true;

        if (GetType() != other.GetType())
            return false;

        return Id.Equals(other.Id);
    }

    public static bool operator ==(BaseEntity<TKey> a, BaseEntity<TKey> b)
    {
        if (a is null && b is null)
            return true;

        if (a is null || b is null)
            return false;

        return a.Equals(b);
    }

    public static bool operator !=(BaseEntity<TKey> a, BaseEntity<TKey> b)
    {
        return !(a == b);
    }

    public override int GetHashCode()
    {
        return (GetType().ToString() + Id).GetHashCode();
    }

    public DateTimeOffset CreatedAt { get; set; }
    public DateTimeOffset? ModifiedAt { get; set; }
    public int? CreatedById { get; set; }
    public int? ModifiedById { get; set; }
}

public abstract class BaseEntity : BaseEntity<int>
{

}
