package git

import (
	"context"
	"fmt"
	"log/slog"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/iomodo/staff/config"
)

// GitInterface defines the contract for Git operations
type GitInterface interface {
	// Repository operations
	Init(ctx context.Context, path string) error
	Clone(ctx context.Context, url, path string) error
	IsRepository(ctx context.Context, path string) (bool, error)

	// Status and information
	Status(ctx context.Context) (*Status, error)
	Log(ctx context.Context, options LogOptions) ([]Commit, error)
	Show(ctx context.Context, ref string) (*Commit, error)

	// Branch operations
	ListBranches(ctx context.Context) ([]Branch, error)
	CreateBranch(ctx context.Context, name string, startPoint string) error
	Checkout(ctx context.Context, ref string) error
	DeleteBranch(ctx context.Context, name string, force bool) error
	GetCurrentBranch(ctx context.Context) (string, error)
	GetUpstreamBranch(ctx context.Context, branch string) (string, error)

	// Commit operations
	Add(ctx context.Context, paths []string) error
	AddAll(ctx context.Context) error
	Commit(ctx context.Context, message string, options CommitOptions) error

	// Remote operations
	ListRemotes(ctx context.Context) ([]Remote, error)
	AddRemote(ctx context.Context, name, url string) error
	RemoveRemote(ctx context.Context, name string) error
	Fetch(ctx context.Context, remote string, options FetchOptions) error
	Pull(ctx context.Context, remote, branch string) error
	Push(ctx context.Context, remote, branch string, options PushOptions) error

	// Merge operations
	Merge(ctx context.Context, ref string, options MergeOptions) error
	MergeBase(ctx context.Context, ref1, ref2 string) (string, error)

	// Configuration
	GetConfig(ctx context.Context, key string) (string, error)
	SetConfig(ctx context.Context, key, value string) error
	GetUserConfig(ctx context.Context) (*UserConfig, error)
	SetUserConfig(ctx context.Context, config UserConfig) error

	// Pull Request operations
	CreatePullRequest(ctx context.Context, options PullRequestOptions) (*PullRequest, error)
	GetPullRequest(ctx context.Context, id string) (*PullRequest, error)
	ListPullRequests(ctx context.Context, options ListPullRequestOptions) ([]PullRequest, error)
	UpdatePullRequest(ctx context.Context, id string, options PullRequestOptions) (*PullRequest, error)
	ClosePullRequest(ctx context.Context, id string) error
	MergePullRequest(ctx context.Context, id string, options MergePullRequestOptions) error

	// Clone Manager Operations
	GetAgentClonePath(agentName string) (string, error)
	RefreshAgentClone(agentName string) error
	CleanupAgentClone(agentName string) error
	CleanupAllClones() error

	// Webhook operations (GitHub only)
	ListWebhooks(ctx context.Context) ([]GitHubWebhookResponse, error)
	CreateWebhook(ctx context.Context, webhookURL, secret string) (*GitHubWebhookResponse, error)
	UpdateWebhook(ctx context.Context, webhookID int, webhookURL, secret string) (*GitHubWebhookResponse, error)
}

// Status represents the current state of the repository
type Status struct {
	Branch    string
	IsClean   bool
	Staged    []FileStatus
	Unstaged  []FileStatus
	Untracked []string
	Conflicts []string
}

// FileStatus represents the status of a file
type FileStatus struct {
	Path   string
	Status string // "modified", "added", "deleted", "renamed", etc.
	Staged bool
}

// Commit represents a Git commit
type Commit struct {
	Hash      string
	Author    Author
	Committer Author
	Message   string
	Parents   []string
	Timestamp time.Time
	Files     []CommitFile
}

// Author represents a Git author or committer
type Author struct {
	Name  string
	Email string
	Time  time.Time
}

// CommitFile represents a file in a commit
type CommitFile struct {
	Path      string
	Status    string // "added", "modified", "deleted", "renamed"
	Additions int
	Deletions int
}

// Branch represents a Git branch
type Branch struct {
	Name      string
	IsCurrent bool
	IsRemote  bool
	Commit    string
	Message   string
}

// Remote represents a Git remote
type Remote struct {
	Name string
	URL  string
}

// UserConfig represents Git user configuration
type UserConfig struct {
	Name  string
	Email string
}

// LogOptions defines options for log operations
type LogOptions struct {
	MaxCount int
	Since    time.Time
	Until    time.Time
	Author   string
	Path     string
	Oneline  bool
}

