package plant

import (
	"sundynix-go/global"
	"sundynix-go/model/plant"
	plantReq "sundynix-go/model/plant/request"
	"sundynix-go/model/system"

	"sundynix-go/utils/wechat"

	"gorm.io/gorm"

	"go.uber.org/zap"
)

type PostService struct{}

var PostServiceApp = new(PostService)

// PublishPost 发表帖子
func (s *PostService) PublishPost(req plantReq.CreatePost, userId string) error {
	var postId string
	var ossList []*system.Oss

	err := global.DB.Transaction(func(tx *gorm.DB) error {
		//1.验证oss是否存在
		err := tx.Where("id in ?", req.OssIds).Find(&ossList).Error
		if err != nil {
			return err
		}
		//2.保存帖子
		post := plant.Post{
			Title:    req.Title,
			UserId:   userId,
			Content:  req.Content,
			Location: req.Location,
		}
		err = tx.Create(&post).Error
		if err != nil {
			return err
		}
		postId = post.Id

		//3.处理图片关系
		if len(ossList) > 0 {
			var relations []map[string]interface{}
			for _, oss := range ossList {
				relations = append(relations, map[string]interface{}{
					"post_id": post.Id,
					"oss_id":  oss.Id,
				})
			}
			err = tx.Table("sundynix_post_oss").Create(relations).Error
			if err != nil {
				return err
			}
		}
		return nil
	})

	if err != nil {
		return err
	}

	// 4.异步内容安全检查
	// 4.异步内容安全检查
	go func(pid, uid, title, content string, imgs []*system.Oss) {
		defer func() {
			if r := recover(); r != nil {
				global.Logger.Error("异步内容安全检查Panic", zap.Any("panic", r))
			}
		}()

		// 获取用户 openid
		var user system.User
		if err := global.DB.Where("id = ?", uid).First(&user).Error; err != nil {
			global.Logger.Error("获取用户失败，跳过安全检查", zap.String("userId", uid), zap.Error(err))
			return
		}
		openid := user.MiniOpenId
		if openid == "" {
			global.Logger.Warn("用户无MiniOpenId，跳过安全检查", zap.String("userId", uid))
			return
		}

		// 文本检查
		fullContent := title + "\n" + content
		isSafe := wechat.MsgSecCheck(fullContent, openid)

		// 文本违规 -> 直接拒绝
		if !isSafe {
			if err := global.DB.Model(&plant.Post{}).Where("id = ?", pid).Update("has_reviewed", 2).Error; err != nil {
				global.Logger.Error("更新帖子违规状态失败", zap.String("postId", pid), zap.Error(err))
			}
			global.Logger.Info("帖子内容违规，已标记", zap.String("postId", pid))
			return // 文本违规，无需再检查图片
		}
		if err := global.DB.Model(&plant.Post{}).Where("id = ?", pid).Update("has_reviewed", 1).Error; err != nil {
			global.Logger.Error("更新帖子违规状态失败", zap.String("postId", pid), zap.Error(err))
		}
		return // 文本违规，无需再检查图片

		// 文本通过，判断是否有图片
		//if len(imgs) == 0 {
		//	// 无图且文本通过 -> 直接通过
		//	if err := global.DB.Model(&plant.Post{}).Where("id = ?", pid).Update("has_reviewed", 1).Error; err != nil {
		//		global.Logger.Error("更新帖子通过状态失败", zap.String("postId", pid), zap.Error(err))
		//	}
		//	return
		//}

		// 有图，文本通过 -> 保持状态为0(待审核)，等待图片回调

		// todo 图片检查
		//for _, oss := range imgs {
		//	// 假设 oss.Url 是完整链接
		//	traceId, err := wechat.MediaCheckAsync(oss.Url, 2, openid)
		//	if err != nil {
		//		global.Logger.Error("图片安全检查请求失败", zap.String("url", oss.Url), zap.Error(err))
		//		continue
		//	}
		//	global.Logger.Info("图片安全检查请求成功", zap.String("traceId", traceId))
		//
		//	// 保存检测记录
		//	checkResult := plant.MediaCheckResult{
		//		TraceId: traceId,
		//		PostId:  pid,
		//		OssId:   oss.Id,
		//		UserId:  uid,
		//		Status:  0, // 检测中
		//		Type:    2, // 图片
		//	}
		//	if err := global.DB.Create(&checkResult).Error; err != nil {
		//		global.Logger.Error("保存媒体检测记录失败", zap.Error(err))
		//	}
		//}

	}(postId, userId, req.Title, req.Content, ossList)

	return nil
}

