package edgecmd

import (
	"fmt"
	"sort"
	"strings"

	"github.com/spf13/cobra"

	"iop/packages/go/config"
)

func nodesCmd() *cobra.Command {
	c := &cobra.Command{
		Use:   "nodes",
		Short: "Inspect registered edge nodes",
		Long:  `Inspect and list configured or connected execution nodes.`,
	}
	c.AddCommand(nodesListCmd())
	return c
}

func nodesListCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "list",
		Short: "List configured edge nodes and connection status",
		Long: `List all nodes registered in the edge configuration file.
When the server is offline or this command is run standalone, all nodes will show their status as 'offline' or 'configured'.`,
		Example: `  iop-edge nodes list`,
		RunE: func(cmd *cobra.Command, _ []string) error {
			cfg, path, err := LoadEdgeConfig(cmd)
			if err != nil {
				return err
			}
			fmt.Fprintf(cmd.OutOrStdout(), "Config Source: %s\n\n", path)
			if len(cfg.Nodes) == 0 {
				fmt.Fprintln(cmd.OutOrStdout(), "No nodes configured.")
				return nil
			}

			nodes := make([]config.NodeDefinition, len(cfg.Nodes))
			copy(nodes, cfg.Nodes)
			sort.Slice(nodes, func(i, j int) bool {
				return nodes[i].ID < nodes[j].ID
			})

			fmt.Fprintf(cmd.OutOrStdout(), "%-25s %-20s %-40s %-12s\n", "NODE ID", "ALIAS", "TOKEN", "STATUS")
			fmt.Fprintf(cmd.OutOrStdout(), "%s\n", strings.Repeat("-", 100))
			for _, n := range nodes {
				fmt.Fprintf(cmd.OutOrStdout(), "%-25s %-20s %-40s %-12s\n", n.ID, n.Alias, n.Token, "offline (configured)")
				if summary := formatConfiguredProviders(n.Providers); summary != "" {
					fmt.Fprintf(cmd.OutOrStdout(), "  providers: %s\n", summary)
				}
			}
			return nil
		},
	}
}

func formatConfiguredProviders(providers []config.NodeProviderConf) string {
	if len(providers) == 0 {
		return ""
	}
	summaries := make([]string, 0, len(providers))
	for _, p := range providers {
		if p.ID == "" {
			continue
		}
		parts := []string{p.ID}
		if p.Type != "" || p.Category != "" {
			typeCategory := string(p.Category)
			if p.Type != "" && typeCategory != "" {
				typeCategory = p.Type + "/" + typeCategory
			} else if p.Type != "" {
				typeCategory = p.Type
			}
			parts = append(parts, "type="+typeCategory)
		}
		if len(p.Models) > 0 {
			parts = append(parts, "models="+strings.Join(p.Models, ","))
		}
		if p.Capacity > 0 {
			parts = append(parts, fmt.Sprintf("capacity=%d", p.Capacity))
		}
		if len(p.LifecycleCapabilities) > 0 {
			parts = append(parts, "lifecycle="+strings.Join(p.LifecycleCapabilities, ","))
		}
		summaries = append(summaries, strings.Join(parts, " "))
	}
	return strings.Join(summaries, "; ")
}
