package git

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

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

// 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
	config     GitConfig
	prProvider PullRequestProvider
	logger     *slog.Logger
}

// GitConfig holds configuration for Git operations
type GitConfig struct {
	Timeout             time.Duration
	Env                 map[string]string
	PullRequestProvider PullRequestProvider
}

// NewGit creates a new Git instance
func NewGit(repoPath string, config GitConfig, logger *slog.Logger) GitInterface {
	if config.Timeout == 0 {
		config.Timeout = 30 * time.Second
	}

	return &Git{
		repoPath:   repoPath,
		config:     config,
		prProvider: config.PullRequestProvider,
		logger:     logger,
	}
}

// DefaultGit creates a Git instance with default configuration
func DefaultGit(repoPath string) GitInterface {
	return NewGit(repoPath, GitConfig{
		Timeout: 30 * time.Second,
	}, slog.Default())
}

// NewGitWithPullRequests creates a Git instance with pull request capabilities
func NewGitWithPullRequests(repoPath string, config GitConfig, prProvider PullRequestProvider, logger *slog.Logger) GitInterface {
	config.PullRequestProvider = prProvider
	return NewGit(repoPath, config, 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...)
	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)
}

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

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