package git

import (
	"context"
	"fmt"
	"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
}

// 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) GitInterface {
	if config.Timeout == 0 {
		config.Timeout = 30 * time.Second
	}

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

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

// NewGitWithPullRequests creates a Git instance with pull request capabilities
func NewGitWithPullRequests(repoPath string, config GitConfig, prProvider PullRequestProvider) GitInterface {
	config.PullRequestProvider = prProvider
	return NewGit(repoPath, config)
}

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