// PostPage 帖子列表
func (s *PostService) PostPage(req plantReq.PostPage, userId string) (list interface{}, total int64, err error) {
	limit := req.PageSize
	offset := req.PageSize * (req.Current - 1)
	db := global.DB.Model(&plant.Post{}).
		Preload("ImgList", func(db *gorm.DB) *gorm.DB {
			return db.Order("created_at desc")
		}).
		Preload("Publisher", func(db *gorm.DB) *gorm.DB {
			return db.Preload("Avatar")
		}).
		Preload("CommentList", func(db *gorm.DB) *gorm.DB {
			return db.Preload("Commentator", func(db *gorm.DB) *gorm.DB {
				return db.Preload("Avatar")
			})
		}).Preload("LikeList", func(db *gorm.DB) *gorm.DB {
		return db.Preload("Liker")
	})
	var posts []plant.Post
	if req.Title != "" {
		db = db.Where("title like ?", "%"+req.Title+"%")
	}
	if req.HasReviewed != nil {
		db = db.Where("has_reviewed = ?", *req.HasReviewed)
	}
	//todo 审核帖子
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&posts).Error
	// 优化 N+1 查询
	var postIds []string
	for _, v := range posts {
		postIds = append(postIds, v.Id)
	}
	// 批量查询当前用户点赞的记录
	var postLikeList []*plant.PostLike
	err = global.DB.Where("user_id = ? and post_id in ?", userId, postIds).Find(&postLikeList).Error
	if err != nil {
		return
	}
	//批量查询当前用户的收藏
	var stars []*plant.UserStar
	err = global.DB.Where("user_id = ? and post_id in ?", userId, postIds).Find(&stars).Error
	if err != nil {
		return
	}
	// 构建id映射
	likesMap := make(map[string]bool)
	for _, v := range postLikeList {
		likesMap[v.PostId] = true
	}
	starsMap := make(map[string]bool)
	for _, v := range stars {
		starsMap[v.PostId] = true
	}
	// 是否点赞
	for i := range posts {
		if likesMap[posts[i].Id] {
			posts[i].HasLiked = 1
		} else {
			posts[i].HasLiked = 0
		}

		if starsMap[posts[i].Id] {
			posts[i].HasStar = 1
		} else {
			posts[i].HasStar = 0
		}
	}

	return posts, total, err
}

// MyPost 我的帖子
func (s *PostService) MyPost(req plantReq.PostPage, userId string) (list interface{}, total int64, err error) {
	limit := req.PageSize
	offset := req.PageSize * (req.Current - 1)
	db := global.DB.Model(&plant.Post{}).
		Preload("ImgList", func(db *gorm.DB) *gorm.DB {
			return db.Order("created_at desc")
		}).
		Preload("Publisher", func(db *gorm.DB) *gorm.DB {
			return db.Preload("Avatar")
		}).
		Preload("LikeList", func(db *gorm.DB) *gorm.DB {
			return db.Preload("Liker", func(db *gorm.DB) *gorm.DB {
				return db.Preload("Avatar")
			})
		}).
		Preload("CommentList", func(db *gorm.DB) *gorm.DB {
			return db.Preload("Commentator", func(db *gorm.DB) *gorm.DB {
				return db.Preload("Avatar")
			})
		})
	var posts []plant.Post
	db = db.Where("user_id = ?", userId)
	if req.Title != "" {
		db = db.Where("title like ?", "%"+req.Title+"%")
	}
	//todo 审核帖子
	err = db.Count(&total).Error
	if err != nil {
		return
	}
	err = db.Limit(limit).Offset(offset).Order("created_at desc").Find(&posts).Error
	// 优化 N+1 查询
	var postIds []string
	for _, v := range posts {
		postIds = append(postIds, v.Id)
	}
	// 批量查询当前用户点赞的记录
	var postLikeList []*plant.PostLike
	err = global.DB.Where("user_id = ? and post_id in ?", userId, postIds).Find(&postLikeList).Error
	if err != nil {
		return
	}
	// 构建id映射
	likesMap := make(map[string]bool)
	for _, v := range postLikeList {
		likesMap[v.PostId] = true
	}
	// 是否点赞
	for i := range posts {
		if likesMap[posts[i].Id] {
			posts[i].HasLiked = 1
		} else {
			posts[i].HasLiked = 0
		}
	}

	return posts, total, err
}

