package git

import (
	"context"
	"log/slog"
	"net/http"
	"os"
	"time"
)

// ExamplePullRequestUsage demonstrates how to use pull request functionality
func ExamplePullRequestUsage() {
	ctx := context.Background()

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

	// Example with GitHub
	exampleGitHubPullRequests(ctx, logger)

	// Example with Gerrit
	exampleGerritPullRequests(ctx, logger)
}

func exampleGitHubPullRequests(ctx context.Context, logger *slog.Logger) {
	logger.Info("=== GitHub Pull Request Example ===")

	// Create GitHub configuration
	githubConfig := GitHubConfig{
		Token:      "your-github-token-here",
		BaseURL:    "https://api.github.com",
		HTTPClient: &http.Client{Timeout: 30 * time.Second},
	}

	// Create GitHub pull request provider
	githubProvider := NewGitHubPullRequestProvider("owner", "repo", githubConfig)

	// Create Git instance with GitHub pull request capabilities
	git := NewGitWithPullRequests("/path/to/repo", GitConfig{
		Timeout: 30 * time.Second,
	}, githubProvider, logger)

	// Create a new pull request
	prOptions := PullRequestOptions{
		Title:       "Add new feature",
		Description: "This PR adds a new feature to the application.",
		BaseBranch:  "main",
		HeadBranch:  "feature/new-feature",
		Labels:      []string{"enhancement", "feature"},
		Assignees:   []string{"username1", "username2"},
		Reviewers:   []string{"reviewer1", "reviewer2"},
		Draft:       false,
	}

	pr, err := git.CreatePullRequest(ctx, prOptions)
	if err != nil {
		logger.Error("Failed to create pull request", slog.String("error", err.Error()))
		return
	}

	logger.Info("Created pull request", slog.String("title", pr.Title), slog.Int("number", pr.Number))

	// List pull requests
	listOptions := ListPullRequestOptions{
		State:      "open",
		Author:     "username",
		BaseBranch: "main",
		Limit:      10,
	}

	prs, err := git.ListPullRequests(ctx, listOptions)
	if err != nil {
		logger.Error("Failed to list pull requests", slog.String("error", err.Error()))
		return
	}

	logger.Info("Found pull requests", slog.Int("count", len(prs)))

	// Get a specific pull request
	pr, err = git.GetPullRequest(ctx, pr.ID)
	if err != nil {
		logger.Error("Failed to get pull request", slog.String("error", err.Error()))
		return
	}

	logger.Info("Pull request status", slog.String("state", pr.State))

	// Update a pull request
	updateOptions := PullRequestOptions{
		Title:       "Updated title",
		Description: "Updated description",
		Labels:      []string{"bug", "urgent"},
	}

	updatedPR, err := git.UpdatePullRequest(ctx, pr.ID, updateOptions)
	if err != nil {
		logger.Error("Failed to update pull request", slog.String("error", err.Error()))
		return
	}

	logger.Info("Updated pull request", slog.String("title", updatedPR.Title))

	// Merge a pull request
	mergeOptions := MergePullRequestOptions{
		MergeMethod: "squash",
		CommitTitle: "Merge pull request #123",
		CommitMsg:   "This merges the feature branch into main",
	}

	err = git.MergePullRequest(ctx, pr.ID, mergeOptions)
	if err != nil {
		logger.Error("Failed to merge pull request", slog.String("error", err.Error()))
		return
	}

	logger.Info("Pull request merged successfully")
}

