namespace adas_core.Domain.Models;

/// <summary>
/// Represents the location of a patient within a healthcare or clinical context.
/// Implements <see cref="IEquatable{PatientLocation}"/> to provide type-specific equality comparison between patient location instances.
/// </summary>
/// <!-- aidoc:v1 sig=6e6501a -->
public class PatientLocation : IEquatable<PatientLocation>
{
    /// <summary>
    /// Initializes a new instance of the <see cref="PatientLocation"/> class, which represents a patient's location within a care unit, using the specified unit name, bed, and room values.
    /// </summary>
    /// <param name="unitName">The name of the care unit assigned to <see cref="PatientLocation.UnitName"/>, or <see langword="null"/>.</param>
    /// <param name="bed">The bed identifier assigned to <see cref="PatientLocation.Bed"/>, or <see langword="null"/>.</param>
    /// <param name="room">The room identifier assigned to <see cref="PatientLocation.Room"/>, or <see langword="null"/>.</param>
    /// <!-- aidoc:v1 sig=401fc97 body=2b1784e -->
    public PatientLocation(string? unitName, string? bed, string? room)
    {
        UnitName = unitName;
        Bed = bed;
        Room = room;
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="PatientLocation"/> class, storing the supplied unit name and bed, and using the bed value as the room identifier.
    /// </summary>
    /// <param name="unitName">The unit name to assign to <see cref="PatientLocation.UnitName"/>, or <see langword="null"/> if unspecified.</param>
    /// <param name="bed">The bed identifier to assign to <see cref="PatientLocation.Bed"/> and <see cref="PatientLocation.Room"/>, or <see langword="null"/> if unspecified.</param>
    /// <!-- aidoc:v1 sig=44a90e4 body=fbafeea -->
    public PatientLocation(string? unitName, string? bed)
    {
        UnitName = unitName;
        Bed = bed;
        Room = bed;
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="PatientLocation"/> class without performing explicit initialization of its members.
    /// The <see cref="PatientLocation"/> type represents the location of a patient.
    /// </summary>
    /// <!-- aidoc:v1 sig=0911aca body=4448e1d -->
    public PatientLocation()
    {
        // Constructor vacío
    }

    public string? UnitName { get; init; }

    public string? Bed { get; set; }
    public string? Room { get; init; }

    /// <summary>
    /// Determines whether the specified <see cref="PatientLocation"/> is equal to the current instance by comparing the <c>UnitName</c>, <c>Bed</c>, and <c>Room</c> properties.
    /// </summary>
    /// <param name="other">The <see cref="PatientLocation"/> to compare with the current instance.</param>
    /// <returns><see langword="true"/> when all three properties (<c>UnitName</c>, <c>Bed</c>, and <c>Room</c>) match; otherwise, <see langword="false"/>. Returns <see langword="false"/> if <paramref name="other"/> is <see langword="null"/>.</returns>
    /// <!-- aidoc:v1 sig=29defab body=9b8e1aa -->
    public bool Equals(PatientLocation? other)
        {
            return UnitName == other?.UnitName && Bed == other?.Bed && Room == other?.Room;
        }

    /// <summary>
    /// Determines whether the current instance is considered empty by checking that both the <see cref="UnitName"/> and <see cref="Bed"/> values are null or empty strings.
    /// </summary>
    /// <returns><see langword="true"/> if both <c>UnitName</c> and <c>Bed</c> are null or empty; otherwise, <see langword="false"/>.</returns>
    /// <!-- aidoc:v1 sig=1112d99 body=46ea0dd -->
    public bool IsEmpty()
        {
            return string.IsNullOrEmpty(UnitName) && string.IsNullOrEmpty(Bed);
        }

    /// <summary>
    /// Determines whether the unit name, bed, and room fields are all null or empty, indicating the entity is fully empty.
    /// </summary>
    /// <returns><c>true</c> if <see cref="UnitName"/>, <see cref="Bed"/>, and <see cref="Room"/> are all null or empty; otherwise, <c>false</c>.</returns>
    /// <!-- aidoc:v1 sig=b4be47a body=0369139 -->
    public bool IsFullEmpty()
        {
            return string.IsNullOrEmpty(UnitName) && string.IsNullOrEmpty(Bed) && string.IsNullOrEmpty(Room);
        }

    /// <summary>
    /// Returns a human-readable string representation of the PatientLocation, including the unit name, room, and bed.
    /// </summary>
    /// <returns>A formatted string in the form "PatientLocation[Unit: {UnitName},room: {Room} ,bed: {Bed}]".</returns>
    /// <!-- aidoc:v1 sig=d27f326 body=bf03a9b -->
    public override string ToString()
        {
            return "PatientLocation[Unit: " + UnitName + ",room: " + Room + " ,bed: " + Bed + "]";
        }

    //public override bool Equals(object? obj)
    //{
    //    return obj is PatientLocation objPl && Equals(objPl);
    //}

    //public override int GetHashCode()
    //{
    //    var hashCode = 511378865;
    //    if (UnitName != null)
    //        hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(UnitName);
    //    // ReSharper disable once NonReadonlyMemberInGetHashCode
    //    if (Bed != null) hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(Bed);
    //    return hashCode;
    //}
}