package platforms

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

type GiteaEvent struct {
	apiBase string
	token   string
	Event   string
	client  *httpClient

	Ref        string `json:"ref"`
	Before     string `json:"before"`
	After      string `json:"after"`
	CompareURL string `json:"compare_url"`
	Commits    []struct {
		ID        string `json:"id"`
		Message   string `json:"message"`
		URL       string `json:"url"`
		Author    Author `json:"author"`
		Committer Author `json:"committer"`
		Timestamp string `json:"timestamp"`
	} `json:"commits"`
	Repository struct {
		ID       int    `json:"id"`
		Name     string `json:"name"`
		FullName string `json:"full_name"`
		HTMLURL  string `json:"html_url"`
		Private  bool   `json:"private"`
	} `json:"repository"`
}

// NewGiteaEvent 创建 Gitea 事件
func NewGiteaEvent(apiBase, token string, event string) *GiteaEvent {
	return &GiteaEvent{
		apiBase: apiBase,
		token:   token,
		Event:   event,
	}
}

func (e *GiteaEvent) 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.Repository.FullName,
		Branch:     e.Ref,
		CommitID:   e.After,
		Files:      make([]types.FileChange, 0),
	}

	for _, commit := range e.Commits {
		// 直接获取 diff 内容
		apiPath := fmt.Sprintf("/api/v1/repos/%s/git/commits/%s.diff?access_token=%s", e.Repository.FullName, commit.ID, e.token)
		var diffContent string

		if err := e.client.get(apiPath, &diffContent); err != nil {
			log.Printf("获取提交详情失败: commit=%s, error=%v", commit.ID, err)
			continue
		}

		// 去除首尾空白
		diffContent = strings.TrimSpace(diffContent)
		if diffContent == "" {
			log.Printf("提交没有变更内容: commit=%s", commit.ID)
			continue
		}

		// 解析 diff 内容
		diffBlocks := strings.Split(diffContent, "diff --git ")
		// 去除空块
		for _, block := range diffBlocks {
			if strings.TrimSpace(block) == "" {
				continue
			}

			// 移除 'diff --git ' 前缀
			block = strings.TrimPrefix(block, "diff --git ")

			// 解析文件名和变更类型
			lines := strings.Split(block, "\n")
			if len(lines) < 2 {
				continue
			}

			// 获取文件名
			filename := ""
			status := "modified"
			for _, line := range lines {
				if strings.HasPrefix(line, "--- a/") {
					filename = strings.TrimPrefix(line, "--- a/")
					break
				} else if strings.HasPrefix(line, "+++ b/") {
					filename = strings.TrimPrefix(line, "+++ b/")
					break
				}
			}

			// 如果没有找到文件名,跳过
			if filename == "" {
				continue
			}

			// 确定变更类型
			if strings.Contains(block, "new file mode") {
				status = "added"
			} else if strings.Contains(block, "deleted file mode") {
				status = "deleted"
			} else if strings.Contains(block, "rename from") {
				status = "renamed"
			}

			var content strings.Builder
			content.WriteString(fmt.Sprintf("### 变更说明\n"))
			content.WriteString(fmt.Sprintf("提交信息: %s\n\n", commit.Message))

			switch status {
			case "added":
				content.WriteString(fmt.Sprintf("新增文件: %s\n\n", filename))
			case "modified":
				content.WriteString(fmt.Sprintf("修改文件: %s\n\n", filename))
			case "deleted":
				content.WriteString(fmt.Sprintf("删除文件: %s\n\n", filename))
			case "renamed":
				content.WriteString(fmt.Sprintf("重命名文件: %s\n\n", filename))
			}

			content.WriteString("### 变更内容\n")
			content.WriteString("```diff\n")
			content.WriteString(block)
			content.WriteString("\n```\n")

			changes.Files = append(changes.Files, types.FileChange{
				Path:    filename,
				Content: content.String(),
				Type:    parseFileType(status),
			})
		}
	}

	return changes, nil
}

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

	// 创建 issue
	path := fmt.Sprintf("/api/v1/repos/%s/issues", e.Repository.FullName)
	issueData := map[string]interface{}{
		"title": fmt.Sprintf("AI 代码审查 - %s", e.After[:7]),
		"body":  utils.FormatReviewResult(result),
	}

	if err := e.client.post(path, issueData); 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 *GiteaEvent) GetPlatform() string {
	return "gitea"
}