using System.CommandLine;
using VigilCare.Simulation;

public static class ReplayCommand
{
    public static Command Create()
    {
        var fileArg = new Argument<FileInfo>("scenario-file");
        var speedOpt = new Option<double>("--speed", () => 60, "Speed multiplier (0=instant, 1=realtime)");
        var baseUrlOpt = new Option<string>("--base-url", () => "http://localhost:5270");
        var pollOpt = new Option<bool>("--poll", () => false, "Poll alerts/scores after each cluster");
        var pollIntervalOpt = new Option<int>("--poll-interval", () => 5, "Seconds between polls");
        var usernameOpt = new Option<string>("--username", () => "physician.demo", "API login username");
        var passwordOpt = new Option<string>("--password", () => "DemoPhysician1!", "API login password");
        var gatewayOpt = new Option<bool>("--gateway", () => false,
            "Target ward gateway API (default base URL http://localhost:5081)");
        var encounterIdOpt = new Option<Guid?>("--encounter-id",
            "Use existing encounter (required for --gateway when replica already synced)");
        var skipSetupOpt = new Option<bool>("--skip-setup", () => false,
            "Skip patient/encounter registration — use --encounter-id");
        var gatewayTokenOpt = new Option<string?>("--gateway-token",
            "Bearer token for ward gateway (default: GATEWAY_JWT env var when --gateway)");

        var command = new Command("replay", "Replay a scenario against the API")
        {
            fileArg, speedOpt, baseUrlOpt, pollOpt, pollIntervalOpt, usernameOpt, passwordOpt,
            gatewayOpt, encounterIdOpt, skipSetupOpt, gatewayTokenOpt
        };

        command.SetHandler(async context =>
        {
            var file = context.ParseResult.GetValueForArgument(fileArg);
            var speed = context.ParseResult.GetValueForOption(speedOpt);
            var baseUrl = context.ParseResult.GetValueForOption(baseUrlOpt)!;
            var poll = context.ParseResult.GetValueForOption(pollOpt);
            var pollInterval = context.ParseResult.GetValueForOption(pollIntervalOpt);
            var username = context.ParseResult.GetValueForOption(usernameOpt)!;
            var password = context.ParseResult.GetValueForOption(passwordOpt)!;
            var gateway = context.ParseResult.GetValueForOption(gatewayOpt);
            var encounterId = context.ParseResult.GetValueForOption(encounterIdOpt);
            var skipSetup = context.ParseResult.GetValueForOption(skipSetupOpt);
            var gatewayToken = context.ParseResult.GetValueForOption(gatewayTokenOpt);

            var scenario = ScenarioLoader.Load(file.FullName);
            var errors = ScenarioValidator.Validate(scenario);
            if (errors.Count > 0)
            {
                SimulatorConsole.Error($"Scenario validation failed with {errors.Count} error(s):");
                foreach (var err in errors) SimulatorConsole.Error($"  • {err}");
                return;
            }

            if (skipSetup && !encounterId.HasValue)
            {
                SimulatorConsole.Error("--skip-setup requires --encounter-id");
                return;
            }

            if (gateway && !encounterId.HasValue)
            {
                SimulatorConsole.Error("--gateway requires --encounter-id");
                return;
            }

            var effectiveBaseUrl = gateway ? "http://localhost:5081" : baseUrl;
            using var http = new HttpClient { BaseAddress = new Uri(effectiveBaseUrl) };
            var client = new VigilCareApiClient(http);

            if (gateway)
            {
                var token = gatewayToken ?? Environment.GetEnvironmentVariable("GATEWAY_JWT");
                if (string.IsNullOrWhiteSpace(token))
                {
                    SimulatorConsole.Error(
                        "Gateway mode requires --gateway-token or GATEWAY_JWT (ward gateway has no /auth/login endpoint)");
                    return;
                }

                client.SetBearerToken(token);
                SimulatorConsole.Info("Using gateway bearer token.");
            }
            else
            {
                SimulatorConsole.Info($"Authenticating as {username}...");
                await client.LoginAsync(username, password);
                SimulatorConsole.Info("Authenticated.");
            }

            var poller = poll ? new ApiPoller(client) : null;
            var engine = new ReplayEngine(client, poller, new ConsoleReplayObserver());
            var options = new ReplayOptions(
                speed, poll, pollInterval, DryRun: false,
                Target: gateway ? ReplayTarget.Gateway : ReplayTarget.Central,
                ExistingEncounterId: encounterId);

            await engine.RunAsync(scenario, options);
        });

        return command;
    }
}