func exampleGerritPullRequests(ctx context.Context, logger *slog.Logger) {
	logger.Info("=== Gerrit Pull Request Example ===")

	// Create Gerrit configuration
	gerritConfig := GerritConfig{
		Username:   "your-username",
		Password:   "your-http-password-or-api-token",
		BaseURL:    "https://gerrit.example.com",
		HTTPClient: &http.Client{Timeout: 30 * time.Second},
	}

	// Create Gerrit pull request provider
	gerritProvider := NewGerritPullRequestProvider("project-name", gerritConfig)

	// Create Git instance with Gerrit pull request capabilities
	git := NewGitWithPullRequests("/path/to/repo", GitConfig{
		Timeout: 30 * time.Second,
	}, gerritProvider, logger)

	// Create a new change (pull request)
	prOptions := PullRequestOptions{
		Title:       "Add new feature",
		Description: "This change adds a new feature to the application.",
		BaseBranch:  "master",
		HeadBranch:  "feature/new-feature",
	}

	pr, err := git.CreatePullRequest(ctx, prOptions)
	if err != nil {
		logger.Error("Failed to create change", slog.String("error", err.Error()))
		return
	}

	logger.Info("Created change", slog.String("title", pr.Title), slog.Int("number", pr.Number))

	// List changes
	listOptions := ListPullRequestOptions{
		State:      "open",
		Author:     "username",
		BaseBranch: "master",
		Limit:      10,
	}

	prs, err := git.ListPullRequests(ctx, listOptions)
	if err != nil {
		logger.Error("Failed to list changes", slog.String("error", err.Error()))
		return
	}

	logger.Info("Found changes", slog.Int("count", len(prs)))

	// Get a specific change
	pr, err = git.GetPullRequest(ctx, pr.ID)
	if err != nil {
		logger.Error("Failed to get change", slog.String("error", err.Error()))
		return
	}

	logger.Info("Change status", slog.String("state", pr.State))

	// Update a change
	updateOptions := PullRequestOptions{
		Title:       "Updated title",
		Description: "Updated description",
	}

	updatedPR, err := git.UpdatePullRequest(ctx, pr.ID, updateOptions)
	if err != nil {
		logger.Error("Failed to update change", slog.String("error", err.Error()))
		return
	}

	logger.Info("Updated change", slog.String("title", updatedPR.Title))

	// Submit a change (merge)
	mergeOptions := MergePullRequestOptions{
		CommitTitle: "Submit change",
		CommitMsg:   "This submits the change to master",
	}

	err = git.MergePullRequest(ctx, pr.ID, mergeOptions)
	if err != nil {
		logger.Error("Failed to submit change", slog.String("error", err.Error()))
		return
	}

	logger.Info("Change submitted successfully")
}

// Example of using both providers in the same application
func ExampleMultiProviderUsage() {
	ctx := context.Background()

	// Determine which provider to use based on configuration
	useGitHub := true // This could come from config

	var git GitInterface

	if useGitHub {
		// Use GitHub
		githubConfig := GitHubConfig{
			Token:   "github-token",
			BaseURL: "https://api.github.com",
		}
		githubProvider := NewGitHubPullRequestProvider("owner", "repo", githubConfig)
		git = NewGitWithPullRequests("/path/to/repo", GitConfig{}, githubProvider, nil) // Pass nil for logger as it's not used in this example
	} else {
		// Use Gerrit
		gerritConfig := GerritConfig{
			Username: "gerrit-username",
			Password: "gerrit-password",
			BaseURL:  "https://gerrit.example.com",
		}
		gerritProvider := NewGerritPullRequestProvider("project", gerritConfig)
		git = NewGitWithPullRequests("/path/to/repo", GitConfig{}, gerritProvider, nil) // Pass nil for logger as it's not used in this example
	}

	// Use the same interface regardless of provider
	prOptions := PullRequestOptions{
		Title:       "Cross-platform PR",
		Description: "This works with both GitHub and Gerrit",
		BaseBranch:  "main",
		HeadBranch:  "feature/cross-platform",
	}

	pr, err := git.CreatePullRequest(ctx, prOptions)
	if err != nil {
		slog.Error("Failed to create pull request", slog.String("error", err.Error()))
		return
	}

	slog.Info("Created pull request", slog.String("title", pr.Title))
}
