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

// ============================================================================
// Two-person ("secured") write commands.
//
// An Operator SUBMITS a pending secured write against an MxGateway data
// connection; a distinct Verifier later APPROVES (executes) or
// REJECTS it. Separation of duties is enforced at the handler: a write may not
// be verified by the same principal that submitted it. ListSecuredWrites is a
// read-only query (any authenticated user). Role gating lives in
// ManagementActor.GetRequiredRole (Operator for submit; Verifier for
// reject/approve).
// ============================================================================

/// <summary>
/// Operator request to submit a pending secured write. The target connection
/// must exist within the site and use the MxGateway protocol; the value is
/// captured as <paramref name="ValueJson"/> interpreted per <paramref name="ValueType"/>.
/// Returns the newly-created <see cref="SecuredWriteDto"/>.
/// </summary>
/// <param name="SiteId">Site identifier the write targets.</param>
/// <param name="ConnectionName">Data connection name within the site.</param>
/// <param name="TagPath">Fully-qualified tag path the value is written to.</param>
/// <param name="ValueJson">JSON-serialised value to write.</param>
/// <param name="ValueType">Target data type name (e.g. <c>Boolean</c>, <c>Double</c>).</param>
/// <param name="Comment">Optional free-text comment supplied by the operator.</param>
public record SubmitSecuredWriteCommand(
    string SiteId,
    string ConnectionName,
    string TagPath,
    string ValueJson,
    string ValueType,
    string? Comment);

/// <summary>
/// Verifier request to approve (and execute) a pending
/// secured write. Declared here so the secured-write contract is complete; the
/// approve→execute relay handler and dispatch arm are implemented separately.
/// </summary>
/// <param name="Id">Identity of the pending secured write.</param>
/// <param name="Comment">Optional free-text comment supplied by the verifier.</param>
public record ApproveSecuredWriteCommand(long Id, string? Comment);

/// <summary>
/// Verifier request to reject a pending secured write. The write must still be
/// <c>Pending</c>, and the verifier must differ from the submitting operator
/// (separation of duties). Returns the updated <see cref="SecuredWriteDto"/>.
/// </summary>
/// <param name="Id">Identity of the pending secured write.</param>
/// <param name="Comment">Optional free-text comment supplied by the verifier.</param>
public record RejectSecuredWriteCommand(long Id, string? Comment);

/// <summary>
/// Read-only query for secured writes, optionally filtered by status and site,
/// with offset paging. A <c>null</c> filter matches every row. The <paramref name="Skip"/>
/// / <paramref name="Take"/> defaults preserve the historical unpaged wire behaviour
/// (first 200 rows) for callers that omit them (additive evolution).
/// </summary>
/// <param name="Status">Status filter; <c>null</c> matches every status.</param>
/// <param name="SiteId">Site id filter; <c>null</c> matches every site.</param>
/// <param name="Skip">Number of rows to skip (offset paging); clamped to &gt;= 0 server-side.</param>
/// <param name="Take">Maximum rows to return; clamped to 1..500 server-side. Default 200.</param>
public record ListSecuredWritesCommand(string? Status, string? SiteId, int Skip = 0, int Take = 200);

/// <summary>
/// Result projection of a single pending secured write row, mirroring the
/// <c>PendingSecuredWrite</c> entity shape.
/// </summary>
public record SecuredWriteDto(
    long Id,
    string SiteId,
    string ConnectionName,
    string TagPath,
    string ValueJson,
    string ValueType,
    string Status,
    string OperatorUser,
    string? OperatorComment,
    DateTime SubmittedAtUtc,
    string? VerifierUser,
    string? VerifierComment,
    DateTime? DecidedAtUtc,
    DateTime? ExecutedAtUtc,
    string? ExecutionError);

/// <summary>
/// Result wrapper for <see cref="ListSecuredWritesCommand"/>. <paramref name="TotalCount"/>
/// is the count of rows matching the query filters ignoring paging, so the UI can render
/// a pager independent of the returned page size.
/// </summary>
/// <param name="Items">The page of matching secured-write rows.</param>
/// <param name="TotalCount">Total number of rows matching the filters (unpaged).</param>
public record SecuredWriteListResult(IReadOnlyList<SecuredWriteDto> Items, int TotalCount);
