namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;

/// <summary>
/// Sent from CentralUI to a specific site to read the current value of one or
/// more tags on the live server backing a named data connection. Backs the
/// "Test Bindings" dialog on the Configure Instance page — a one-shot read of
/// every bound attribute, grouped by connection, with no subscription.
/// </summary>
/// <remarks>
/// Keyed by <see cref="ConnectionName"/> (not id) for the same reason as
/// <see cref="BrowseNodeCommand"/>: the site-side
/// <c>DataConnectionManagerActor</c> indexes its children by connection name,
/// and the central UI already has the connection name in scope from the
/// bindings table. The central <c>DataConnections</c> table's id is not
/// exposed at the site.
/// </remarks>
/// <param name="ConnectionName">Name of the site-local data connection to read against.</param>
/// <param name="TagPaths">Tag paths to read (one batch per connection — caller groups by connection name).</param>
public record ReadTagValuesCommand(
    string ConnectionName,
    IReadOnlyList<string> TagPaths);

/// <summary>
/// Per-tag outcome of a <see cref="ReadTagValuesCommand"/>. The site returns
/// one outcome per requested tag path; a single failing tag never aborts the
/// batch (the underlying <c>IDataConnection.ReadBatchAsync</c> contract).
/// </summary>
/// <param name="TagPath">Tag path that was read — matches an entry in the request.</param>
/// <param name="Success">True when the read returned a value; false when the per-tag read failed.</param>
/// <param name="Value">Read value (may be null even on success); always null on failure.</param>
/// <param name="Quality">Quality code as a string (<c>Good</c>/<c>Bad</c>/<c>Uncertain</c>); always <c>Bad</c> on failure.</param>
/// <param name="Timestamp">Source timestamp on success; the central-noted UTC time of the failure otherwise.</param>
/// <param name="ErrorMessage">Per-tag error message on failure; null on success.</param>
public record TagReadOutcome(
    string TagPath,
    bool Success,
    object? Value,
    string Quality,
    DateTimeOffset Timestamp,
    string? ErrorMessage);

/// <summary>
/// Reply to a <see cref="ReadTagValuesCommand"/>. Either <see cref="Outcomes"/>
/// is populated (one entry per requested tag, in any order) and
/// <see cref="Failure"/> is null, or <see cref="Failure"/> is set and
/// <see cref="Outcomes"/> is empty — the latter is the connection-level
/// short-circuit (unknown connection, not connected, server error, etc.) where
/// no per-tag attempt was made.
/// </summary>
public record ReadTagValuesResult(
    IReadOnlyList<TagReadOutcome> Outcomes,
    ReadTagValuesFailure? Failure);

/// <summary>
/// Connection-level failure carried by <see cref="ReadTagValuesResult"/>. The
/// dialog maps each <see cref="ReadTagValuesFailureKind"/> to a friendly
/// banner; <see cref="Message"/> is surfaced verbatim for the
/// <see cref="ReadTagValuesFailureKind.ServerError"/> case.
/// </summary>
public record ReadTagValuesFailure(
    ReadTagValuesFailureKind Kind,
    string Message);

public enum ReadTagValuesFailureKind
{
    ConnectionNotFound,
    ConnectionNotConnected,
    Timeout,
    ServerError
}
