package dingtalk

import (
	"context"
	"errors"
	"fmt"
	"time"

	redisLib "github.com/go-redis/redis/v8"
)

// redisTokenStorage 用 go-redis 实现的 TokenStorage
type redisTokenStorage struct {
	cli       *redisLib.Client
	keyPrefix string
}

// NewRedisTokenStorage 基于 *redisLib.Client 构造 TokenStorage
// keyPrefix 默认："dingtalk:access_token:"
func NewRedisTokenStorage(cli *redisLib.Client, keyPrefix string) TokenStorage {
	if keyPrefix == "" {
		keyPrefix = "dingtalk:access_token:"
	}
	return &redisTokenStorage{cli: cli, keyPrefix: keyPrefix}
}

func (r *redisTokenStorage) key(clientID string) string {
	return fmt.Sprintf("%s%s", r.keyPrefix, clientID)
}

// GetToken 从 Redis 读取 token；未命中返回 ("", nil)
func (r *redisTokenStorage) GetToken(ctx context.Context, clientID string) (string, error) {
	if r.cli == nil {
		return "", nil
	}
	val, err := r.cli.Get(ctx, r.key(clientID)).Result()
	if err != nil {
		if errors.Is(err, redisLib.Nil) {
			return "", nil
		}
		return "", err
	}
	return val, nil
}

// SetToken 写入 Redis，ttl<=0 时删除该 key
func (r *redisTokenStorage) SetToken(ctx context.Context, clientID, token string, ttl time.Duration) error {
	if r.cli == nil {
		return nil
	}
	if token == "" || ttl <= 0 {
		return r.cli.Del(ctx, r.key(clientID)).Err()
	}
	return r.cli.Set(ctx, r.key(clientID), token, ttl).Err()
}
