using System.CommandLine;
using System.CommandLine.Parsing;
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Management;

namespace ZB.MOM.WW.ScadaBridge.CLI.Commands;

/// <summary>
/// Builds the <c>secured-write</c> command group. Currently exposes the read-only
/// <c>list</c> sub-command, which relays a <see cref="ListSecuredWritesCommand"/> to the
/// central <c>ManagementActor</c> (gated any-of <c>Operator</c> / <c>Verifier</c> /
/// <c>Administrator</c>). The list is offset-paged via <c>--skip</c> / <c>--take</c>
/// (arch-review P3); omitting them preserves the historical unpaged default (first 200 rows).
/// </summary>
public static class SecuredWriteCommands
{
    // Options are static so the parsed values can be read back from both the SetAction
    // and the internal BuildListCommand helper (used by command-construction tests).
    private static readonly Option<string?> StatusOption =
        new("--status") { Description = "Filter by status (e.g. Pending, Approved, Rejected, Expired, Executed, Failed); omit to match all" };
    private static readonly Option<string?> SiteOption =
        new("--site") { Description = "Filter by site identifier; omit to match all sites" };
    private static readonly Option<int> SkipOption =
        new("--skip") { Description = "Number of rows to skip (offset paging)", DefaultValueFactory = _ => 0 };
    private static readonly Option<int> TakeOption =
        new("--take") { Description = "Maximum rows to return (clamped to 1..500 server-side)", DefaultValueFactory = _ => 200 };

    /// <summary>Builds the <c>secured-write</c> command group with its <c>list</c> sub-command.</summary>
    /// <param name="urlOption">Global <c>--url</c> option for the management API endpoint.</param>
    /// <param name="formatOption">Global <c>--format</c> option for output format.</param>
    /// <param name="usernameOption">Global <c>--username</c> option for authentication.</param>
    /// <param name="passwordOption">Global <c>--password</c> option for authentication.</param>
    /// <returns>The configured <c>secured-write</c> command.</returns>
    public static Command Build(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
    {
        var command = new Command("secured-write") { Description = "Query two-person (MxGateway) secured writes" };
        command.Add(BuildList(urlOption, formatOption, usernameOption, passwordOption));
        return command;
    }

    private static Command BuildList(Option<string> urlOption, Option<string> formatOption, Option<string> usernameOption, Option<string> passwordOption)
    {
        var cmd = new Command("list") { Description = "List secured writes (pending queue + terminal history), optionally filtered and paged" };
        cmd.Add(StatusOption);
        cmd.Add(SiteOption);
        cmd.Add(SkipOption);
        cmd.Add(TakeOption);
        cmd.SetAction(async (ParseResult result) =>
        {
            return await CommandHelpers.ExecuteCommandAsync(
                result, urlOption, formatOption, usernameOption, passwordOption,
                BuildListCommand(result));
        });
        return cmd;
    }

    /// <summary>
    /// Builds a <see cref="ListSecuredWritesCommand"/> from a parsed <c>secured-write list</c>
    /// invocation. Exposed internally so command-construction tests can assert field mapping
    /// (including the <c>--skip</c> / <c>--take</c> paging options) without triggering the HTTP call.
    /// </summary>
    /// <param name="result">The parsed command-line result from the <c>secured-write list</c> invocation.</param>
    /// <returns>A <see cref="ListSecuredWritesCommand"/> populated from the parsed result.</returns>
    internal static ListSecuredWritesCommand BuildListCommand(ParseResult result)
    {
        var status = result.GetValue(StatusOption);
        var site = result.GetValue(SiteOption);
        var skip = result.GetValue(SkipOption);
        var take = result.GetValue(TakeOption);
        return new ListSecuredWritesCommand(status, site, skip, take);
    }
}
