namespace ZB.MOM.WW.OtOpcUa.Configuration.Entities;

/// <summary>Physical OPC UA server node within a <see cref="ServerCluster"/>.</summary>
public sealed class ClusterNode
{
    /// <summary>Stable per-machine logical ID, e.g. "LINE3-OPCUA-A".</summary>
    public required string NodeId { get; set; }

    /// <summary>The unique identifier of the cluster this node belongs to.</summary>
    public required string ClusterId { get; set; }

    /// <summary>Machine hostname / IP.</summary>
    public required string Host { get; set; }

    /// <summary>The OPC UA server port (default 4840).</summary>
    public int OpcUaPort { get; set; } = 4840;

    /// <summary>The dashboard HTTP port (default 8081).</summary>
    public int DashboardPort { get; set; } = 8081;

    /// <summary>
    ///     OPC UA <c>ApplicationUri</c> — MUST be unique per node per OPC UA spec. Clients pin trust here.
    ///     Fleet-wide unique index enforces no two nodes share a value.
    ///     Stored explicitly, NOT derived from <see cref="Host"/> at runtime — silent rewrite on
    ///     hostname change would break all client trust.
    /// </summary>
    public required string ApplicationUri { get; set; }

    /// <summary>Primary = 200, Secondary = 150 by default.</summary>
    public byte ServiceLevelBase { get; set; } = 200;

    /// <summary>
    ///     Per-node override JSON keyed by DriverInstanceId, merged onto cluster-level DriverConfig
    ///     at apply time. Minimal by intent. Nullable when no overrides exist.
    /// </summary>
    public string? DriverConfigOverridesJson { get; set; }

    /// <summary>Gets or sets a value indicating whether this node is enabled.</summary>
    public bool Enabled { get; set; } = true;

    /// <summary>Gets or sets the timestamp when this node was last seen.</summary>
    public DateTime? LastSeenAt { get; set; }

    /// <summary>Gets or sets the timestamp when this node was created.</summary>
    public DateTime CreatedAt { get; set; } = DateTime.UtcNow;

    /// <summary>Gets or sets the username of who created this node.</summary>
    public required string CreatedBy { get; set; }

    // Navigation
    /// <summary>Gets or sets the cluster this node belongs to.</summary>
    public ServerCluster? Cluster { get; set; }
    /// <summary>Gets or sets the credentials associated with this node.</summary>
    public ICollection<ClusterNodeCredential> Credentials { get; set; } = [];
}
