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)

	// 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
}

// 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)
}
