package cmd

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

	"bdev/internal/config"
	"bdev/internal/git"
	"bdev/internal/ui"

	"github.com/spf13/cobra"
)

var initCmd = &cobra.Command{
	Use:   "init",
	Short: "Initialize a Chromium checkout for bdev",
	Long:  "Sets up a .bros/ directory in the current Chromium checkout,\nlinking it to a BrowserOS patches repository.",
	RunE:  runInit,
}

var (
	initPatchesRepo string
	initName        string
)

func init() {
	initCmd.Flags().StringVar(&initPatchesRepo, "patches-repo", "", "path to BrowserOS packages directory (required)")
	initCmd.Flags().StringVar(&initName, "name", "", "human name for this checkout (default: directory name)")
	_ = initCmd.MarkFlagRequired("patches-repo")
	rootCmd.AddCommand(initCmd)
}

func runInit(cmd *cobra.Command, args []string) error {
	cwd, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("getting cwd: %w", err)
	}

	if !config.LooksLikeChromium(cwd) {
		return fmt.Errorf("current directory does not look like a Chromium checkout (missing chrome/, base/, or .git/)")
	}

	brosDir := filepath.Join(cwd, config.BrosDirName)
	if _, err := os.Stat(filepath.Join(brosDir, "config.yaml")); err == nil {
		return fmt.Errorf(".bros/config.yaml already exists — checkout already initialized")
	}

	patchesRepo, err := filepath.Abs(initPatchesRepo)
	if err != nil {
		return fmt.Errorf("resolving patches repo path: %w", err)
	}

	patchesDir := filepath.Join(patchesRepo, "chromium_patches")
	if _, err := os.Stat(patchesDir); err != nil {
		return fmt.Errorf("chromium_patches/ not found in %s", patchesRepo)
	}

	baseCommit, err := config.ReadBaseCommit(patchesRepo)
	if err != nil {
		return err
	}

	if !git.CommitExists(cwd, baseCommit) {
		return fmt.Errorf("BASE_COMMIT %s not found in this checkout's git history", baseCommit)
	}

	name := initName
	if name == "" {
		name = filepath.Base(cwd)
	}

	cfg := &config.Config{
		Name:        name,
		PatchesRepo: patchesRepo,
	}
	if err := config.WriteConfig(brosDir, cfg); err != nil {
		return err
	}

	// Create logs directory
	if err := os.MkdirAll(filepath.Join(brosDir, "logs"), 0o755); err != nil {
		return fmt.Errorf("creating logs directory: %w", err)
	}

	chromiumVersion, _ := config.ReadChromiumVersion(patchesRepo)

	// Count existing patches
	patchCount := 0
	_ = filepath.Walk(patchesDir, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}
		if !info.IsDir() {
			patchCount++
		}
		return nil
	})

	fmt.Println(ui.TitleStyle.Render("bdev init"))
	fmt.Println()
	fmt.Printf("  %s %s\n", ui.LabelStyle.Render("Checkout:"), ui.ValueStyle.Render(name))
	fmt.Printf("  %s %s\n", ui.LabelStyle.Render("Directory:"), cwd)
	fmt.Printf("  %s %s\n", ui.LabelStyle.Render("Patches repo:"), patchesRepo)
	fmt.Printf("  %s %s\n", ui.LabelStyle.Render("Base commit:"), baseCommit[:min(12, len(baseCommit))])
	if chromiumVersion != "" {
		fmt.Printf("  %s %s\n", ui.LabelStyle.Render("Chromium:"), chromiumVersion)
	}
	fmt.Printf("  %s %d files\n", ui.LabelStyle.Render("Patches:"), patchCount)
	fmt.Println()
	fmt.Println(ui.SuccessStyle.Render("Initialized .bros/config.yaml"))
	fmt.Println(ui.MutedStyle.Render("Run 'bdev pull' to apply patches, or 'bdev push' to extract."))

	return nil
}
