package main

import (
	"context"
	"fmt"
	"path/filepath"

	"github.com/spf13/cobra"

	mcpv1 "git.wntrmute.dev/mc/mcp/gen/mcp/v1"
	"git.wntrmute.dev/mc/mcp/internal/config"
	"git.wntrmute.dev/mc/mcp/internal/servicedef"
)

func stopCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "stop <service>",
		Short: "Stop all components, set active=false",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			cfg, err := config.LoadCLIConfig(cfgPath)
			if err != nil {
				return fmt.Errorf("load config: %w", err)
			}

			serviceName := args[0]
			defPath := filepath.Join(cfg.Services.Dir, serviceName+".toml")

			def, err := servicedef.Load(defPath)
			if err != nil {
				return fmt.Errorf("load service def: %w", err)
			}

			active := false
			def.Active = &active
			if err := servicedef.Write(defPath, def); err != nil {
				return fmt.Errorf("write service def: %w", err)
			}

			address, err := findNodeAddress(cfg, def.Node)
			if err != nil {
				return err
			}

			client, conn, err := dialAgent(address, cfg)
			if err != nil {
				return fmt.Errorf("dial agent: %w", err)
			}
			defer func() { _ = conn.Close() }()

			resp, err := client.StopService(context.Background(), &mcpv1.StopServiceRequest{
				Name: serviceName,
			})
			if err != nil {
				return fmt.Errorf("stop service: %w", err)
			}

			printComponentResults(resp.GetResults())
			return nil
		},
	}
}

func startCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "start <service>",
		Short: "Start all components, set active=true",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			cfg, err := config.LoadCLIConfig(cfgPath)
			if err != nil {
				return fmt.Errorf("load config: %w", err)
			}

			serviceName := args[0]
			defPath := filepath.Join(cfg.Services.Dir, serviceName+".toml")

			def, err := servicedef.Load(defPath)
			if err != nil {
				return fmt.Errorf("load service def: %w", err)
			}

			active := true
			def.Active = &active
			if err := servicedef.Write(defPath, def); err != nil {
				return fmt.Errorf("write service def: %w", err)
			}

			address, err := findNodeAddress(cfg, def.Node)
			if err != nil {
				return err
			}

			client, conn, err := dialAgent(address, cfg)
			if err != nil {
				return fmt.Errorf("dial agent: %w", err)
			}
			defer func() { _ = conn.Close() }()

			resp, err := client.StartService(context.Background(), &mcpv1.StartServiceRequest{
				Name: serviceName,
			})
			if err != nil {
				return fmt.Errorf("start service: %w", err)
			}

			printComponentResults(resp.GetResults())
			return nil
		},
	}
}

func restartCmd() *cobra.Command {
	return &cobra.Command{
		Use:   "restart <service>",
		Short: "Restart all components",
		Args:  cobra.ExactArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			cfg, err := config.LoadCLIConfig(cfgPath)
			if err != nil {
				return fmt.Errorf("load config: %w", err)
			}

			serviceName := args[0]
			defPath := filepath.Join(cfg.Services.Dir, serviceName+".toml")

			def, err := servicedef.Load(defPath)
			if err != nil {
				return fmt.Errorf("load service def: %w", err)
			}

			address, err := findNodeAddress(cfg, def.Node)
			if err != nil {
				return err
			}

			client, conn, err := dialAgent(address, cfg)
			if err != nil {
				return fmt.Errorf("dial agent: %w", err)
			}
			defer func() { _ = conn.Close() }()

			resp, err := client.RestartService(context.Background(), &mcpv1.RestartServiceRequest{
				Name: serviceName,
			})
			if err != nil {
				return fmt.Errorf("restart service: %w", err)
			}

			printComponentResults(resp.GetResults())
			return nil
		},
	}
}
