package cmd

import (
	"context"
	"fmt"
	"os"

	"gogs.dmsc.dev/arp/arp_cli/client"
	"gogs.dmsc.dev/arp/arp_cli/config"

	"github.com/urfave/cli/v3"
)

var (
	// Global flags
	urlFlag = &cli.StringFlag{
		Name:    "url",
		Aliases: []string{"u"},
		Usage:   "ARP server URL",
		Sources: cli.EnvVars("ARP_URL"),
	}
	outputFlag = &cli.StringFlag{
		Name:    "output",
		Aliases: []string{"o"},
		Usage:   "Output format (table, json, quiet)",
		Value:   "table",
	}
)

// GetClient creates a GraphQL client with the configured URL and token
func GetClient(ctx context.Context, cmd *cli.Command) (*client.Client, error) {
	cfg, err := config.Load()
	if err != nil {
		return nil, fmt.Errorf("failed to load config: %w", err)
	}

	// Command flag takes precedence, then config, then empty
	serverURL := cmd.String(urlFlag.Name)
	if serverURL == "" {
		serverURL = cfg.ServerURL
	}
	if serverURL == "" {
		return nil, fmt.Errorf("no server URL configured. Use --url flag or run 'arp_cli login' first")
	}

	c := client.New(serverURL)
	if cfg.Token != "" {
		c.SetToken(cfg.Token)
	}

	return c, nil
}

// RequireAuth ensures the user is authenticated
func RequireAuth(cfg *config.Config) error {
	if cfg.Token == "" {
		return fmt.Errorf("not authenticated. Run 'arp_cli login' first")
	}
	return nil
}

// RootCommand returns the root CLI command
func RootCommand() *cli.Command {
	return &cli.Command{
		Name:  "arp_cli",
		Usage: "Command-line interface for ARP (Agent-native ERP) server",
		Description: `arp_cli is a command-line tool for interacting with the ARP GraphQL API.

It provides CRUD operations for managing users, services, tasks, notes,
messages, roles, and permissions. The CLI also supports real-time subscriptions
for task and message events.

Start by running 'arp_cli login' to authenticate with your ARP server.`,
		Flags: []cli.Flag{
			urlFlag,
			outputFlag,
		},
		Commands: []*cli.Command{
			LoginCommand(),
			ConfigCommand(),
			ServiceCommand(),
			UserCommand(),
			NoteCommand(),
			TaskCommand(),
			MessageCommand(),
			RoleCommand(),
			PermissionCommand(),
			WorkflowCommand(),
		},
		Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
			// Set default output format in context if needed
			return ctx, nil
		},
		Action: func(ctx context.Context, cmd *cli.Command) error {
			// Show help when no subcommand is provided
			return cli.ShowAppHelp(cmd)
		},
	}
}

// Run executes the CLI
func Run() error {
	cmd := RootCommand()
	return cmd.Run(context.Background(), os.Args)
}
