using System.Text;
using System.Text.Json.Serialization;

namespace eSuite.Core.Miscellaneous;

/// <summary>
/// General interface that can be used to identify an item.
/// To use this, will be expected to supply the Id or Guid.
/// If both at supplied, the Id is use primarily, and the Guid can then be used as a confirmation.
/// </summary>
public class GeneralIdRef : IGeneralIdRef, IEquatable<GeneralIdRef>
{
    [JsonPropertyName("id")]
    public long? Id { get; set; }

    [JsonPropertyName("guid")]
    public Guid? Guid { get; set; }

    public bool Equals(GeneralIdRef? other)
    {
        if (Id == null || other?.Id == null)
        {
            return Nullable.Equals(Guid, other?.Guid);
        }

        if (Guid == null || other?.Guid == null)
        {
            return Nullable.Equals(Id, other?.Id);
        }
        
        return Nullable.Equals(Id, other?.Id) && Nullable.Equals(Guid, other?.Guid);
    }

    public override bool Equals(object? obj)
    {
        if (obj is null) return false;
        if (ReferenceEquals(this, obj)) return true;
        return obj.GetType() == this.GetType() && Equals(obj as GeneralIdRef);
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(Id, Guid);

    }

    public override string ToString()
    {
        var needsComma = false;
        var output = new StringBuilder();

        output.Append("GeneralIdRef(");
        if (Id != null)
        {
            output.Append("Id:");
            output.Append(Id);
            needsComma = true;
        }

        if (Guid != null)
        {
            if (needsComma)
                output.Append(", ");
            output.Append("Guid:");
            output.Append(Guid);
        }
        output.Append(")");
        return output.ToString();
    }
}