package repository

import (
	"time"

	"metazone.cc/metalab/internal/model"

	"gorm.io/gorm"
	"gorm.io/gorm/clause"
)

// CountUserPosts 统计某用户的已发布文章数
func (r *PostRepo) CountUserPosts(userID uint) (int64, error) {
	var count int64
	err := r.db.Model(&model.Post{}).
		Where("user_id = ? AND status = ? AND deleted_at IS NULL", userID, model.PostStatusApproved).
		Count(&count).Error
	return count, err
}

// GetUserStats 获取用户的文章统计数据（总获赞/总收藏/总阅读）
func (r *PostRepo) GetUserStats(userID uint) (likes, favorites, reads int64, err error) {
	type stats struct {
		TotalLikes     int64
		TotalFavorites int64
		TotalReads     int64
	}
	var s stats
	err = r.db.Model(&model.Post{}).
		Select("COALESCE(SUM(likes_count), 0) AS total_likes, COALESCE(SUM(favorites_count), 0) AS total_favorites, COALESCE(SUM(views_count), 0) AS total_reads").
		Where("user_id = ? AND status = ? AND deleted_at IS NULL", userID, model.PostStatusApproved).
		Scan(&s).Error
	return s.TotalLikes, s.TotalFavorites, s.TotalReads, err
}

// overviewRow GetOverviewByUserID 单次 GROUP BY 查询结果行
type overviewRow struct {
	TotalPosts    int64
	DraftCount    int64
	PendingCount  int64
	ApprovedCount int64
	RejectedCount int64
}

// GetOverviewByUserID 用单次 GROUP BY 查询聚合用户各状态文章数
func (r *PostRepo) GetOverviewByUserID(userID uint) (totalPosts, draftCount, pendingCount, approvedCount, rejectedCount int64, err error) {
	var row overviewRow
	err = r.db.Model(&model.Post{}).
		Select(`
			COUNT(*) AS total_posts,
			COALESCE(SUM(CASE WHEN status = 'draft' THEN 1 ELSE 0 END), 0) AS draft_count,
			COALESCE(SUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END), 0) AS pending_count,
			COALESCE(SUM(CASE WHEN status = 'approved' THEN 1 ELSE 0 END), 0) AS approved_count,
			COALESCE(SUM(CASE WHEN status = 'rejected' THEN 1 ELSE 0 END), 0) AS rejected_count
		`).
		Where("user_id = ? AND deleted_at IS NULL", userID).
		Scan(&row).Error
	return row.TotalPosts, row.DraftCount, row.PendingCount, row.ApprovedCount, row.RejectedCount, err
}

// readCooldown 两次阅读记录最小间隔
const readCooldown = 2 * time.Second

// RecordRead 记录已登录用户阅读文章（防刷量：取去重+冷却）
// 返回 true 表示首次阅读（新记录），false 表示重复或冷却中
func (r *PostRepo) RecordRead(userID, postID uint) (bool, error) {
	// 冷却检查：同用户两次阅读之间至少间隔 2 秒
	var lastRead model.PostReadLog
	if err := r.db.Where("user_id = ?", userID).
		Order("read_at DESC").First(&lastRead).Error; err == nil {
		if time.Since(lastRead.ReadAt) < readCooldown {
			return false, nil
		}
	}

	result := r.db.Clauses(clause.OnConflict{DoNothing: true}).
		Create(&model.PostReadLog{UserID: userID, PostID: postID})
	if result.Error != nil {
		return false, result.Error
	}
	return result.RowsAffected > 0, nil
}

// RecordGuestRead 记录访客阅读文章（基于 Cookie visitor_id 去重+冷却）
// 返回 true 表示首次阅读（新记录），false 表示重复或冷却中
func (r *PostRepo) RecordGuestRead(visitorID string, postID uint) (bool, error) {
	// 冷却检查：同访客两次阅读之间至少间隔 2 秒
	var lastRead model.PostGuestReadLog
	if err := r.db.Where("visitor_id = ?", visitorID).
		Order("read_at DESC").First(&lastRead).Error; err == nil {
		if time.Since(lastRead.ReadAt) < readCooldown {
			return false, nil
		}
	}

	result := r.db.Clauses(clause.OnConflict{DoNothing: true}).
		Create(&model.PostGuestReadLog{VisitorID: visitorID, PostID: postID})
	if result.Error != nil {
		return false, result.Error
	}
	return result.RowsAffected > 0, nil
}

// IncrementViewsCount 阅读数 +1
func (r *PostRepo) IncrementViewsCount(postID uint) error {
	return r.db.Model(&model.Post{}).Where("id = ?", postID).
		Update("views_count", gorm.Expr("views_count + 1")).Error
}
