package git

import (
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"
	"time"
)

// GerritConfig holds configuration for Gerrit operations
type GerritConfig struct {
	Username   string
	Password   string // Can be HTTP password or API token
	BaseURL    string
	HTTPClient *http.Client
}

// GerritPullRequestProvider implements PullRequestProvider for Gerrit
type GerritPullRequestProvider struct {
	config  GerritConfig
	project string
}

// NewGerritPullRequestProvider creates a new Gerrit pull request provider
func NewGerritPullRequestProvider(project string, config GerritConfig) PullRequestProvider {
	if config.HTTPClient == nil {
		config.HTTPClient = &http.Client{Timeout: 30 * time.Second}
	}

	return &GerritPullRequestProvider{
		config:  config,
		project: project,
	}
}

// Gerrit API response types
type gerritChange struct {
	ID              string                     `json:"id"`
	Number          int                        `json:"_number"`
	Subject         string                     `json:"subject"`
	Description     string                     `json:"description"`
	Status          string                     `json:"status"`
	Owner           gerritAccount              `json:"owner"`
	Created         time.Time                  `json:"created"`
	Updated         time.Time                  `json:"updated"`
	Branch          string                     `json:"branch"`
	Topic           string                     `json:"topic"`
	Labels          map[string]gerritLabelInfo `json:"labels"`
	Reviewers       map[string][]gerritAccount `json:"reviewers"`
	CurrentRevision string                     `json:"current_revision"`
	Revisions       map[string]gerritRevision  `json:"revisions"`
	Messages        []gerritMessage            `json:"messages"`
}

type gerritAccount struct {
	AccountID int    `json:"_account_id"`
	Name      string `json:"name"`
	Email     string `json:"email"`
	Username  string `json:"username"`
}

type gerritLabelInfo struct {
	All []gerritApproval `json:"all"`
}

type gerritApproval struct {
	AccountID int    `json:"_account_id"`
	Name      string `json:"name"`
	Email     string `json:"email"`
	Value     int    `json:"value"`
}

type gerritRevision struct {
	Number int                        `json:"_number"`
	Ref    string                     `json:"ref"`
	Fetch  map[string]gerritFetchInfo `json:"fetch"`
	Commit gerritCommit               `json:"commit"`
	Files  map[string]gerritFileInfo  `json:"files"`
}

type gerritFetchInfo struct {
	URL string `json:"url"`
	Ref string `json:"ref"`
}

type gerritCommit struct {
	Subject string       `json:"subject"`
	Message string       `json:"message"`
	Author  gerritPerson `json:"author"`
}

type gerritPerson struct {
	Name  string `json:"name"`
	Email string `json:"email"`
	Date  string `json:"date"`
}

type gerritFileInfo struct {
	Status        string `json:"status"`
	LinesInserted int    `json:"lines_inserted"`
	LinesDeleted  int    `json:"lines_deleted"`
}

type gerritMessage struct {
	ID             string        `json:"id"`
	Author         gerritAccount `json:"author"`
	Message        string        `json:"message"`
	Date           time.Time     `json:"date"`
	RevisionNumber int           `json:"_revision_number"`
}

type gerritCreateChangeRequest struct {
	Project     string `json:"project"`
	Subject     string `json:"subject"`
	Description string `json:"description"`
	Branch      string `json:"branch"`
	Topic       string `json:"topic,omitempty"`
	Base        string `json:"base,omitempty"`
}

type gerritUpdateChangeRequest struct {
	Subject     string `json:"subject,omitempty"`
	Description string `json:"description,omitempty"`
	Topic       string `json:"topic,omitempty"`
	Status      string `json:"status,omitempty"`
}

// CreatePullRequest creates a new change (pull request) on Gerrit
func (g *GerritPullRequestProvider) CreatePullRequest(ctx context.Context, options PullRequestOptions) (*PullRequest, error) {
	reqBody := gerritCreateChangeRequest{
		Project:     g.project,
		Subject:     options.Title,
		Description: options.Description,
		Branch:      options.BaseBranch,
		Topic:       options.HeadBranch, // Use head branch as topic
	}

	jsonBody, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal request body: %w", err)
	}

	url := fmt.Sprintf("%s/a/changes/", g.config.BaseURL)
	req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonBody))
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	req.SetBasicAuth(g.config.Username, g.config.Password)
	req.Header.Set("Content-Type", "application/json")

	resp, err := g.config.HTTPClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to make request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusCreated {
		return nil, fmt.Errorf("gerrit API error: %d", resp.StatusCode)
	}

	// Gerrit returns the change ID in the response body
	var changeID string
	if err := json.NewDecoder(resp.Body).Decode(&changeID); err != nil {
		return nil, fmt.Errorf("failed to decode response: %w", err)
	}

	// Remove the ")]}'" prefix that Gerrit adds to responses
	changeID = strings.TrimPrefix(changeID, ")]}'")

	// Fetch the created change
	return g.GetPullRequest(ctx, changeID)
}

