package cmd

import (
	"fmt"

	"github.com/spf13/cobra"
	"github.com/steveyegge/gastown/internal/refinery"
	"github.com/steveyegge/gastown/internal/style"
	"github.com/steveyegge/gastown/internal/tmux"
	"github.com/steveyegge/gastown/internal/wisp"
	"github.com/steveyegge/gastown/internal/witness"
)

// RigStatusKey is the wisp config key for rig operational status.
const RigStatusKey = "status"

// RigStatusParked is the value indicating a rig is parked.
const RigStatusParked = "parked"

var rigParkCmd = &cobra.Command{
	Use:   "park <rig>",
	Short: "Park a rig (stops agents, daemon won't auto-restart)",
	Long: `Park a rig to temporarily disable it.

Parking a rig:
  - Stops the witness if running
  - Stops the refinery if running
  - Sets status=parked in the wisp layer (local/ephemeral)
  - The daemon respects this status and won't auto-restart agents

This is a Level 1 (local/ephemeral) operation:
  - Only affects this town
  - Disappears on wisp cleanup
  - Use 'gt rig unpark' to resume normal operation

Examples:
  gt rig park gastown
  gt rig park beads`,
	Args: cobra.ExactArgs(1),
	RunE: runRigPark,
}

var rigUnparkCmd = &cobra.Command{
	Use:   "unpark <rig>",
	Short: "Unpark a rig (allow daemon to auto-restart agents)",
	Long: `Unpark a rig to resume normal operation.

Unparking a rig:
  - Removes the parked status from the wisp layer
  - Allows the daemon to auto-restart agents
  - Does NOT automatically start agents (use 'gt rig start' for that)

Examples:
  gt rig unpark gastown
  gt rig unpark beads`,
	Args: cobra.ExactArgs(1),
	RunE: runRigUnpark,
}

func init() {
	rigCmd.AddCommand(rigParkCmd)
	rigCmd.AddCommand(rigUnparkCmd)
}

func runRigPark(cmd *cobra.Command, args []string) error {
	rigName := args[0]

	// Get rig and town root
	townRoot, r, err := getRig(rigName)
	if err != nil {
		return err
	}

	fmt.Printf("Parking rig %s...\n", style.Bold.Render(rigName))

	var stoppedAgents []string

	t := tmux.NewTmux()

	// Stop witness if running
	witnessSession := fmt.Sprintf("gt-%s-witness", rigName)
	witnessRunning, _ := t.HasSession(witnessSession)
	if witnessRunning {
		fmt.Printf("  Stopping witness...\n")
		witMgr := witness.NewManager(r)
		if err := witMgr.Stop(); err != nil {
			fmt.Printf("  %s Failed to stop witness: %v\n", style.Warning.Render("!"), err)
		} else {
			stoppedAgents = append(stoppedAgents, "Witness stopped")
		}
	}

	// Stop refinery if running
	refinerySession := fmt.Sprintf("gt-%s-refinery", rigName)
	refineryRunning, _ := t.HasSession(refinerySession)
	if refineryRunning {
		fmt.Printf("  Stopping refinery...\n")
		refMgr := refinery.NewManager(r)
		if err := refMgr.Stop(); err != nil {
			fmt.Printf("  %s Failed to stop refinery: %v\n", style.Warning.Render("!"), err)
		} else {
			stoppedAgents = append(stoppedAgents, "Refinery stopped")
		}
	}

	// Set parked status in wisp layer
	wispCfg := wisp.NewConfig(townRoot, rigName)
	if err := wispCfg.Set(RigStatusKey, RigStatusParked); err != nil {
		return fmt.Errorf("setting parked status: %w", err)
	}

	// Output
	fmt.Printf("%s Rig %s parked (local only)\n", style.Success.Render("✓"), rigName)
	for _, msg := range stoppedAgents {
		fmt.Printf("  %s\n", msg)
	}
	fmt.Printf("  Daemon will not auto-restart\n")

	return nil
}

func runRigUnpark(cmd *cobra.Command, args []string) error {
	rigName := args[0]

	// Get rig and town root
	townRoot, _, err := getRig(rigName)
	if err != nil {
		return err
	}

	// Remove parked status from wisp layer
	wispCfg := wisp.NewConfig(townRoot, rigName)
	if err := wispCfg.Unset(RigStatusKey); err != nil {
		return fmt.Errorf("clearing parked status: %w", err)
	}

	fmt.Printf("%s Rig %s unparked\n", style.Success.Render("✓"), rigName)
	fmt.Printf("  Daemon can now auto-restart agents\n")
	fmt.Printf("  Use '%s' to start agents immediately\n", style.Dim.Render("gt rig start "+rigName))

	return nil
}

// IsRigParked checks if a rig is parked in the wisp layer.
// This function is exported for use by the daemon.
func IsRigParked(townRoot, rigName string) bool {
	wispCfg := wisp.NewConfig(townRoot, rigName)
	return wispCfg.GetString(RigStatusKey) == RigStatusParked
}
