// ABOUTME: Quick-add command for adding a repo to Gas Town with minimal friction.
// ABOUTME: Used by shell hook for automatic "add to Gas Town?" prompts.

package cmd

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/spf13/cobra"
	"github.com/steveyegge/gastown/internal/style"
	"github.com/steveyegge/gastown/internal/workspace"
)

var (
	quickAddUser  string
	quickAddYes   bool
	quickAddQuiet bool
)

var rigQuickAddCmd = &cobra.Command{
	Use:    "quick-add [path]",
	Short:  "Quickly add current repo to Gas Town",
	Hidden: true,
	Long: `Quickly add a git repository to Gas Town with minimal interaction.

This command is designed for the shell hook's "Add to Gas Town?" prompt.
It infers the rig name from the directory and git URL from the remote.

Examples:
  gt rig quick-add                    # Add current directory
  gt rig quick-add ~/Repos/myproject  # Add specific path
  gt rig quick-add --yes              # Non-interactive`,
	Args: cobra.MaximumNArgs(1),
	RunE: runRigQuickAdd,
}

func init() {
	rigCmd.AddCommand(rigQuickAddCmd)
	rigQuickAddCmd.Flags().StringVar(&quickAddUser, "user", "", "Crew workspace name (default: $USER)")
	rigQuickAddCmd.Flags().BoolVar(&quickAddYes, "yes", false, "Non-interactive, assume yes")
	rigQuickAddCmd.Flags().BoolVar(&quickAddQuiet, "quiet", false, "Minimal output")
}

func runRigQuickAdd(cmd *cobra.Command, args []string) error {
	targetPath := "."
	if len(args) > 0 {
		targetPath = args[0]
	}

	absPath, err := filepath.Abs(targetPath)
	if err != nil {
		return fmt.Errorf("resolving path: %w", err)
	}

	if townRoot, err := workspace.Find(absPath); err == nil && townRoot != "" {
		return fmt.Errorf("already part of a Gas Town workspace: %s", townRoot)
	}

	gitRoot, err := findGitRoot(absPath)
	if err != nil {
		return fmt.Errorf("not a git repository: %w", err)
	}

	gitURL, err := findGitRemoteURL(gitRoot)
	if err != nil {
		return fmt.Errorf("no git remote found: %w", err)
	}

	rigName := sanitizeRigName(filepath.Base(gitRoot))

	townRoot, err := findOrCreateTown()
	if err != nil {
		return fmt.Errorf("finding Gas Town: %w", err)
	}

	rigPath := filepath.Join(townRoot, rigName)
	if _, err := os.Stat(rigPath); err == nil {
		return fmt.Errorf("rig %q already exists in %s", rigName, townRoot)
	}

	originalName := filepath.Base(gitRoot)
	if rigName != originalName && !quickAddQuiet {
		fmt.Printf("Note: Using %q as rig name (sanitized from %q)\n", rigName, originalName)
	}

	if !quickAddQuiet {
		fmt.Printf("Adding %s to Gas Town...\n", style.Bold.Render(rigName))
		fmt.Printf("  Repository: %s\n", gitURL)
		fmt.Printf("  Town: %s\n", townRoot)
	}

	addArgs := []string{"rig", "add", rigName, gitURL}
	addCmd := exec.Command("gt", addArgs...)
	addCmd.Dir = townRoot
	addCmd.Stdout = os.Stdout
	addCmd.Stderr = os.Stderr
	if err := addCmd.Run(); err != nil {
		fmt.Printf("\n%s Failed to add rig. You can try manually:\n", style.Warning.Render("⚠"))
		fmt.Printf("  cd %s && gt rig add %s %s\n", townRoot, rigName, gitURL)
		return fmt.Errorf("gt rig add failed: %w", err)
	}

	user := quickAddUser
	if user == "" {
		user = os.Getenv("USER")
	}
	if user == "" {
		user = "default"
	}

	if !quickAddQuiet {
		fmt.Printf("\nCreating crew workspace for %s...\n", user)
	}

	crewArgs := []string{"crew", "add", user, "--rig", rigName}
	crewCmd := exec.Command("gt", crewArgs...)
	crewCmd.Dir = filepath.Join(townRoot, rigName)
	crewCmd.Stdout = os.Stdout
	crewCmd.Stderr = os.Stderr
	if err := crewCmd.Run(); err != nil {
		fmt.Printf("  %s Could not create crew workspace: %v\n", style.Dim.Render("⚠"), err)
		fmt.Printf("  Run manually: cd %s && gt crew add %s --rig %s\n", filepath.Join(townRoot, rigName), user, rigName)
	}

	crewPath := filepath.Join(townRoot, rigName, "crew", user)
	if !quickAddQuiet {
		fmt.Printf("\n%s Added to Gas Town!\n", style.Success.Render("✓"))
		fmt.Printf("\nYour workspace: %s\n", style.Bold.Render(crewPath))
	}

	fmt.Printf("GT_CREW_PATH=%s\n", crewPath)

	return nil
}

func findGitRoot(path string) (string, error) {
	cmd := exec.Command("git", "rev-parse", "--show-toplevel")
	cmd.Dir = path
	out, err := cmd.Output()
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(out)), nil
}

func findGitRemoteURL(gitRoot string) (string, error) {
	cmd := exec.Command("git", "remote", "get-url", "origin")
	cmd.Dir = gitRoot
	out, err := cmd.Output()
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(out)), nil
}

func sanitizeRigName(name string) string {
	name = strings.ReplaceAll(name, "-", "_")
	name = strings.ReplaceAll(name, ".", "_")
	name = strings.ReplaceAll(name, " ", "_")
	return name
}

func findOrCreateTown() (string, error) {
	home, err := os.UserHomeDir()
	if err != nil {
		return "", err
	}

	candidates := []string{
		filepath.Join(home, "gt"),
		filepath.Join(home, "gastown"),
	}

	for _, path := range candidates {
		mayorDir := filepath.Join(path, "mayor")
		if _, err := os.Stat(mayorDir); err == nil {
			return path, nil
		}
	}

	return "", fmt.Errorf("no Gas Town found - run 'gt install ~/gt' first")
}
