package cmd

import (
	"fmt"
	"path/filepath"

	"github.com/spf13/cobra"
	"github.com/steveyegge/gastown/internal/beads"
	"github.com/steveyegge/gastown/internal/config"
	"github.com/steveyegge/gastown/internal/crew"
	"github.com/steveyegge/gastown/internal/git"
	"github.com/steveyegge/gastown/internal/rig"
	"github.com/steveyegge/gastown/internal/style"
	"github.com/steveyegge/gastown/internal/workspace"
)

func runCrewAdd(cmd *cobra.Command, args []string) error {
	// Find workspace first (needed for all names)
	townRoot, err := workspace.FindFromCwdOrError()
	if err != nil {
		return fmt.Errorf("not in a Gas Town workspace: %w", err)
	}

	// Load rigs config
	rigsConfigPath := filepath.Join(townRoot, "mayor", "rigs.json")
	rigsConfig, err := config.LoadRigsConfig(rigsConfigPath)
	if err != nil {
		rigsConfig = &config.RigsConfig{Rigs: make(map[string]config.RigEntry)}
	}

	// Determine base rig from --rig flag or first name's rig/name format
	baseRig := crewRig
	if baseRig == "" {
		// Check if first arg has rig/name format
		if parsedRig, _, ok := parseRigSlashName(args[0]); ok {
			baseRig = parsedRig
		}
	}
	if baseRig == "" {
		// Try to infer from cwd
		baseRig, err = inferRigFromCwd(townRoot)
		if err != nil {
			return fmt.Errorf("could not determine rig (use --rig flag): %w", err)
		}
	}

	// Get rig
	g := git.NewGit(townRoot)
	rigMgr := rig.NewManager(townRoot, rigsConfig, g)
	r, err := rigMgr.GetRig(baseRig)
	if err != nil {
		return fmt.Errorf("rig '%s' not found", baseRig)
	}

	// Create crew manager
	crewGit := git.NewGit(r.Path)
	crewMgr := crew.NewManager(r, crewGit)

	bd := beads.New(beads.ResolveBeadsDir(r.Path))

	// Track results
	var created []string
	var failed []string
	var lastWorker *crew.CrewWorker

	// Process each name
	for _, arg := range args {
		name := arg
		rigName := baseRig

		// Parse rig/name format (e.g., "beads/emma" -> rig=beads, name=emma)
		if parsedRig, crewName, ok := parseRigSlashName(arg); ok {
			// For rig/name format, use that rig (but warn if different from base)
			if parsedRig != baseRig {
				style.PrintWarning("%s: different rig '%s' ignored (use --rig to change)", arg, parsedRig)
			}
			name = crewName
		}

		// Create crew workspace
		fmt.Printf("Creating crew workspace %s in %s...\n", name, rigName)

		worker, err := crewMgr.Add(name, crewBranch)
		if err != nil {
			if err == crew.ErrCrewExists {
				style.PrintWarning("crew workspace '%s' already exists, skipping", name)
				failed = append(failed, name+" (exists)")
				continue
			}
			style.PrintWarning("creating crew workspace '%s': %v", name, err)
			failed = append(failed, name)
			continue
		}

		fmt.Printf("%s Created crew workspace: %s/%s\n",
			style.Bold.Render("✓"), rigName, name)
		fmt.Printf("  Path: %s\n", worker.ClonePath)
		fmt.Printf("  Branch: %s\n", worker.Branch)

		// Create agent bead for the crew worker
		prefix := beads.GetPrefixForRig(townRoot, rigName)
		crewID := beads.CrewBeadIDWithPrefix(prefix, rigName, name)
		if _, err := bd.Show(crewID); err != nil {
			// Agent bead doesn't exist, create it
			fields := &beads.AgentFields{
				RoleType:   "crew",
				Rig:        rigName,
				AgentState: "idle",
				RoleBead:   beads.RoleBeadIDTown("crew"),
			}
			desc := fmt.Sprintf("Crew worker %s in %s - human-managed persistent workspace.", name, rigName)
			if _, err := bd.CreateAgentBead(crewID, desc, fields); err != nil {
				style.PrintWarning("could not create agent bead for %s: %v", name, err)
			} else {
				fmt.Printf("  Agent bead: %s\n", crewID)
			}
		}

		created = append(created, name)
		lastWorker = worker
		fmt.Println()
	}

	// Summary
	if len(created) > 0 {
		fmt.Printf("%s Created %d crew workspace(s): %v\n",
			style.Bold.Render("✓"), len(created), created)
		if lastWorker != nil && len(created) == 1 {
			fmt.Printf("\n%s\n", style.Dim.Render("Start working with: cd "+lastWorker.ClonePath))
		}
	}
	if len(failed) > 0 {
		fmt.Printf("%s Failed to create %d workspace(s): %v\n",
			style.Warning.Render("!"), len(failed), failed)
	}

	// Return error if all failed
	if len(created) == 0 && len(failed) > 0 {
		return fmt.Errorf("failed to create any crew workspaces")
	}

	return nil
}