// CommitOptions defines options for commit operations
type CommitOptions struct {
	Author     *Author
	Committer  *Author
	Sign       bool
	AllowEmpty bool
}

// FetchOptions defines options for fetch operations
type FetchOptions struct {
	All   bool
	Tags  bool
	Depth int
	Prune bool
}

// PushOptions defines options for push operations
type PushOptions struct {
	Force       bool
	Tags        bool
	SetUpstream bool
}

// MergeOptions defines options for merge operations
type MergeOptions struct {
	NoFF     bool
	Message  string
	Strategy string
}

// GitError represents a Git-specific error
type GitError struct {
	Command string
	Output  string
	Err     error
}

func (e *GitError) Error() string {
	if e.Err != nil {
		return fmt.Sprintf("git %s failed: %v\nOutput: %s", e.Command, e.Err, e.Output)
	}
	return fmt.Sprintf("git %s failed\nOutput: %s", e.Command, e.Output)
}

func (e *GitError) Unwrap() error {
	return e.Err
}

// Git implementation using os/exec to call git commands
type Git struct {
	repoPath     string
	prProvider   PullRequestProvider
	cloneManager *CloneManager
	logger       *slog.Logger
}

// NewGit creates a new Git instance
func New(cfg *config.Config, logger *slog.Logger) GitInterface {
	var prProvider PullRequestProvider
	var repoURL string

	switch cfg.GetPrimaryGitProvider() {
	case "github":
		githubConfig := GitHubConfig{
			Token:  cfg.GitHub.Token,
			Logger: logger,
		}
		prProvider = NewGitHubPullRequestProvider(cfg.GitHub.Owner, cfg.GitHub.Repo, githubConfig)
		repoURL = fmt.Sprintf("https://github.com/%s/%s.git", cfg.GitHub.Owner, cfg.GitHub.Repo)
		logger.Info("Using GitHub as pull request provider",
			slog.String("owner", cfg.GitHub.Owner),
			slog.String("repo", cfg.GitHub.Repo))
	case "gerrit":
		gerritConfig := GerritConfig{
			Username: cfg.Gerrit.Username,
			Password: cfg.Gerrit.Password,
			BaseURL:  cfg.Gerrit.BaseURL,
			Logger:   logger,
		}
		prProvider = NewGerritPullRequestProvider(cfg.Gerrit.Project, gerritConfig)
		repoURL = fmt.Sprintf("%s/%s", cfg.Gerrit.BaseURL, cfg.Gerrit.Project)
		logger.Info("Using Gerrit as pull request provider",
			slog.String("base_url", cfg.Gerrit.BaseURL),
			slog.String("project", cfg.Gerrit.Project))
	default:
		panic("no valid Git provider configured")
	}

	cloneManager := NewCloneManager(repoURL, cfg.Git.WorkspacePath)

	return &Git{
		repoPath:     cfg.Git.RepoPath,
		prProvider:   prProvider,
		cloneManager: cloneManager,
		logger:       logger,
	}
}

// Ensure Git implements GitInterface
var _ GitInterface = (*Git)(nil)

// Init initializes a new Git repository
func (g *Git) Init(ctx context.Context, path string) error {
	cmd := exec.CommandContext(ctx, "git", "init")
	cmd.Dir = path
	return g.runCommand(cmd, "init")
}

// Clone clones a repository from URL to path
func (g *Git) Clone(ctx context.Context, url, path string) error {
	cmd := exec.CommandContext(ctx, "git", "clone", url, path)
	return g.runCommand(cmd, "clone")
}

// IsRepository checks if a path is a valid Git repository
func (g *Git) IsRepository(ctx context.Context, path string) (bool, error) {
	return g.isValidRepo(path), nil
}

// Status returns the current status of the repository
func (g *Git) Status(ctx context.Context) (*Status, error) {
	cmd := exec.CommandContext(ctx, "git", "status", "--porcelain", "--branch")
	cmd.Dir = g.repoPath
	output, err := g.runCommandWithOutput(cmd, "status")
	if err != nil {
		return nil, err
	}

	return g.parseStatus(output)
}

