package repository

import (
	"context"

	"gorm.io/gorm"

	"github.com/user-management-system/internal/domain"
)

// RolePermissionRepository 角色权限关联数据访问层
type RolePermissionRepository struct {
	db *gorm.DB
}

// NewRolePermissionRepository 创建角色权限关联数据访问层
func NewRolePermissionRepository(db *gorm.DB) *RolePermissionRepository {
	return &RolePermissionRepository{db: db}
}

// Create 创建角色权限关联
func (r *RolePermissionRepository) Create(ctx context.Context, rolePermission *domain.RolePermission) error {
	return r.db.WithContext(ctx).Create(rolePermission).Error
}

// Delete 删除角色权限关联
func (r *RolePermissionRepository) Delete(ctx context.Context, id int64) error {
	return r.db.WithContext(ctx).Delete(&domain.RolePermission{}, id).Error
}

// DeleteByRoleID 删除角色的所有权限
func (r *RolePermissionRepository) DeleteByRoleID(ctx context.Context, roleID int64) error {
	return r.db.WithContext(ctx).Where("role_id = ?", roleID).Delete(&domain.RolePermission{}).Error
}

// DeleteByPermissionID 删除权限的所有角色
func (r *RolePermissionRepository) DeleteByPermissionID(ctx context.Context, permissionID int64) error {
	return r.db.WithContext(ctx).Where("permission_id = ?", permissionID).Delete(&domain.RolePermission{}).Error
}

// GetByRoleID 根据角色ID获取权限列表
func (r *RolePermissionRepository) GetByRoleID(ctx context.Context, roleID int64) ([]*domain.RolePermission, error) {
	var rolePermissions []*domain.RolePermission
	err := r.db.WithContext(ctx).Where("role_id = ?", roleID).Find(&rolePermissions).Error
	if err != nil {
		return nil, err
	}
	return rolePermissions, nil
}

// GetByPermissionID 根据权限ID获取角色列表
func (r *RolePermissionRepository) GetByPermissionID(ctx context.Context, permissionID int64) ([]*domain.RolePermission, error) {
	var rolePermissions []*domain.RolePermission
	err := r.db.WithContext(ctx).Where("permission_id = ?", permissionID).Find(&rolePermissions).Error
	if err != nil {
		return nil, err
	}
	return rolePermissions, nil
}

// GetPermissionIDsByRoleID 根据角色ID获取权限ID列表
func (r *RolePermissionRepository) GetPermissionIDsByRoleID(ctx context.Context, roleID int64) ([]int64, error) {
	var permissionIDs []int64
	err := r.db.WithContext(ctx).Model(&domain.RolePermission{}).Where("role_id = ?", roleID).Pluck("permission_id", &permissionIDs).Error
	if err != nil {
		return nil, err
	}
	return permissionIDs, nil
}

// GetRoleIDByPermissionID 根据权限ID获取角色ID列表
func (r *RolePermissionRepository) GetRoleIDByPermissionID(ctx context.Context, permissionID int64) ([]int64, error) {
	var roleIDs []int64
	err := r.db.WithContext(ctx).Model(&domain.RolePermission{}).Where("permission_id = ?", permissionID).Pluck("role_id", &roleIDs).Error
	if err != nil {
		return nil, err
	}
	return roleIDs, nil
}

// Exists 检查角色权限关联是否存在
func (r *RolePermissionRepository) Exists(ctx context.Context, roleID, permissionID int64) (bool, error) {
	var count int64
	err := r.db.WithContext(ctx).Model(&domain.RolePermission{}).
		Where("role_id = ? AND permission_id = ?", roleID, permissionID).
		Count(&count).Error
	return count > 0, err
}

// BatchCreate 批量创建角色权限关联
func (r *RolePermissionRepository) BatchCreate(ctx context.Context, rolePermissions []*domain.RolePermission) error {
	if len(rolePermissions) == 0 {
		return nil
	}
	return r.db.WithContext(ctx).Create(&rolePermissions).Error
}

// BatchDelete 批量删除角色权限关联
func (r *RolePermissionRepository) BatchDelete(ctx context.Context, rolePermissions []*domain.RolePermission) error {
	if len(rolePermissions) == 0 {
		return nil
	}

	var ids []int64
	for _, rp := range rolePermissions {
		ids = append(ids, rp.ID)
	}

	return r.db.WithContext(ctx).Delete(&domain.RolePermission{}, ids).Error
}

// GetPermissionByID 根据权限ID获取权限信息
func (r *RolePermissionRepository) GetPermissionByID(ctx context.Context, permissionID int64) (*domain.Permission, error) {
	var permission domain.Permission
	err := r.db.WithContext(ctx).First(&permission, permissionID).Error
	if err != nil {
		return nil, err
	}
	return &permission, nil
}

// GetPermissionIDsByRoleIDs 根据角色ID列表批量获取权限ID
func (r *RolePermissionRepository) GetPermissionIDsByRoleIDs(ctx context.Context, roleIDs []int64) ([]int64, error) {
	if len(roleIDs) == 0 {
		return []int64{}, nil
	}

	var permissionIDs []int64
	err := r.db.WithContext(ctx).Model(&domain.RolePermission{}).
		Where("role_id IN ?", roleIDs).
		Pluck("permission_id", &permissionIDs).Error
	if err != nil {
		return nil, err
	}
	return permissionIDs, nil
}

// GetPermissionsByIDs 根据权限ID列表批量获取权限
func (r *RolePermissionRepository) GetPermissionsByIDs(ctx context.Context, permissionIDs []int64) ([]*domain.Permission, error) {
	if len(permissionIDs) == 0 {
		return []*domain.Permission{}, nil
	}

	var permissions []*domain.Permission
	err := r.db.WithContext(ctx).Where("id IN ?", permissionIDs).Find(&permissions).Error
	if err != nil {
		return nil, err
	}
	return permissions, nil
}