// GetPullRequest retrieves a change by ID
func (g *GerritPullRequestProvider) GetPullRequest(ctx context.Context, id string) (*PullRequest, error) {
	url := fmt.Sprintf("%s/a/changes/%s?o=DETAILED_ACCOUNTS&o=DETAILED_LABELS&o=MESSAGES&o=CURRENT_REVISION&o=CURRENT_COMMIT", g.config.BaseURL, id)
	req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	req.SetBasicAuth(g.config.Username, g.config.Password)

	resp, err := g.config.HTTPClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to make request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("gerrit API error: %d", resp.StatusCode)
	}

	// Read and remove Gerrit's ")]}'" prefix
	body := make([]byte, 4)
	if _, err := resp.Body.Read(body); err != nil {
		return nil, fmt.Errorf("failed to read response prefix: %w", err)
	}
	if string(body) != ")]}'" {
		return nil, fmt.Errorf("unexpected response prefix: %s", string(body))
	}

	var gerritChange gerritChange
	if err := json.NewDecoder(resp.Body).Decode(&gerritChange); err != nil {
		return nil, fmt.Errorf("failed to decode response: %w", err)
	}

	return g.convertGerritChange(gerritChange), nil
}

// ListPullRequests lists changes
func (g *GerritPullRequestProvider) ListPullRequests(ctx context.Context, options ListPullRequestOptions) ([]PullRequest, error) {
	url := fmt.Sprintf("%s/a/changes/", g.config.BaseURL)
	req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	// Add query parameters
	q := req.URL.Query()
	q.Add("q", fmt.Sprintf("project:%s", g.project))

	if options.State != "" {
		switch options.State {
		case "open":
			q.Add("q", "status:open")
		case "closed":
			q.Add("q", "status:closed")
		}
	}
	if options.Author != "" {
		q.Add("q", fmt.Sprintf("owner:%s", options.Author))
	}
	if options.Assignee != "" {
		q.Add("q", fmt.Sprintf("reviewer:%s", options.Assignee))
	}
	if options.BaseBranch != "" {
		q.Add("q", fmt.Sprintf("branch:%s", options.BaseBranch))
	}
	if options.Limit > 0 {
		q.Add("n", strconv.Itoa(options.Limit))
	}
	req.URL.RawQuery = q.Encode()

	req.SetBasicAuth(g.config.Username, g.config.Password)

	resp, err := g.config.HTTPClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to make request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("gerrit API error: %d", resp.StatusCode)
	}

	// Read and remove Gerrit's ")]}'" prefix
	body := make([]byte, 4)
	if _, err := resp.Body.Read(body); err != nil {
		return nil, fmt.Errorf("failed to read response prefix: %w", err)
	}
	if string(body) != ")]}'" {
		return nil, fmt.Errorf("unexpected response prefix: %s", string(body))
	}

	var gerritChanges []gerritChange
	if err := json.NewDecoder(resp.Body).Decode(&gerritChanges); err != nil {
		return nil, fmt.Errorf("failed to decode response: %w", err)
	}

	prs := make([]PullRequest, len(gerritChanges))
	for i, change := range gerritChanges {
		prs[i] = *g.convertGerritChange(change)
	}

	return prs, nil
}