// LikePost 点赞帖或取消赞
func (s *PostService) LikePost(userId, postId, class string) error {
	// class = 1点赞
	if class == "1" {
		return global.DB.Transaction(func(tx *gorm.DB) error {
			var post plant.Post
			err := tx.Where("id = ?", postId).First(&post).Error
			if err != nil {
				return err
			}
			//1.更新点赞数
			err = tx.Model(&post).Update("like_count", post.LikeCount+1).Error
			if err != nil {
				return err
			}
			//2.添加点赞记录
			like := plant.PostLike{
				UserId: userId,
				PostId: postId,
			}
			return tx.Create(&like).Error
		})
	} else if class == "2" {
		return global.DB.Transaction(func(tx *gorm.DB) error {
			var like plant.PostLike
			err := tx.Where("post_id = ? and user_id = ?", postId, userId).First(&like).Error
			if err != nil {
				return err
			}
			//1.更新点赞数
			var post plant.Post
			err = tx.Where("id = ?", postId).First(&post).Error
			if err != nil {
				return err
			}
			err = tx.Model(&post).
				Where("like_count > 0"). // 只有大于 0 才会执行减法
				Update("like_count", post.LikeCount-1).Error
			if err != nil {
				return err
			}
			//2.删除点赞记录
			return tx.Unscoped().Delete(&like).Error
		})
	}
	return nil
}

// CommentPost 评论帖子
func (s *PostService) CommentPost(req plantReq.CreateComment, userId string) error {
	return global.DB.Transaction(func(tx *gorm.DB) error {
		//1.为帖子评论数量+1
		var post plant.Post
		err := global.DB.Where("id = ?", req.PostId).First(&post).Error
		if err != nil {
			return err
		}
		//1.更新评论数
		err = tx.Model(&post).Update("comment_count", post.CommentCount+1).Error
		if err != nil {
			return err
		}
		//2.添加评论
		comment := plant.PostComment{
			PostId:  req.PostId,
			UserId:  userId,
			Content: req.Content,
		}
		return tx.Create(&comment).Error
	})
}

// DeletePost 删除帖子
func (s *PostService) DeletePost(ids []string) error {
	return global.DB.Transaction(func(tx *gorm.DB) error {
		var imgIds []string
		tx.Table("sundynix_post_oss").Where("post_id IN ?", ids).Pluck("oss_id", &imgIds)

		// 2. 清理中间表记录 (解开多对多关系)
		// 使用 Exec 直接操作中间表比循环 Clear 快得多
		if err := tx.Exec("DELETE FROM sundynix_post_oss WHERE post_id IN ?", ids).Error; err != nil {
			return err
		}

		// 3. 物理删除图片记录本身
		if len(imgIds) > 0 {
			if err := tx.Unscoped().Where("id IN ?", imgIds).Delete(&system.Oss{}).Error; err != nil {
				return err
			}
		}
		// 4. 批量删除点赞 (PostLike)
		if err := tx.Unscoped().Where("post_id IN ?", ids).Delete(&plant.PostLike{}).Error; err != nil {
			return err
		}
		// 5. 批量删除评论 (PostComment)
		if err := tx.Unscoped().Where("post_id IN ?", ids).Delete(&plant.PostComment{}).Error; err != nil {
			return err
		}

		// 6. 最后删除主表 Post
		if err := tx.Unscoped().Where("id IN ?", ids).Delete(&plant.Post{}).Error; err != nil {
			return err
		}

		return nil
	})
}

// StarPost 收藏帖子
func (s *PostService) StarPost(userId string, postId string, class string) error {
	if class == "1" {
		return global.DB.Transaction(func(tx *gorm.DB) error {
			var post plant.Post
			err := tx.Where("id = ?", postId).First(&post).Error
			if err != nil {
				return err
			}
			//1.更新点赞数
			err = tx.Model(&post).Update("star_count", post.LikeCount+1).Error
			if err != nil {
				return err
			}
			//2.添加到我的收藏
			star := plant.UserStar{
				UserId: userId,
				Type:   2,
				PostId: postId,
			}
			return tx.Create(&star).Error
		})
	} else if class == "2" {
		return global.DB.Transaction(func(tx *gorm.DB) error {
			var star plant.UserStar
			err := tx.Where("post_id = ? and user_id = ?", postId, userId).First(&star).Error
			if err != nil {
				return err
			}
			//1.更新收藏数
			var post plant.Post
			err = tx.Where("id = ?", postId).First(&post).Error
			if err != nil {
				return err
			}
			err = tx.Model(&post).
				Where("star_count > ?", 0). // 只有大于 0 才会执行减法
				Update("star_count", gorm.Expr("star_count - 1")).
				Error

			if err != nil {
				return err
			}
			//2.删除收藏
			return tx.Unscoped().Delete(&star).Error
		})
	}
	return nil
}
