using ZB.MOM.WW.ScadaBridge.Commons.Entities.Schemas;

namespace ZB.MOM.WW.ScadaBridge.CentralUI.Services;

/// <summary>
/// Outcome of a single schema-library mutation dispatch (create / update / delete).
/// Wraps either success or a human-readable server error (a duplicate-name guard, an
/// invalid-JSON validation failure, or a not-found) so the schema-library page can
/// render an inline result rather than reasoning about transport exceptions or the
/// three management response shapes. Mirrors <see cref="DataConnectionMoveResult"/>.
/// </summary>
/// <param name="Success">Whether the mutation succeeded.</param>
/// <param name="Error">A human-readable error message when <paramref name="Success"/> is <c>false</c>; otherwise <c>null</c>.</param>
public record SchemaLibraryActionResult(bool Success, string? Error)
{
    /// <summary>Creates a successful result.</summary>
    /// <returns>A successful <see cref="SchemaLibraryActionResult"/>.</returns>
    public static SchemaLibraryActionResult Ok() => new(true, null);

    /// <summary>Creates a failed result carrying <paramref name="error"/>.</summary>
    /// <param name="error">The human-readable failure (typically a server guard / validation message).</param>
    /// <returns>A failed <see cref="SchemaLibraryActionResult"/>.</returns>
    public static SchemaLibraryActionResult Fail(string error) => new(false, error);
}

/// <summary>
/// CentralUI facade over the schema-library CRUD management commands. Every
/// mutation (<c>CreateSharedSchemaCommand</c> / <c>UpdateSharedSchemaCommand</c> /
/// <c>DeleteSharedSchemaCommand</c>) and the list query is dispatched to the central
/// <c>ManagementActor</c> through the in-process <c>ManagementActorHolder</c> seam — the
/// SAME Ask path the HTTP <c>/management</c> endpoint uses — so the server remains the
/// single enforcer of the Designer role gate, the unique-name guard, and JSON-Schema
/// validation. The page re-implements none of that: it lists, authors via
/// <c>SchemaBuilder</c>, and SUBMITS commands; any guard / validation failure comes back
/// as a classified <see cref="SchemaLibraryActionResult"/>.
/// </summary>
/// <remarks>
/// The current Blazor principal is projected to an <c>AuthenticatedUser</c> so the
/// server's role gate runs against the real identity. Mirrors
/// <c>IDataConnectionMoveService</c> / <c>ISecuredWriteService</c>.
/// </remarks>
public interface ISchemaLibraryService
{
    /// <summary>
    /// Lists every library schema (name-ordered) via the read-gated
    /// <c>ListSharedSchemasCommand</c>. A read failure yields an empty list (logged) so
    /// the page renders gracefully.
    /// </summary>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task resolving to the library entries, or an empty list on failure.</returns>
    Task<IReadOnlyList<SharedSchema>> ListAsync(CancellationToken cancellationToken = default);

    /// <summary>
    /// Creates a library schema via the Designer-gated <c>CreateSharedSchemaCommand</c>.
    /// </summary>
    /// <param name="name">The unique schema name.</param>
    /// <param name="scope">An optional scope discriminator (<c>null</c> = global).</param>
    /// <param name="schemaJson">The JSON Schema document text.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task resolving to a classified create outcome.</returns>
    Task<SchemaLibraryActionResult> CreateAsync(
        string name, string? scope, string schemaJson, CancellationToken cancellationToken = default);

    /// <summary>
    /// Updates a library schema via the Designer-gated <c>UpdateSharedSchemaCommand</c>.
    /// </summary>
    /// <param name="id">Primary key of the schema to update.</param>
    /// <param name="name">The (possibly renamed) unique schema name.</param>
    /// <param name="scope">An optional scope discriminator (<c>null</c> = global).</param>
    /// <param name="schemaJson">The JSON Schema document text.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task resolving to a classified update outcome.</returns>
    Task<SchemaLibraryActionResult> UpdateAsync(
        int id, string name, string? scope, string schemaJson, CancellationToken cancellationToken = default);

    /// <summary>
    /// Deletes a library schema via the Designer-gated <c>DeleteSharedSchemaCommand</c>.
    /// </summary>
    /// <param name="id">Primary key of the schema to delete.</param>
    /// <param name="cancellationToken">Cancellation token.</param>
    /// <returns>A task resolving to a classified delete outcome.</returns>
    Task<SchemaLibraryActionResult> DeleteAsync(int id, CancellationToken cancellationToken = default);
}
