package common

import (
	"context"
	"fmt"
	"log"
	"time"

	"github.com/redis/go-redis/v9"
	"metazone.cc/metalab/internal/config"
)

// NewRedisClient 创建 Redis 客户端并尝试验证连接
// Redis 不可达时不返回错误，而是返回 client（go-redis 自带自动重连），由调用方决定降级策略
func NewRedisClient(cfg config.RedisConfig) (*redis.Client, error) {
	client := redis.NewClient(&redis.Options{
		Addr:         fmt.Sprintf("%s:%s", cfg.Host, cfg.Port),
		Password:     cfg.Password,
		DB:           cfg.DB,
		DialTimeout:  1 * time.Second, // 连接超时降低（默认 5s），配合 FallbackStore 快速降级
		ReadTimeout:  1 * time.Second,
		WriteTimeout: 1 * time.Second,
		MaxRetries:   1,               // 最多重试 1 次（默认 3 次），减少故障阻塞时间
		PoolSize:     5,               // 会话存储不需要大连接池（默认 10*GOMAXPROCS）
	})

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := client.Ping(ctx).Err(); err != nil {
		log.Printf("[Redis] 连接失败: %v，将降级为内存存储", err)
		return client, fmt.Errorf("Redis 连接失败: %w", err)
	}

	return client, nil
}
