namespace Modules.Library.Domain.Entities;

public abstract class Entity
{
    private int? _requestedHashCode;

    //public virtual Guid Id { get; protected set; } = Guid.NewGuid();
    public virtual Guid Id { get; protected set; }

    public virtual bool Deleted { get; protected set; }

    //internal virtual void SetDeleted() => Deleted = true;

    public bool IsTransient() => Id == default;

    public override bool Equals(object? obj)
    {
        if (obj == null || obj is not Entity)
            return false;

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

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

        Entity item = (Entity)obj;

        if (item.IsTransient() || IsTransient())
            return false;
        else
            return item.Id == Id;
    }

    public override int GetHashCode()
    {
        if (!IsTransient())
        {
            if (!_requestedHashCode.HasValue)
                _requestedHashCode = Id.GetHashCode() ^ 31; // XOR for random distribution (http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx)
            return _requestedHashCode.Value;
        }
        else
            return base.GetHashCode();
    }

    public static bool operator ==(Entity? left, Entity? right) =>
        Equals(left, null) ? Equals(right, null) : left.Equals(right);

    public static bool operator !=(Entity? left, Entity? right)
    {
        return !(left == right);
    }
}
