using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using CliFx;
using CliFx.Attributes;
using CliFx.Infrastructure;
using ArchestrA.GRAccess;
using Newtonsoft.Json;
using ZB.MOM.WW.GRAccess.Cli.GRAccess;
using ZB.MOM.WW.GRAccess.Cli.Protocol;
using ZB.MOM.WW.GRAccess.Cli.Session;

namespace ZB.MOM.WW.GRAccess.Cli.Commands.Galaxy
{
    [Command("galaxy list", Description = "List available galaxies on a GR node")]
    public class GalaxyListCommand : ICommand
    {
        [CommandOption("node", 'n', Description = "GR node name (blank = local node)")]
        public string NodeName { get; init; } = "";

        [CommandOption("json", Description = "Output as JSON")]
        public bool Json { get; init; }

        [CommandOption("llm-json", Description = "Output stable machine JSON envelope")]
        public bool LlmJson { get; init; }

        public async ValueTask ExecuteAsync(IConsole console)
        {
            // This command always runs one-shot — no galaxy login needed,
            // so no session routing (session is galaxy-specific).
            var galaxyNames = ListGalaxies(NodeName);

            if (LlmJson)
            {
                await console.Output.WriteLineAsync(LlmResponse.Ok("galaxy list", string.Empty, NodeName, galaxyNames)).ConfigureAwait(false);
                return;
            }

            if (Json)
            {
                var json = JsonConvert.SerializeObject(galaxyNames, Formatting.Indented);
                await console.Output.WriteLineAsync(json).ConfigureAwait(false);
            }
            else
            {
                foreach (var name in galaxyNames)
                    await console.Output.WriteLineAsync(name).ConfigureAwait(false);
            }
        }

        internal static List<string> ListGalaxies(string nodeName)
        {
            nodeName = GRAccessDiagnostics.NormalizeNodeName(nodeName);

            var grAccess = new GRAccessAppClass();

            var galaxies = grAccess.QueryGalaxies(nodeName);

            var result = grAccess.CommandResult;
            if (result != null && !result.Successful)
            {
                throw new InvalidOperationException(
                    GRAccessDiagnostics.FormatCommandResult("QueryGalaxies", result));
            }

            var names = new List<string>();
            if (galaxies != null)
            {
                for (int i = 1; i <= galaxies.count; i++)
                {
                    var galaxy = galaxies[i];
                    if (galaxy != null)
                        names.Add(galaxy.Name);
                }
            }

            return names;
        }
    }
}