// Log returns commit history
func (g *Git) Log(ctx context.Context, options LogOptions) ([]Commit, error) {
	args := []string{"log", "--format=%H%n%an%n%ae%n%at%n%s%n%cn%n%ce%n%ct%n%P"}

	if options.MaxCount > 0 {
		args = append(args, fmt.Sprintf("-%d", options.MaxCount))
	}

	if !options.Since.IsZero() {
		args = append(args, fmt.Sprintf("--since=%s", options.Since.Format(time.RFC3339)))
	}

	if !options.Until.IsZero() {
		args = append(args, fmt.Sprintf("--until=%s", options.Until.Format(time.RFC3339)))
	}

	if options.Author != "" {
		args = append(args, fmt.Sprintf("--author=%s", options.Author))
	}

	if options.Path != "" {
		args = append(args, "--", options.Path)
	}

	if options.Oneline {
		args = append(args, "--oneline")
	}

	cmd := exec.CommandContext(ctx, "git", args...)
	cmd.Dir = g.repoPath
	output, err := g.runCommandWithOutput(cmd, "log")
	if err != nil {
		return nil, err
	}

	return g.parseLog(output)
}

// Show shows commit details
func (g *Git) Show(ctx context.Context, ref string) (*Commit, error) {
	cmd := exec.CommandContext(ctx, "git", "show", "--format=json", ref)
	cmd.Dir = g.repoPath
	output, err := g.runCommandWithOutput(cmd, "show")
	if err != nil {
		return nil, err
	}

	commits, err := g.parseLog(output)
	if err != nil || len(commits) == 0 {
		return nil, &GitError{Command: "show", Output: "failed to parse commit"}
	}

	return &commits[0], nil
}

// ListBranches returns all branches
func (g *Git) ListBranches(ctx context.Context) ([]Branch, error) {
	cmd := exec.CommandContext(ctx, "git", "branch", "-a", "--format=%(refname:short)%09%(objectname)%09%(contents:subject)")
	cmd.Dir = g.repoPath
	output, err := g.runCommandWithOutput(cmd, "branch")
	if err != nil {
		return nil, err
	}

	return g.parseBranches(output)
}

// CreateBranch creates a new branch
func (g *Git) CreateBranch(ctx context.Context, name string, startPoint string) error {
	args := []string{"branch", name}
	if startPoint != "" {
		args = append(args, startPoint)
	}

	cmd := exec.CommandContext(ctx, "git", args...)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "branch")
}

// Checkout switches to a branch or commit
func (g *Git) Checkout(ctx context.Context, ref string) error {
	cmd := exec.CommandContext(ctx, "git", "checkout", ref)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "checkout")
}

// DeleteBranch deletes a branch
func (g *Git) DeleteBranch(ctx context.Context, name string, force bool) error {
	args := []string{"branch"}
	if force {
		args = append(args, "-D")
	} else {
		args = append(args, "-d")
	}
	args = append(args, name)

	cmd := exec.CommandContext(ctx, "git", args...)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "branch")
}

// GetCurrentBranch returns the current branch name
func (g *Git) GetCurrentBranch(ctx context.Context) (string, error) {
	cmd := exec.CommandContext(ctx, "git", "rev-parse", "--abbrev-ref", "HEAD")
	cmd.Dir = g.repoPath
	output, err := g.runCommandWithOutput(cmd, "rev-parse")
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(output), nil
}

// GetUpstreamBranch returns the upstream branch for a given branch
func (g *Git) GetUpstreamBranch(ctx context.Context, branch string) (string, error) {
	cmd := exec.CommandContext(ctx, "git", "rev-parse", "--abbrev-ref", branch+"@{upstream}")
	cmd.Dir = g.repoPath
	output, err := g.runCommandWithOutput(cmd, "rev-parse")
	if err != nil {
		return "", err
	}

	// The output will be in format "origin/branch-name", we want just "branch-name"
	upstream := strings.TrimSpace(output)
	upstream = strings.TrimPrefix(upstream, "origin/")

	return upstream, nil
}

// Add stages files for commit
func (g *Git) Add(ctx context.Context, paths []string) error {
	args := append([]string{"add"}, paths...)
	cmd := exec.CommandContext(ctx, "git", args...)
	g.logger.Info("Adding files", slog.String("paths", strings.Join(paths, ", ")))
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "add")
}

// AddAll stages all changes
func (g *Git) AddAll(ctx context.Context) error {
	cmd := exec.CommandContext(ctx, "git", "add", "-A")
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "add")
}

