package platforms

import (
	"code-review/services/types"
	"code-review/utils"
	"fmt"
	"log"
	"strings"
)

// GitlabEvent Gitlab 平台的 webhook 事件
type GitlabEvent struct {
	apiBase string
	token   string
	Event   string
	client  *httpClient

	ObjectKind string `json:"object_kind"` // "push", "merge_request" 等
	Before     string `json:"before"`
	After      string `json:"after"`
	Ref        string `json:"ref"`
	Project    struct {
		ID                int    `json:"id"`
		Name              string `json:"name"`
		Description       string `json:"description"`
		WebURL            string `json:"web_url"`
		PathWithNamespace string `json:"path_with_namespace"`
	} `json:"project"`
	Commits []struct {
		ID      string `json:"id"`
		Message string `json:"message"`
		Title   string `json:"title"`
	} `json:"commits"`
}

// NewGitlabEvent 创建 GitLab 事件实例
func NewGitlabEvent(baseURL, token string, event string) *GitlabEvent {
	return &GitlabEvent{
		apiBase: baseURL,
		token:   token,
		Event:   event,
	}
}

// 定义 GitLab diff 响应的结构
type gitlabDiff struct {
	Diff        string `json:"diff"`
	NewPath     string `json:"new_path"`
	OldPath     string `json:"old_path"`
	AMode       string `json:"a_mode"`
	BMode       string `json:"b_mode"`
	NewFile     bool   `json:"new_file"`
	RenamedFile bool   `json:"renamed_file"`
	DeletedFile bool   `json:"deleted_file"`
}

func (e *GitlabEvent) ExtractChanges() (*types.CodeChanges, error) {
	// 检查是否有提交记录
	if len(e.Commits) == 0 {
		log.Printf("没有提交记录,跳过代码审查")
		return nil, nil
	}

	// 检查是否跳过代码审查
	for _, commit := range e.Commits {
		if strings.Contains(commit.Message, "[skip codereview]") {
			log.Printf("跳过代码审查: commit=%s", commit.ID)
			return nil, nil
		}
	}

	if e.client == nil {
		e.client = newHTTPClient(e.apiBase, e.token)
		log.Printf("初始化 HTTP 客户端: url=%s", e.apiBase)
	}

	changes := &types.CodeChanges{
		Repository: e.Project.PathWithNamespace,
		Branch:     e.Ref,
		CommitID:   e.After,
		Files:      make([]types.FileChange, 0),
	}

	for _, commit := range e.Commits {
		// 移除 URL 中的 token
		apiPath := fmt.Sprintf("/api/v4/projects/%d/repository/commits/%s/diff",
			e.Project.ID, commit.ID)

		headers := map[string]string{
			"PRIVATE-TOKEN": e.token,
		}

		var diffs []gitlabDiff
		if err := e.client.getWithHeaders(apiPath, &diffs, headers); err != nil {
			log.Printf("获取提交详情失败: commit=%s, error=%v", commit.ID, err)
			continue
		}

		for _, diff := range diffs {
			status := "modified"
			if diff.NewFile {
				status = "added"
			} else if diff.DeletedFile {
				status = "deleted"
			} else if diff.RenamedFile {
				status = "renamed"
			}

			changes.Files = append(changes.Files, types.FileChange{
				Path:    diff.NewPath,
				Content: diff.Diff,
				Type:    parseFileType(status),
			})
		}
	}

	return changes, nil
}

func (e *GitlabEvent) PostComments(result *types.ReviewResult) error {
	if e.client == nil {
		e.client = newHTTPClient(e.apiBase, e.token)
	}

	// 创建 issue
	path := fmt.Sprintf("/api/v4/projects/%d/issues", e.Project.ID)
	issueData := map[string]interface{}{
		"title":       fmt.Sprintf("AI 代码审查 - %s", e.After[:7]),
		"description": utils.FormatReviewResult(result),
	}

	headers := map[string]string{
		"PRIVATE-TOKEN": e.token,
	}

	if err := e.client.postWithHeaders(path, issueData, headers); err != nil {
		log.Printf("创建 issue 失败: path=%s, error=%v", path, err)
		return fmt.Errorf("创建 issue 失败: %w", err)
	}

	log.Printf("成功创建 issue: path=%s, commitID=%s", path, e.After[:7])
	return nil
}

func (e *GitlabEvent) GetPlatform() string {
	return "gitlab"
}