package repository

import (
	"metazone.cc/metalab/internal/model"
	"metazone.cc/metalab/internal/service"

	"gorm.io/gorm"
)

// FavoriteRepo 收藏夹数据访问
type FavoriteRepo struct {
	db *gorm.DB
}

// NewFavoriteRepo 构造函数
func NewFavoriteRepo(db *gorm.DB) *FavoriteRepo {
	return &FavoriteRepo{db: db}
}

// WithTx 基于事务连接创建 FavoriteRepo
func (r *FavoriteRepo) WithTx(tx *gorm.DB) service.FavoriteStore {
	return &FavoriteRepo{db: tx}
}

// Transaction 在事务内执行业务逻辑
func (r *FavoriteRepo) Transaction(fn func(tx service.FavoriteStore) error) error {
	return r.db.Transaction(func(tx *gorm.DB) error {
		return fn(r.WithTx(tx))
	})
}

// ======================== Folder CRUD ========================

// CreateFolder 创建收藏夹
func (r *FavoriteRepo) CreateFolder(folder *model.Folder) error {
	return r.db.Create(folder).Error
}

// FindFolderByID 按 ID 查找收藏夹
func (r *FavoriteRepo) FindFolderByID(id uint) (*model.Folder, error) {
	var f model.Folder
	err := r.db.First(&f, id).Error
	if err != nil {
		return nil, err
	}
	return &f, nil
}

// ListFoldersByUser 列用户的收藏夹（附项目数）
func (r *FavoriteRepo) ListFoldersByUser(userID uint) ([]model.Folder, error) {
	var folders []model.Folder
	err := r.db.Table("folders").
		Select("folders.*, COUNT(folder_items.id) AS item_count").
		Joins("LEFT JOIN folder_items ON folder_items.folder_id = folders.id").
		Where("folders.user_id = ?", userID).
		Group("folders.id").
		Order("folders.is_default DESC, folders.created_at ASC").
		Scan(&folders).Error
	return folders, err
}

// UpdateFolder 更新收藏夹
func (r *FavoriteRepo) UpdateFolder(folder *model.Folder) error {
	return r.db.Save(folder).Error
}

// DeleteFolder 删除收藏夹
func (r *FavoriteRepo) DeleteFolder(id uint) error {
	return r.db.Where("id = ?", id).Delete(&model.Folder{}).Error
}

// DeleteItemsByFolder 删除收藏夹内所有记录
func (r *FavoriteRepo) DeleteItemsByFolder(folderID uint) error {
	return r.db.Where("folder_id = ?", folderID).Delete(&model.FolderItem{}).Error
}

// CountByNameAndUser 检查同用户下名称是否重复（排除自身）
func (r *FavoriteRepo) CountByNameAndUser(userID uint, name string, excludeID uint) (int64, error) {
	var count int64
	q := r.db.Model(&model.Folder{}).Where("user_id = ? AND name = ?", userID, name)
	if excludeID > 0 {
		q = q.Where("id != ?", excludeID)
	}
	err := q.Count(&count).Error
	return count, err
}

// HasDefaultFolder 检查用户是否有默认收藏夹
func (r *FavoriteRepo) HasDefaultFolder(userID uint) (bool, error) {
	var count int64
	err := r.db.Model(&model.Folder{}).Where("user_id = ? AND is_default = ?", userID, true).Count(&count).Error
	return count > 0, err
}

// ======================== FolderItem CRUD ========================

// CreateItem 添加收藏
func (r *FavoriteRepo) CreateItem(item *model.FolderItem) error {
	return r.db.Create(item).Error
}

// DeleteItem 取消收藏
func (r *FavoriteRepo) DeleteItem(folderID, postID uint) error {
	return r.db.Where("folder_id = ? AND post_id = ?", folderID, postID).Delete(&model.FolderItem{}).Error
}

// FindItemByUserAndPost 查找用户对某文章的收藏记录
func (r *FavoriteRepo) FindItemByUserAndPost(userID, postID uint) (*model.FolderItem, error) {
	var item model.FolderItem
	err := r.db.Where("user_id = ? AND post_id = ?", userID, postID).First(&item).Error
	if err != nil {
		return nil, err
	}
	return &item, nil
}

// ListItemsByFolder 列收藏夹内文章（分页，JOIN posts 获取标题）
func (r *FavoriteRepo) ListItemsByFolder(folderID uint, offset, limit int) ([]model.FolderItem, int64, error) {
	var total int64
	if err := r.db.Model(&model.FolderItem{}).Where("folder_id = ?", folderID).Count(&total).Error; err != nil {
		return nil, 0, err
	}

	var items []model.FolderItem
	err := r.db.Table("folder_items").
		Select("folder_items.*, posts.title AS post_title").
		Joins("LEFT JOIN posts ON posts.id = folder_items.post_id").
		Where("folder_items.folder_id = ?", folderID).
		Order("folder_items.created_at DESC").
		Offset(offset).Limit(limit).
		Scan(&items).Error
	return items, total, err
}

// CountItemsByFolder 统计收藏夹内文章数
func (r *FavoriteRepo) CountItemsByFolder(folderID uint) (int64, error) {
	var count int64
	err := r.db.Model(&model.FolderItem{}).Where("folder_id = ?", folderID).Count(&count).Error
	return count, err
}

// ======================== Post 计数器 ========================

// IncrPostFavoritesCount 原子更新文章收藏数
func (r *FavoriteRepo) IncrPostFavoritesCount(postID uint, delta int) error {
	return r.db.Model(&model.Post{}).
		Where("id = ?", postID).
		UpdateColumn("favorites_count", gorm.Expr("favorites_count + ?", delta)).Error
}

// ======================== 趋势聚合 ========================

// AggregateFavoritesByAuthor 按日期聚合收藏量（对于某用户的文章）
func (r *FavoriteRepo) AggregateFavoritesByAuthor(userID uint, since string) ([]service.TrendPoint, error) {
	var results []service.TrendPoint
	err := r.db.Table("folder_items").
		Select("TO_CHAR(folder_items.created_at, 'YYYY-MM-DD') AS date, COUNT(*) AS value").
		Joins("JOIN posts ON posts.id = folder_items.post_id").
		Where("posts.user_id = ? AND folder_items.created_at >= ?", userID, since).
		Group("TO_CHAR(folder_items.created_at, 'YYYY-MM-DD')").
		Order("date ASC").
		Scan(&results).Error
	return results, err
}