// Commit creates a new commit
func (g *Git) Commit(ctx context.Context, message string, options CommitOptions) error {
	args := []string{"commit", "-m", message}

	if options.Author != nil {
		args = append(args, fmt.Sprintf("--author=%s <%s>", options.Author.Name, options.Author.Email))
	}

	if options.Sign {
		args = append(args, "-S")
	}

	if options.AllowEmpty {
		args = append(args, "--allow-empty")
	}

	cmd := exec.CommandContext(ctx, "git", args...)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "commit")
}

// ListRemotes returns all remotes
func (g *Git) ListRemotes(ctx context.Context) ([]Remote, error) {
	cmd := exec.CommandContext(ctx, "git", "remote", "-v")
	cmd.Dir = g.repoPath
	output, err := g.runCommandWithOutput(cmd, "remote")
	if err != nil {
		return nil, err
	}

	return g.parseRemotes(output)
}

// AddRemote adds a new remote
func (g *Git) AddRemote(ctx context.Context, name, url string) error {
	cmd := exec.CommandContext(ctx, "git", "remote", "add", name, url)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "remote")
}

// RemoveRemote removes a remote
func (g *Git) RemoveRemote(ctx context.Context, name string) error {
	cmd := exec.CommandContext(ctx, "git", "remote", "remove", name)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "remote")
}

// Fetch fetches from a remote
func (g *Git) Fetch(ctx context.Context, remote string, options FetchOptions) error {
	args := []string{"fetch"}

	if options.All {
		args = append(args, "--all")
	} else if remote != "" {
		args = append(args, remote)
	}

	if options.Tags {
		args = append(args, "--tags")
	}

	if options.Depth > 0 {
		args = append(args, fmt.Sprintf("--depth=%d", options.Depth))
	}

	if options.Prune {
		args = append(args, "--prune")
	}

	cmd := exec.CommandContext(ctx, "git", args...)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "fetch")
}

// Pull pulls from a remote
func (g *Git) Pull(ctx context.Context, remote, branch string) error {
	args := []string{"pull"}
	if remote != "" {
		args = append(args, remote)
		if branch != "" {
			args = append(args, branch)
		}
	}

	cmd := exec.CommandContext(ctx, "git", args...)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "pull")
}

// Push pushes to a remote
func (g *Git) Push(ctx context.Context, remote, branch string, options PushOptions) error {
	args := []string{"push"}

	if options.Force {
		args = append(args, "--force")
	}

	if options.Tags {
		args = append(args, "--tags")
	}

	if options.SetUpstream {
		args = append(args, "--set-upstream")
	}

	if remote != "" {
		args = append(args, remote)
		if branch != "" {
			args = append(args, branch)
		}
	}

	cmd := exec.CommandContext(ctx, "git", args...)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "push")
}

// Merge merges a branch into current branch
func (g *Git) Merge(ctx context.Context, ref string, options MergeOptions) error {
	args := []string{"merge"}

	if options.NoFF {
		args = append(args, "--no-ff")
	}

	if options.Message != "" {
		args = append(args, "-m", options.Message)
	}

	if options.Strategy != "" {
		args = append(args, "-s", options.Strategy)
	}

	args = append(args, ref)

	cmd := exec.CommandContext(ctx, "git", args...)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "merge")
}

// MergeBase finds the common ancestor of two commits
func (g *Git) MergeBase(ctx context.Context, ref1, ref2 string) (string, error) {
	cmd := exec.CommandContext(ctx, "git", "merge-base", ref1, ref2)
	cmd.Dir = g.repoPath
	output, err := g.runCommandWithOutput(cmd, "merge-base")
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(output), nil
}

// GetConfig gets a Git configuration value
func (g *Git) GetConfig(ctx context.Context, key string) (string, error) {
	cmd := exec.CommandContext(ctx, "git", "config", "--get", key)
	cmd.Dir = g.repoPath
	output, err := g.runCommandWithOutput(cmd, "config")
	if err != nil {
		return "", err
	}

	return strings.TrimSpace(output), nil
}

// SetConfig sets a Git configuration value
func (g *Git) SetConfig(ctx context.Context, key, value string) error {
	cmd := exec.CommandContext(ctx, "git", "config", key, value)
	cmd.Dir = g.repoPath
	return g.runCommand(cmd, "config")
}

// GetUserConfig gets user configuration
func (g *Git) GetUserConfig(ctx context.Context) (*UserConfig, error) {
	name, err := g.GetConfig(ctx, "user.name")
	if err != nil {
		return nil, err
	}

	email, err := g.GetConfig(ctx, "user.email")
	if err != nil {
		return nil, err
	}

	return &UserConfig{
		Name:  name,
		Email: email,
	}, nil
}

