package postgres

import (
	"context"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/middleware"
	"github.com/redis/go-redis/v9"
	"gorm.io/gorm"
)

type ShopRoleStore struct {
	db          *gorm.DB
	redisClient *redis.Client
}

func NewShopRoleStore(db *gorm.DB, redisClient *redis.Client) *ShopRoleStore {
	return &ShopRoleStore{
		db:          db,
		redisClient: redisClient,
	}
}

func (s *ShopRoleStore) Create(ctx context.Context, sr *model.ShopRole) error {
	if err := s.db.WithContext(ctx).Create(sr).Error; err != nil {
		return err
	}
	s.clearShopRoleCache(ctx, sr.ShopID)
	return nil
}

func (s *ShopRoleStore) BatchCreate(ctx context.Context, srs []*model.ShopRole) error {
	if len(srs) == 0 {
		return nil
	}
	if err := s.db.WithContext(ctx).Create(&srs).Error; err != nil {
		return err
	}
	s.clearShopRoleCache(ctx, srs[0].ShopID)
	return nil
}

func (s *ShopRoleStore) Delete(ctx context.Context, shopID, roleID uint) error {
	if err := s.db.WithContext(ctx).
		Where("shop_id = ? AND role_id = ?", shopID, roleID).
		Delete(&model.ShopRole{}).Error; err != nil {
		return err
	}
	s.clearShopRoleCache(ctx, shopID)
	return nil
}

func (s *ShopRoleStore) DeleteByShopID(ctx context.Context, shopID uint) error {
	if err := s.db.WithContext(ctx).
		Where("shop_id = ?", shopID).
		Delete(&model.ShopRole{}).Error; err != nil {
		return err
	}
	s.clearShopRoleCache(ctx, shopID)
	return nil
}

// CountByRoleID 统计持有指定角色的店铺数量
func (s *ShopRoleStore) CountByRoleID(ctx context.Context, roleID uint) (int64, error) {
	var count int64
	if err := s.db.WithContext(ctx).
		Model(&model.ShopRole{}).
		Where("role_id = ?", roleID).
		Count(&count).Error; err != nil {
		return 0, err
	}
	return count, nil
}

func (s *ShopRoleStore) GetByShopID(ctx context.Context, shopID uint) ([]*model.ShopRole, error) {
	var srs []*model.ShopRole
	query := s.db.WithContext(ctx).Where("shop_id = ?", shopID)
	// 应用数据权限过滤
	query = middleware.ApplyShopFilter(ctx, query)
	if err := query.Find(&srs).Error; err != nil {
		return nil, err
	}
	return srs, nil
}

func (s *ShopRoleStore) GetRoleIDsByShopID(ctx context.Context, shopID uint) ([]uint, error) {
	var roleIDs []uint
	query := s.db.WithContext(ctx).
		Model(&model.ShopRole{}).
		Where("shop_id = ?", shopID)
	// 应用数据权限过滤
	query = middleware.ApplyShopFilter(ctx, query)
	if err := query.Pluck("role_id", &roleIDs).Error; err != nil {
		return nil, err
	}
	return roleIDs, nil
}

func (s *ShopRoleStore) clearShopRoleCache(ctx context.Context, shopID uint) {
	if s.redisClient == nil {
		return
	}

	var accountIDs []uint
	if err := s.db.WithContext(ctx).
		Model(&model.Account{}).
		Where("shop_id = ?", shopID).
		Pluck("id", &accountIDs).Error; err != nil {
		return
	}

	for _, accountID := range accountIDs {
		key := constants.RedisUserPermissionsKey(accountID)
		s.redisClient.Del(ctx, key)
	}
}
