// Package redis 提供 Redis 数据库连接和管理功能。
// 支持 Unix Socket 和 TCP 两种连接方式。
// 注意：此包作为纯内存缓存使用，不开启持久化。
package redis

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

	"github.com/redis/go-redis/v9"
	"sese-engine/config"
)

// Client 是 Redis 客户端连接
var Client *redis.Client

// Open 初始化 Redis 连接
// 根据配置自动选择 Unix Socket 或 TCP 连接
// 注意：不开持久化，作为纯内存缓存使用
func Open() error {
	cfg := config.Global.Redis

	opt := &redis.Options{
		Addr:         config.RedisAddr(),
		Password:     config.RedisPassword(),
		DB:           config.RedisDB(),
		PoolSize:     config.RedisPoolSize(),
		MinIdleConns: config.RedisMinIdleConns(),
		ReadTimeout:  time.Duration(config.RedisReadTimeout()) * time.Millisecond,
		WriteTimeout: time.Duration(config.RedisWriteTimeout()) * time.Millisecond,
		// 禁用持久化 - 作为纯内存缓存
		// 不设置任何 save 策略即可禁用 RDB
	}

	client := redis.NewClient(opt)
	Client = client

	// 验证连接
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	if err := client.Ping(ctx).Err(); err != nil {
		return fmt.Errorf("redis.Ping: %w", err)
	}

	log.Printf("[redis] connected via %s (DB=%d)", formatAddr(opt), cfg.DB)
	return nil
}

// Close 关闭 Redis 连接
func Close() error {
	if Client != nil {
		return Client.Close()
	}
	return nil
}

// Ping 检查 Redis 连接是否正常
func Ping() error {
	if Client == nil {
		return fmt.Errorf("redis not initialized")
	}
	return Client.Ping(context.Background()).Err()
}

// FlushDB 清空当前数据库（谨慎使用，仅用于测试或重置）
func FlushDB() error {
	if Client == nil {
		return fmt.Errorf("redis not initialized")
	}
	return Client.FlushDB(context.Background()).Err()
}

// formatAddr 格式化地址用于日志
func formatAddr(opt *redis.Options) string {
	if opt.Addr != "" {
		return opt.Addr
	}
	return fmt.Sprintf("%s:%d", opt.Addr, 6379)
}