// SetUserConfig sets user configuration
func (g *Git) SetUserConfig(ctx context.Context, config UserConfig) error {
	if err := g.SetConfig(ctx, "user.name", config.Name); err != nil {
		return err
	}

	return g.SetConfig(ctx, "user.email", config.Email)
}

// Pull Request operations

// CreatePullRequest creates a new pull request
func (g *Git) CreatePullRequest(ctx context.Context, options PullRequestOptions) (*PullRequest, error) {
	if g.prProvider == nil {
		return nil, &GitError{Command: "CreatePullRequest", Output: "no pull request provider configured"}
	}
	return g.prProvider.CreatePullRequest(ctx, options)
}

// GetPullRequest retrieves a pull request by ID
func (g *Git) GetPullRequest(ctx context.Context, id string) (*PullRequest, error) {
	if g.prProvider == nil {
		return nil, &GitError{Command: "GetPullRequest", Output: "no pull request provider configured"}
	}
	return g.prProvider.GetPullRequest(ctx, id)
}

// ListPullRequests lists pull requests
func (g *Git) ListPullRequests(ctx context.Context, options ListPullRequestOptions) ([]PullRequest, error) {
	if g.prProvider == nil {
		return nil, &GitError{Command: "ListPullRequests", Output: "no pull request provider configured"}
	}
	return g.prProvider.ListPullRequests(ctx, options)
}

// UpdatePullRequest updates a pull request
func (g *Git) UpdatePullRequest(ctx context.Context, id string, options PullRequestOptions) (*PullRequest, error) {
	if g.prProvider == nil {
		return nil, &GitError{Command: "UpdatePullRequest", Output: "no pull request provider configured"}
	}
	return g.prProvider.UpdatePullRequest(ctx, id, options)
}

// ClosePullRequest closes a pull request
func (g *Git) ClosePullRequest(ctx context.Context, id string) error {
	if g.prProvider == nil {
		return &GitError{Command: "ClosePullRequest", Output: "no pull request provider configured"}
	}
	return g.prProvider.ClosePullRequest(ctx, id)
}

// MergePullRequest merges a pull request
func (g *Git) MergePullRequest(ctx context.Context, id string, options MergePullRequestOptions) error {
	if g.prProvider == nil {
		return &GitError{Command: "MergePullRequest", Output: "no pull request provider configured"}
	}
	return g.prProvider.MergePullRequest(ctx, id, options)
}

// Clone manage methods
func (g *Git) GetAgentClonePath(agentName string) (string, error) {
	if g.cloneManager == nil {
		return "", &GitError{Command: "GetAgentClonePath", Output: "no clone manager configured"}
	}
	return g.cloneManager.GetAgentClonePath(agentName)
}
func (g *Git) RefreshAgentClone(agentName string) error {
	if g.cloneManager == nil {
		return &GitError{Command: "RefreshAgentClone", Output: "no clone manager configured"}
	}
	return g.cloneManager.RefreshAgentClone(agentName)
}
func (g *Git) CleanupAgentClone(agentName string) error {
	if g.cloneManager == nil {
		return &GitError{Command: "CleanupAgentClone", Output: "no clone manager configured"}
	}
	return g.cloneManager.CleanupAgentClone(agentName)
}
func (g *Git) CleanupAllClones() error {
	if g.cloneManager == nil {
		return &GitError{Command: "CleanupAllClones", Output: "no clone manager configured"}
	}
	return g.cloneManager.CleanupAllClones()
}

// Webhook operations (GitHub only)

// ListWebhooks lists existing webhooks for the repository
func (g *Git) ListWebhooks(ctx context.Context) ([]GitHubWebhookResponse, error) {
	webhookProvider, ok := g.prProvider.(WebhookProvider)
	if !ok {
		return nil, &GitError{Command: "ListWebhooks", Output: "webhook operations not supported by current provider"}
	}
	return webhookProvider.ListWebhooks(ctx)
}

// CreateWebhook creates a new webhook for the repository
func (g *Git) CreateWebhook(ctx context.Context, webhookURL, secret string) (*GitHubWebhookResponse, error) {
	webhookProvider, ok := g.prProvider.(WebhookProvider)
	if !ok {
		return nil, &GitError{Command: "CreateWebhook", Output: "webhook operations not supported by current provider"}
	}
	return webhookProvider.CreateWebhook(ctx, webhookURL, secret)
}

