package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"gogs.dmsc.dev/arp/arp_cli/cmd"

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

func main() {
	// Create context with cancellation for graceful shutdown
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// Handle interrupt signals
	sigChan := make(chan os.Signal, 1)
	signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
	go func() {
		<-sigChan
		cancel()
	}()

	// Build the CLI app
	app := buildApp()

	// If no arguments provided (only program name), start REPL mode
	if len(os.Args) <= 1 {
		repl := cmd.NewREPL(app)
		if err := repl.Run(ctx); err != nil {
			fmt.Fprintf(os.Stderr, "Error: %v\n", err)
			os.Exit(1)
		}
		return
	}

	// Otherwise, run single command mode
	if err := app.Run(ctx, os.Args); err != nil {
		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
		os.Exit(1)
	}
}

func buildApp() *cli.Command {
	return &cli.Command{
		Name:  "arp_cli",
		Usage: "Command-line interface for ARP (Agent-native ERP)",
		Description: `ARP CLI is a command-line tool for interacting with ARP GraphQL servers.

It provides CRUD operations for Services, Users, Notes, Tasks, Messages,
Roles, and Permissions. Real-time updates are available via WebSocket subscriptions
for Tasks and Messages.

When run without arguments, it starts an interactive REPL mode.
Use 'exit' or 'quit' to leave the REPL, or Ctrl+D.

First, login to an ARP server using 'login' to store your credentials.
Then use the various commands to manage your ARP data.`,
		Version: "1.0.0",
		Flags: []cli.Flag{
			&cli.StringFlag{
				Name:    "url",
				Aliases: []string{"u"},
				Usage:   "ARP server URL",
				Sources: cli.EnvVars("ARP_URL"),
			},
			&cli.StringFlag{
				Name:    "output",
				Aliases: []string{"o"},
				Usage:   "Output format (table, json)",
				Value:   "table",
			},
		},
		Commands: []*cli.Command{
			cmd.LoginCommand(),
			cmd.ConfigCommand(),
			cmd.ServiceCommand(),
			cmd.UserCommand(),
			cmd.NoteCommand(),
			cmd.TaskCommand(),
			cmd.MessageCommand(),
			cmd.RoleCommand(),
			cmd.PermissionCommand(),
			cmd.WorkflowCommand(),
		},
		Before: func(ctx context.Context, command *cli.Command) (context.Context, error) {
			// Store global flags in context for later use
			return ctx, nil
		},
		Action: func(ctx context.Context, cmd *cli.Command) error {
			// Show help when no subcommand is provided
			return cli.ShowAppHelp(cmd)
		},
	}
}