// UpdatePullRequest updates a change
func (g *GerritPullRequestProvider) UpdatePullRequest(ctx context.Context, id string, options PullRequestOptions) (*PullRequest, error) {
	reqBody := gerritUpdateChangeRequest{
		Subject:     options.Title,
		Description: options.Description,
	}

	jsonBody, err := json.Marshal(reqBody)
	if err != nil {
		return nil, fmt.Errorf("failed to marshal request body: %w", err)
	}

	url := fmt.Sprintf("%s/a/changes/%s", g.config.BaseURL, id)
	req, err := http.NewRequestWithContext(ctx, "PUT", url, bytes.NewBuffer(jsonBody))
	if err != nil {
		return nil, fmt.Errorf("failed to create request: %w", err)
	}

	req.SetBasicAuth(g.config.Username, g.config.Password)
	req.Header.Set("Content-Type", "application/json")

	resp, err := g.config.HTTPClient.Do(req)
	if err != nil {
		return nil, fmt.Errorf("failed to make request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("gerrit API error: %d", resp.StatusCode)
	}

	// Fetch the updated change
	return g.GetPullRequest(ctx, id)
}

// ClosePullRequest closes a change
func (g *GerritPullRequestProvider) ClosePullRequest(ctx context.Context, id string) error {
	reqBody := gerritUpdateChangeRequest{
		Status: "ABANDONED",
	}

	jsonBody, err := json.Marshal(reqBody)
	if err != nil {
		return fmt.Errorf("failed to marshal request body: %w", err)
	}

	url := fmt.Sprintf("%s/a/changes/%s/abandon", g.config.BaseURL, id)
	req, err := http.NewRequestWithContext(ctx, "POST", url, bytes.NewBuffer(jsonBody))
	if err != nil {
		return fmt.Errorf("failed to create request: %w", err)
	}

	req.SetBasicAuth(g.config.Username, g.config.Password)
	req.Header.Set("Content-Type", "application/json")

	resp, err := g.config.HTTPClient.Do(req)
	if err != nil {
		return fmt.Errorf("failed to make request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("gerrit API error: %d", resp.StatusCode)
	}

	return nil
}

// MergePullRequest merges a change
func (g *GerritPullRequestProvider) MergePullRequest(ctx context.Context, id string, options MergePullRequestOptions) error {
	url := fmt.Sprintf("%s/a/changes/%s/submit", g.config.BaseURL, id)
	req, err := http.NewRequestWithContext(ctx, "POST", url, nil)
	if err != nil {
		return fmt.Errorf("failed to create request: %w", err)
	}

	req.SetBasicAuth(g.config.Username, g.config.Password)

	resp, err := g.config.HTTPClient.Do(req)
	if err != nil {
		return fmt.Errorf("failed to make request: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("gerrit API error: %d", resp.StatusCode)
	}

	return nil
}

// convertGerritChange converts a Gerrit change to our PullRequest type
func (g *GerritPullRequestProvider) convertGerritChange(change gerritChange) *PullRequest {
	// Extract labels
	var labels []string
	for labelName := range change.Labels {
		labels = append(labels, labelName)
	}

	// Extract reviewers
	var reviewers []Author
	if reviewersMap, exists := change.Reviewers["REVIEWER"]; exists {
		for _, reviewer := range reviewersMap {
			reviewers = append(reviewers, Author{
				Name:  reviewer.Name,
				Email: reviewer.Email,
			})
		}
	}

	// Extract comments from messages
	var comments []PullRequestComment
	for _, message := range change.Messages {
		if message.Message != "" {
			comments = append(comments, PullRequestComment{
				ID: message.ID,
				Author: Author{
					Name:  message.Author.Name,
					Email: message.Author.Email,
				},
				Content:   message.Message,
				CreatedAt: message.Date,
				UpdatedAt: message.Date,
			})
		}
	}

	// Determine state
	state := "open"
	switch change.Status {
	case "MERGED":
		state = "merged"
	case "ABANDONED":
		state = "closed"
	}

	return &PullRequest{
		ID:          change.ID,
		Number:      change.Number,
		Title:       change.Subject,
		Description: change.Description,
		State:       state,
		Author: Author{
			Name:  change.Owner.Name,
			Email: change.Owner.Email,
		},
		CreatedAt:  change.Created,
		UpdatedAt:  change.Updated,
		BaseBranch: change.Branch,
		HeadBranch: change.Topic, // Use topic as head branch
		BaseRepo:   g.project,
		HeadRepo:   g.project, // Gerrit changes are within the same project
		Labels:     labels,
		Assignees:  []Author{}, // Gerrit doesn't have assignees in the same way
		Reviewers:  reviewers,
		Commits:    []Commit{}, // Would need additional API call to populate
		Comments:   comments,
	}
}
