using adas_core.Domain.Models.MongoModels;
using Microsoft.Extensions.Logging;

namespace adas_core.Domain.Utils;

/// <summary>
/// Provides static utility methods for working with HL7 (Health Level 7) data formats and messages.
/// </summary>
public static class Hl7Utils
{
    /// <summary>
    ///     Evalúa si se debe permitir el auto ADT basándose en la configuración de la unidad actual y la antigua.
    /// </summary>
    /// <param name="unitConfig">Configuración de la unidad (Location)</param>
    /// <param name="oldUnitConfig">Configuración de la antigua unidad (OldLocation)</param>
    /// <param name="logger">Logger para registrar advertencias</param>
    /// <param name="type">Tipo de mensaje HL7 que se va a procesar su entrada</param>
    /// <returns>true si se permite; false en caso contrario.</returns>
    public static bool ManageAutoAdt(Unit? unitConfig, Unit? oldUnitConfig, ILogger logger, string type)
    {
        // Variables de estado:
        var locationKnown = unitConfig != null;
        var oldLocationKnown = oldUnitConfig != null;
        var locationAutoAdt = unitConfig?.Configuration.AutoAdt ?? false;
        var oldLocationAutoAdt = oldUnitConfig?.Configuration.AutoAdt ?? false;

        // Creamos una clave que combine ambas informaciones:
        // Formato: "LK-LA:OLK-OLA" donde LK = locationKnown (1=si, 0=no) y LA = locationAutoAdt (1=si, 0=no)
        var key = $"{(locationKnown ? "1" : "0")}-" +
                  $"{(locationAutoAdt ? "1" : "0")}/" +
                  $"{(oldLocationKnown ? "1" : "0")}-" +
                  $"{(oldLocationAutoAdt ? "1" : "0")}";

        // Evaluamos la clave según los escenarios:
        // Caso 1: "1-1/1-1"  → Ambas conocidas y AutoAdt true → Permitido.
        // Caso 2: "1-0/1-1"  → Ambas conocidas, pero location.AutoAdt false → No permitido.
        // Caso 3: "0-0/1-1"  → Location desconocida, oldLocation conocida con AutoAdt true → Permitido.
        // Caso 4: "1-1/0-0"  → Location conocida con AutoAdt true, oldLocation desconocida → Permitido.
        // Caso 5: "1-1/1-0"  → Ambas conocidas, pero oldLocation.AutoAdt false → No permitido.
        // Caso 6: "1-0/1-0"  → Ambas conocidas, ambas con AutoAdt false → No permitido.
        // Caso 7: "0-0/1-0"  → Location desconocida, pero oldLocation.AutoAdt false → No permitido.
        // Caso 8: "1-0/0-0"  → Location conocida con AutoAdt false, y oldLocation desconocida → No permitido.
        // Caso 9: "0-0/0-0"  → Ambas desconocidas → No permitido.
        switch (key)
        {
            case "1-1/1-1": // Caso 1
            case "0-0/1-1": // Caso 3
            case "1-1/0-0": // Caso 4
                return true;
            case "1-0/1-1": // Caso 2
            case "1-1/1-0": // Caso 5
            case "1-0/1-0": // Caso 6
            case "0-0/1-0": // Caso 7
            case "1-0/0-0": // Caso 8
                logger.LogWarning(
                    "Deny permission for auto {HL7} on Location: {Location}, OldLocation: {OldLocation} check: {Key}",
                    type, unitConfig?.Name, oldUnitConfig?.Name, key);
                return false;
            default: // Caso 9 u otro escenario no contemplado
                logger.LogWarning("Both units are unknown on Auto {HL7} check: {Key}", type, key);
                return false;
        }
    }
}