package services

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

// CodeReviewer 定义代码审查的接口
type CodeReviewer interface {
	Review(changes *types.CodeChanges) (*types.ReviewResult, error)
}

// WebhookEvent 定义 webhook 事件的接口
type WebhookEvent interface {
	ExtractChanges() (*types.CodeChanges, error)
	PostComments(result *types.ReviewResult) error
	GetPlatform() string
}

// AIPool 定义 AI 池接口
type AIPool interface {
	GetAI() CodeReviewer
}

// ReviewService 代码审查服务
type ReviewService struct {
	aiPool AIPool
}

// NewReviewService 创建代码审查服务
func NewReviewService(aiPool AIPool) *ReviewService {
	return &ReviewService{
		aiPool: aiPool,
	}
}

// GetCodeChanges 从 webhook 事件中提取代码变更
func (s *ReviewService) GetCodeChanges(event WebhookEvent) (*types.CodeChanges, error) {
	return event.ExtractChanges()
}

// ReviewCode 使用配置的审查器进行代码审查
func (s *ReviewService) ReviewCode(changes *types.CodeChanges) (*types.ReviewResult, error) {
	if s.aiPool == nil {
		return nil, fmt.Errorf("未配置 AI 池")
	}
	ai := s.aiPool.GetAI()
	if ai == nil {
		log.Printf("没有可用的 AI")
		return nil, fmt.Errorf("没有可用的 AI")
	}
	return ai.Review(changes)
}

// PostReviewComments 将审查结果发送到代码托管平台
func (s *ReviewService) PostReviewComments(event WebhookEvent, result *types.ReviewResult) error {
	return event.PostComments(result)
}

// Review 执行代码审查流程
func (s *ReviewService) Review(event WebhookEvent) error {
	log.Printf("开始代码审查: platform=%s", event.GetPlatform())

	changes, err := event.ExtractChanges()
	if err != nil {
		log.Printf("提取代码变更失败: error=%v", err)
		return fmt.Errorf("提取代码变更失败: %w", err)
	}

	// 如果没有变更或者跳过审查,直接返回
	if changes == nil || len(changes.Files) == 0 {
		log.Printf("没有需要审查的代码变更")
		return nil
	}

	ai := s.aiPool.GetAI()
	if ai == nil {
		log.Printf("没有可用的 AI")
		return fmt.Errorf("没有可用的 AI")
	}

	result, err := ai.Review(changes)
	if err != nil {
		log.Printf("AI 代码审查失败: error=%v", err)
		return fmt.Errorf("AI 代码审查失败: %w", err)
	}

	if err := event.PostComments(result); err != nil {
		log.Printf("发送审查结果失败: error=%v", err)
		return fmt.Errorf("发送审查结果失败: %w", err)
	}

	log.Printf("代码审查完成")
	return nil
}