// UpdateWebhook updates an existing webhook
func (g *Git) UpdateWebhook(ctx context.Context, webhookID int, webhookURL, secret string) (*GitHubWebhookResponse, error) {
	webhookProvider, ok := g.prProvider.(WebhookProvider)
	if !ok {
		return nil, &GitError{Command: "UpdateWebhook", Output: "webhook operations not supported by current provider"}
	}
	return webhookProvider.UpdateWebhook(ctx, webhookID, webhookURL, secret)
}

// Helper methods

func (g *Git) runCommand(cmd *exec.Cmd, command string) error {
	output, err := cmd.CombinedOutput()
	if err != nil {
		return &GitError{
			Command: command,
			Output:  string(output),
			Err:     err,
		}
	}
	return nil
}

func (g *Git) runCommandWithOutput(cmd *exec.Cmd, command string) (string, error) {
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", &GitError{
			Command: command,
			Output:  string(output),
			Err:     err,
		}
	}
	return string(output), nil
}

func (g *Git) isValidRepo(path string) bool {
	gitDir := filepath.Join(path, ".git")
	info, err := os.Stat(gitDir)
	return err == nil && info.IsDir()
}

func (g *Git) parseStatus(output string) (*Status, error) {
	lines := strings.Split(strings.TrimSpace(output), "\n")
	status := &Status{
		Staged:    []FileStatus{},
		Unstaged:  []FileStatus{},
		Untracked: []string{},
		Conflicts: []string{},
	}

	for _, line := range lines {
		if strings.HasPrefix(line, "## ") {
			// Parse branch info
			parts := strings.Fields(line[3:])
			if len(parts) > 0 {
				// Extract local branch name from tracking information
				// Format can be: "main" or "main...origin/master"
				branchInfo := parts[0]
				if strings.Contains(branchInfo, "...") {
					// Split on "..." and take the local branch name
					branchParts := strings.Split(branchInfo, "...")
					status.Branch = branchParts[0]
				} else {
					status.Branch = branchInfo
				}
			}
			continue
		}

		if len(line) < 3 {
			continue
		}

		// Parse file status
		staged := line[0:1]
		unstaged := line[1:2]
		path := strings.TrimSpace(line[3:])

		if staged != " " {
			status.Staged = append(status.Staged, FileStatus{
				Path:   path,
				Status: g.parseStatusCode(staged),
				Staged: true,
			})
		}

		if unstaged != " " {
			status.Unstaged = append(status.Unstaged, FileStatus{
				Path:   path,
				Status: g.parseStatusCode(unstaged),
				Staged: false,
			})
		}

		if staged == " " && unstaged == "?" {
			status.Untracked = append(status.Untracked, path)
		}
	}

	status.IsClean = len(status.Staged) == 0 && len(status.Unstaged) == 0 && len(status.Untracked) == 0
	return status, nil
}

func (g *Git) parseStatusCode(code string) string {
	switch code {
	case "M":
		return "modified"
	case "A":
		return "added"
	case "D":
		return "deleted"
	case "R":
		return "renamed"
	case "C":
		return "copied"
	case "U":
		return "unmerged"
	default:
		return "unknown"
	}
}

func (g *Git) parseLog(output string) ([]Commit, error) {
	lines := strings.Split(strings.TrimSpace(output), "\n")
	var commits []Commit

	// Each commit takes 9 lines in the format:
	// Hash, AuthorName, AuthorEmail, AuthorTime, Subject, CommitterName, CommitterEmail, CommitterTime, Parents
	for i := 0; i < len(lines); i += 9 {
		if i+8 >= len(lines) {
			break
		}

		hash := lines[i]
		authorName := lines[i+1]
		authorEmail := lines[i+2]
		authorTimeStr := lines[i+3]
		subject := lines[i+4]
		committerName := lines[i+5]
		committerEmail := lines[i+6]
		committerTimeStr := lines[i+7]
		parentsStr := lines[i+8]

		// Parse timestamps
		authorTime, _ := strconv.ParseInt(authorTimeStr, 10, 64)
		committerTime, _ := strconv.ParseInt(committerTimeStr, 10, 64)

		// Parse parents
		var parents []string
		if parentsStr != "" {
			parents = strings.Fields(parentsStr)
		}

		commit := Commit{
			Hash: hash,
			Author: Author{
				Name:  authorName,
				Email: authorEmail,
				Time:  time.Unix(authorTime, 0),
			},
			Committer: Author{
				Name:  committerName,
				Email: committerEmail,
				Time:  time.Unix(committerTime, 0),
			},
			Message:   subject,
			Parents:   parents,
			Timestamp: time.Unix(authorTime, 0),
		}

		commits = append(commits, commit)
	}

	return commits, nil
}

