package plant

import (
	"sundynix-go/global"
	"sundynix-go/model/plant"
	plantres "sundynix-go/model/plant/response"

	"go.uber.org/zap"
	"gorm.io/gorm"
)

type CallbackService struct{}

var CallbackServiceApp = new(CallbackService)

// HandleMediaCheckCallback 处理媒体检测回调
func (s *CallbackService) HandleMediaCheckCallback(cb plantres.WeChatCheckResultCallback) error {
	global.Logger.Info("收到微信媒体检测回调", zap.String("traceId", cb.TraceId), zap.String("suggest", cb.Result.Suggest))

	var checkResult plant.MediaCheckResult
	err := global.DB.Where("trace_id = ?", cb.TraceId).First(&checkResult).Error
	if err != nil {
		global.Logger.Error("回调traceId未找到", zap.String("traceId", cb.TraceId), zap.Error(err))
		return err
	}

	// 1. 更新检测结果状态
	status := 0
	if cb.Result.Suggest == "pass" {
		status = 1
	} else {
		status = 2
	}

	err = global.DB.Model(&checkResult).Updates(map[string]interface{}{
		"status":  status,
		"err_msg": cb.Result.Suggest,
	}).Error

	if err != nil {
		global.Logger.Error("更新检测结果失败", zap.Error(err))
		return err
	}

	// 2. 根据结果处理帖子状态
	return s.updatePostStatus(checkResult.PostId)
}

// updatePostStatus 更新帖子状态
// 逻辑：
// 1. 如果有任意一个检测结果为违规(2) -> 帖子违规(2)
// 2. 如果所有检测结果都为通过(1) -> 帖子通过(1)
// 3. 否则保持待审核(0)
func (s *CallbackService) updatePostStatus(postId string) error {
	return global.DB.Transaction(func(tx *gorm.DB) error {
		var post plant.Post
		if err := tx.Where("id = ?", postId).First(&post).Error; err != nil {
			return err
		}

		// 如果帖子已经是违规状态，无需再处理（可能之前已经由文本检测判定违规）
		if post.HasReviewed == 2 {
			return nil
		}

		var results []plant.MediaCheckResult
		if err := tx.Where("post_id = ?", postId).Find(&results).Error; err != nil {
			return err
		}

		hasRisky := false
		allPass := true

		for _, res := range results {
			if res.Status == 2 {
				hasRisky = true
				break
			}
			if res.Status != 1 {
				allPass = false
			}
		}

		var newStatus = post.HasReviewed // 默认保持原状态

		if hasRisky {
			newStatus = 2
			// TODO: 这里可以执行额外的封禁逻辑，例如不仅标记违规，还软删除Oss关联等
			global.Logger.Warn("帖子包含违规图片，标记为违规", zap.String("postId", postId))
		} else if allPass {
			// 只有当所有图片都通过，且原状态不是违规时，才标记为通过
			// 注意：这里假设文本检测已经通过（文本检测是同步的，若不通过早已设为2）
			// 如果文本检测尚未完成（理论上不可能，因为是先文本后图片），这里可能会有竞态，但文本检测在发帖goroutine中是串行的。
			// 唯一需要注意的是，如果文本检测还在进行中，这里不应覆盖。
			// 但我们在PublishPost中是先改HasReviewed再发图片检查。
			// 如果文本通过，HasReviewed会被设为1? 不，根据新逻辑，PublishPost中只有无图才设为1。
			// 有图时，PublishPost中HasReviewed保持0。
			newStatus = 1
			global.Logger.Info("帖子所有图片检测通过，标记为通过", zap.String("postId", postId))
		}

		if newStatus != post.HasReviewed {
			if err := tx.Model(&post).Update("has_reviewed", newStatus).Error; err != nil {
				return err
			}
		}

		return nil
	})
}
