package git

import (
	"context"
	"log/slog"
	"os"
)

// Example demonstrates how to use the Git interface
func Example() {
	ctx := context.Background()

	// Create logger
	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))

	// Create a new Git instance
	git := DefaultGit("/path/to/your/repo")

	// Get repository status
	status, err := git.Status(ctx)
	if err != nil {
		logger.Error("Failed to get status", slog.String("error", err.Error()))
		os.Exit(1)
	}

	logger.Info("Repository status", slog.String("branch", status.Branch), slog.Bool("clean", status.IsClean))

	// List branches
	branches, err := git.ListBranches(ctx)
	if err != nil {
		logger.Error("Failed to list branches", slog.String("error", err.Error()))
		os.Exit(1)
	}

	logger.Info("Branches found", slog.Int("count", len(branches)))
	for _, branch := range branches {
		current := ""
		if branch.IsCurrent {
			current = " (current)"
		}
		logger.Info("Branch", slog.String("name", branch.Name+current))
	}

	// Get recent commits
	logOptions := LogOptions{
		MaxCount: 5,
		Oneline:  true,
	}

	commits, err := git.Log(ctx, logOptions)
	if err != nil {
		logger.Error("Failed to get log", slog.String("error", err.Error()))
		os.Exit(1)
	}

	logger.Info("Recent commits", slog.Int("count", len(commits)))
	for _, commit := range commits {
		logger.Info("Commit", slog.String("hash", commit.Hash[:8]), slog.String("message", commit.Message))
	}
}

// ExampleWorkflow demonstrates a typical Git workflow
func ExampleWorkflow() {
	ctx := context.Background()

	// Create logger
	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))

	// Initialize a new repository
	git := DefaultGit("/path/to/new/repo")

	// Initialize the repository
	if err := git.Init(ctx, "/path/to/new/repo"); err != nil {
		logger.Error("Failed to initialize repository", slog.String("error", err.Error()))
		os.Exit(1)
	}

	// Set user configuration
	userConfig := UserConfig{
		Name:  "John Doe",
		Email: "john@example.com",
	}

	if err := git.SetUserConfig(ctx, userConfig); err != nil {
		logger.Error("Failed to set user config", slog.String("error", err.Error()))
		os.Exit(1)
	}

	// Create a new file and add it
	// (In a real scenario, you would create the file here)

	// Stage all changes
	if err := git.AddAll(ctx); err != nil {
		logger.Error("Failed to add files", slog.String("error", err.Error()))
		os.Exit(1)
	}

	// Commit the changes
	commitOptions := CommitOptions{
		AllowEmpty: false,
	}

	if err := git.Commit(ctx, "Initial commit", commitOptions); err != nil {
		logger.Error("Failed to commit", slog.String("error", err.Error()))
		os.Exit(1)
	}

	// Create a new branch
	if err := git.CreateBranch(ctx, "feature/new-feature", ""); err != nil {
		logger.Error("Failed to create branch", slog.String("error", err.Error()))
		os.Exit(1)
	}

	// Switch to the new branch
	if err := git.Checkout(ctx, "feature/new-feature"); err != nil {
		logger.Error("Failed to checkout branch", slog.String("error", err.Error()))
		os.Exit(1)
	}

	logger.Info("Repository initialized and feature branch created!")
}

// ExampleRemoteOperations demonstrates remote repository operations
func ExampleRemoteOperations() {
	ctx := context.Background()

	// Create logger
	logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelInfo}))

	git := DefaultGit("/path/to/your/repo")

	// Add a remote
	if err := git.AddRemote(ctx, "origin", "https://github.com/user/repo.git"); err != nil {
		logger.Error("Failed to add remote", slog.String("error", err.Error()))
		os.Exit(1)
	}

	// List remotes
	remotes, err := git.ListRemotes(ctx)
	if err != nil {
		logger.Error("Failed to list remotes", slog.String("error", err.Error()))
		os.Exit(1)
	}

	logger.Info("Remotes found", slog.Int("count", len(remotes)))
	for _, remote := range remotes {
		logger.Info("Remote", slog.String("name", remote.Name), slog.String("url", remote.URL))
	}

	// Fetch from remote
	fetchOptions := FetchOptions{
		All:  true,
		Tags: true,
	}

	if err := git.Fetch(ctx, "", fetchOptions); err != nil {
		logger.Error("Failed to fetch", slog.String("error", err.Error()))
		os.Exit(1)
	}

	// Push to remote
	pushOptions := PushOptions{
		SetUpstream: true,
	}

	if err := git.Push(ctx, "origin", "main", pushOptions); err != nil {
		logger.Error("Failed to push", slog.String("error", err.Error()))
		os.Exit(1)
	}
}