func (g *Git) parseBranches(output string) ([]Branch, error) {
	lines := strings.Split(strings.TrimSpace(output), "\n")
	var branches []Branch

	for _, line := range lines {
		if strings.TrimSpace(line) == "" {
			continue
		}

		parts := strings.Split(line, "\t")
		if len(parts) < 3 {
			continue
		}

		branch := Branch{
			Name:     parts[0],
			Commit:   parts[1],
			Message:  parts[2],
			IsRemote: strings.HasPrefix(parts[0], "remotes/"),
		}

		// Check if this is the current branch
		if !branch.IsRemote {
			branch.IsCurrent = strings.HasPrefix(line, "*")
		}

		branches = append(branches, branch)
	}

	return branches, nil
}

func (g *Git) parseRemotes(output string) ([]Remote, error) {
	lines := strings.Split(strings.TrimSpace(output), "\n")
	var remotes []Remote
	seen := make(map[string]bool)

	for _, line := range lines {
		if strings.TrimSpace(line) == "" {
			continue
		}

		parts := strings.Fields(line)
		if len(parts) < 3 {
			continue
		}

		name := parts[0]
		if seen[name] {
			continue
		}

		remotes = append(remotes, Remote{
			Name: name,
			URL:  parts[1],
		})
		seen[name] = true
	}

	return remotes, nil
}

// PullRequest represents a pull request or merge request
type PullRequest struct {
	ID          string
	Number      int
	Title       string
	Description string
	State       string // "open", "closed", "merged"
	Author      Author
	CreatedAt   time.Time
	UpdatedAt   time.Time
	BaseBranch  string
	HeadBranch  string
	BaseRepo    string
	HeadRepo    string
	Labels      []string
	Assignees   []Author
	Reviewers   []Author
	Commits     []Commit
	Comments    []PullRequestComment
	URL         string
}

// PullRequestComment represents a comment on a pull request
type PullRequestComment struct {
	ID        string
	Author    Author
	Content   string
	CreatedAt time.Time
	UpdatedAt time.Time
	Path      string
	Line      int
}

// PullRequestOptions defines options for creating/updating pull requests
type PullRequestOptions struct {
	Title       string
	Description string
	BaseBranch  string
	HeadBranch  string
	BaseRepo    string
	HeadRepo    string
	Labels      []string
	Assignees   []string
	Reviewers   []string
	Draft       bool
}

// ListPullRequestOptions defines options for listing pull requests
type ListPullRequestOptions struct {
	State      string // "open", "closed", "all"
	Author     string
	Assignee   string
	BaseBranch string
	HeadBranch string
	Labels     []string
	Limit      int
}

// MergePullRequestOptions defines options for merging pull requests
type MergePullRequestOptions struct {
	MergeMethod string // "merge", "squash", "rebase"
	CommitTitle string
	CommitMsg   string
}

// PullRequestProvider defines the interface for pull request operations
type PullRequestProvider interface {
	CreatePullRequest(ctx context.Context, options PullRequestOptions) (*PullRequest, error)
	GetPullRequest(ctx context.Context, id string) (*PullRequest, error)
	ListPullRequests(ctx context.Context, options ListPullRequestOptions) ([]PullRequest, error)
	UpdatePullRequest(ctx context.Context, id string, options PullRequestOptions) (*PullRequest, error)
	ClosePullRequest(ctx context.Context, id string) error
	MergePullRequest(ctx context.Context, id string, options MergePullRequestOptions) error
}

// WebhookProvider defines the interface for webhook operations
type WebhookProvider interface {
	ListWebhooks(ctx context.Context) ([]GitHubWebhookResponse, error)
	CreateWebhook(ctx context.Context, webhookURL, secret string) (*GitHubWebhookResponse, error)
	UpdateWebhook(ctx context.Context, webhookID int, webhookURL, secret string) (*GitHubWebhookResponse, error)
}
