package cli

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"

	"drip/internal/shared/ui"
	"github.com/spf13/cobra"
)

var interactiveMode bool

var listCmd = &cobra.Command{
	Use:   "list",
	Short: "List all running background tunnels",
	Long: `List all running background tunnels.

Example:
  drip list                     Show all running tunnels
  drip list -i                  Interactive mode (select to attach/stop)

This command shows:
  - Tunnel type (HTTP/HTTPS/TCP)
  - Local port being tunneled
  - Public URL
  - Process ID (PID)
  - Uptime

In interactive mode, you can select a tunnel to:
  - Attach: View real-time logs
  - Stop: Terminate the tunnel`,
	Aliases: []string{"ls", "ps", "status"},
	RunE:    runList,
}

func init() {
	listCmd.Flags().BoolVarP(&interactiveMode, "interactive", "i", false, "Interactive mode for attach/stop")
	rootCmd.AddCommand(listCmd)
}

func runList(_ *cobra.Command, _ []string) error {
	CleanupStaleDaemons()

	daemons, err := ListAllDaemons()
	if err != nil {
		return fmt.Errorf("failed to list daemons: %w", err)
	}

	if len(daemons) == 0 {
		fmt.Println()
		fmt.Println(ui.Info(
			"No Running Tunnels",
			"",
			ui.Muted("Start a tunnel in background with:"),
			"",
			ui.Cyan("  drip http 3000 -d"),
			ui.Cyan("  drip tcp 5432 -d"),
		))
		return nil
	}

	table := ui.NewTable([]string{"#", "TYPE", "PORT", "URL", "PID", "UPTIME"}).
		WithTitle("Running Tunnels")

	idx := 1
	for _, d := range daemons {
		if !IsProcessRunning(d.PID) {
			RemoveDaemonInfo(d.Type, d.Port)
			continue
		}

		uptime := time.Since(d.StartTime)

		var typeStr string
		if d.Type == "http" {
			typeStr = ui.Highlight("HTTP")
		} else if d.Type == "https" {
			typeStr = ui.Highlight("HTTPS")
		} else {
			typeStr = ui.Cyan("TCP")
		}

		table.AddRow([]string{
			ui.Highlight(fmt.Sprintf("%d", idx)),
			typeStr,
			fmt.Sprintf("%d", d.Port),
			ui.URL(d.URL),
			ui.Muted(fmt.Sprintf("%d", d.PID)),
			FormatDuration(uptime),
		})
		idx++
	}

	fmt.Print(table.Render())

	if interactiveMode {
		return runInteractiveList(daemons)
	}

	fmt.Println(ui.Muted("Commands:"))
	fmt.Println(ui.RenderList([]string{
		ui.Cyan("drip list -i") + ui.Muted("               Interactive mode"),
		ui.Cyan("drip attach http 3000") + ui.Muted("      Attach to tunnel (view logs)"),
		ui.Cyan("drip stop http 3000") + ui.Muted("        Stop tunnel"),
		ui.Cyan("drip stop all") + ui.Muted("              Stop all tunnels"),
	}))

	return nil
}

func runInteractiveList(daemons []*DaemonInfo) error {
	var runningDaemons []*DaemonInfo
	for _, d := range daemons {
		if IsProcessRunning(d.PID) {
			runningDaemons = append(runningDaemons, d)
		} else {
			RemoveDaemonInfo(d.Type, d.Port)
		}
	}

	if len(runningDaemons) == 0 {
		return nil
	}

	fmt.Println()
	fmt.Print(ui.Muted("Select a tunnel (number) or 'q' to quit: "))
	reader := bufio.NewReader(os.Stdin)
	input, err := reader.ReadString('\n')
	if err != nil {
		return fmt.Errorf("failed to read input: %w", err)
	}

	input = strings.TrimSpace(input)
	if input == "" || input == "q" || input == "Q" {
		return nil
	}

	selection, err := strconv.Atoi(input)
	if err != nil || selection < 1 || selection > len(runningDaemons) {
		return fmt.Errorf("invalid selection: %s", input)
	}

	selectedDaemon := runningDaemons[selection-1]

	fmt.Println()
	fmt.Println(ui.Info(
		fmt.Sprintf("Selected: %s tunnel on port %d", strings.ToUpper(selectedDaemon.Type), selectedDaemon.Port),
		"",
		ui.Muted("What would you like to do?"),
		"",
		ui.Cyan("  1.")+" Attach (view logs)",
		ui.Cyan("  2.")+" Stop tunnel",
		ui.Muted("  q.")+" Cancel",
	))

	fmt.Print(ui.Muted("Choose an action: "))

	actionInput, err := reader.ReadString('\n')
	if err != nil {
		return fmt.Errorf("failed to read input: %w", err)
	}

	actionInput = strings.TrimSpace(actionInput)
	switch actionInput {
	case "1":
		return attachToDaemon(selectedDaemon)
	case "2":
		return stopDaemon(selectedDaemon.Type, selectedDaemon.Port)
	case "q", "Q", "":
		return nil
	default:
		return fmt.Errorf("invalid action: %s", actionInput)
	}
}
