package redis

import (
	"context"
	"fmt"
	"strings"
	"time"

	"github.com/redis/go-redis/v9"
)

// ConnRedis 连接redis对象
type ConnRedis struct {
	Addr     string `json:"addr"`     //  地址
	Port     int64  `json:"port"`     // 端口
	User     string `json:"user"`     //  用户名
	Password string `json:"password"` // 认证密码
	Database int    `json:"database"` // 数据库名称

	DialTimeOut time.Duration `json:"dialTimeOut"` // 连接超时断开

	Client *redis.Client `json:"client"`
}

// NewClient 创建Redis客户端
func (c *ConnRedis) NewClient() (*ConnRedis, error) {
	// IPV6地址协议
	if strings.Contains(c.Addr, ":") {
		c.Addr = fmt.Sprintf("[%s]", c.Addr)
	}
	addr := fmt.Sprintf("%s:%d", c.Addr, c.Port)

	// 默认等待5s
	if c.DialTimeOut == 0 {
		c.DialTimeOut = 5 * time.Second
	}

	// 连接
	rdb := redis.NewClient(&redis.Options{
		Addr: addr,
		// Username:    c.User,
		Password:    c.Password,
		DB:          c.Database,
		DialTimeout: c.DialTimeOut,
	})

	// 测试数据库连接
	if _, err := rdb.Ping(context.Background()).Result(); err != nil {
		return nil, err
	}

	c.Client = rdb
	return c, nil
}

// Close 关闭当前Redis客户端
func (c *ConnRedis) Close() {
	if c.Client != nil {
		c.Client.Close()
	}
}

// RunCMD 执行单次命令 "GET key"
func (c *ConnRedis) RunCMD(cmd string) (any, error) {
	if c.Client == nil {
		return "", fmt.Errorf("redis client not connected")
	}
	// 写入命令
	cmdArr := strings.Fields(cmd)
	if len(cmdArr) == 0 {
		return "", fmt.Errorf("redis command is empty")
	}
	conn := *c.Client
	args := make([]any, 0)
	for _, v := range cmdArr {
		args = append(args, v)
	}
	return conn.Do(context.Background(), args...).Result()
}
