package repository

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

	"gorm.io/gorm"
)

// FollowRepo 关注数据访问
type FollowRepo struct {
	db *gorm.DB
}

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

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

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

// Create 创建关注
func (r *FollowRepo) Create(follow *model.UserFollow) error {
	return r.db.Create(follow).Error
}

// Delete 取消关注
func (r *FollowRepo) Delete(followerID, followeeID uint) error {
	return r.db.Where("follower_id = ? AND followee_id = ?", followerID, followeeID).
		Delete(&model.UserFollow{}).Error
}

// Exists 检查是否已关注
func (r *FollowRepo) Exists(followerID, followeeID uint) (bool, error) {
	var count int64
	err := r.db.Model(&model.UserFollow{}).
		Where("follower_id = ? AND followee_id = ?", followerID, followeeID).
		Count(&count).Error
	return count > 0, err
}

// CountFollowers 粉丝数
func (r *FollowRepo) CountFollowers(userID uint) (int64, error) {
	var count int64
	err := r.db.Model(&model.UserFollow{}).Where("followee_id = ?", userID).Count(&count).Error
	return count, err
}

// CountFollowing 关注数
func (r *FollowRepo) CountFollowing(userID uint) (int64, error) {
	var count int64
	err := r.db.Model(&model.UserFollow{}).Where("follower_id = ?", userID).Count(&count).Error
	return count, err
}

// ListFollowers 粉丝列表（分页，JOIN users 获取用户名、头像、简介）
func (r *FollowRepo) ListFollowers(userID uint, offset, limit int) ([]model.UserFollow, int64, error) {
	var total int64
	if err := r.db.Model(&model.UserFollow{}).Where("followee_id = ?", userID).Count(&total).Error; err != nil {
		return nil, 0, err
	}
	var items []model.UserFollow
	err := r.db.Table("user_follows").
		Select("user_follows.*, u.username AS follower_username, u.avatar AS follower_avatar, u.bio AS follower_bio").
		Joins("INNER JOIN users u ON u.uid = user_follows.follower_id").
		Where("user_follows.followee_id = ?", userID).
		Order("user_follows.created_at DESC").
		Offset(offset).Limit(limit).
		Scan(&items).Error
	return items, total, err
}

// ListFollowing 关注列表（分页，JOIN users 获取用户名、头像、简介）
func (r *FollowRepo) ListFollowing(userID uint, offset, limit int) ([]model.UserFollow, int64, error) {
	var total int64
	if err := r.db.Model(&model.UserFollow{}).Where("follower_id = ?", userID).Count(&total).Error; err != nil {
		return nil, 0, err
	}
	var items []model.UserFollow
	err := r.db.Table("user_follows").
		Select("user_follows.*, u.username AS followee_username, u.avatar AS followee_avatar, u.bio AS followee_bio").
		Joins("INNER JOIN users u ON u.uid = user_follows.followee_id").
		Where("user_follows.follower_id = ?", userID).
		Order("user_follows.created_at DESC").
		Offset(offset).Limit(limit).
		Scan(&items).Error
	return items, total, err
}

// IncrFollowersCount 原子增减粉丝数
func (r *FollowRepo) IncrFollowersCount(userID uint, delta int) error {
	return r.db.Model(&model.User{}).
		Where("uid = ?", userID).
		UpdateColumn("followers_count", gorm.Expr("followers_count + ?", delta)).Error
}

// IncrFollowingCount 原子增减关注数
func (r *FollowRepo) IncrFollowingCount(userID uint, delta int) error {
	return r.db.Model(&model.User{}).
		Where("uid = ?", userID).
		UpdateColumn("following_count", gorm.Expr("following_count + ?", delta)).Error
}

// GetFollowListPublic 查询用户关注列表公开性
func (r *FollowRepo) GetFollowListPublic(userID uint) (bool, error) {
	var listPublic bool
	err := r.db.Model(&model.User{}).
		Select("follow_list_public").
		Where("uid = ?", userID).
		Scan(&listPublic).Error
	return listPublic, err
}
