package apikey

import (
	"context"
	"fmt"
	"time"

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

type UsageStore struct{ redis *redis.Client }

func NewUsageStore(client *redis.Client) *UsageStore { return &UsageStore{redis: client} }

func MonthlyTokenUsageKey(apiKeyID string, now time.Time) string {
	return fmt.Sprintf("gateway:usage:api-key:%s:tokens:%s", apiKeyID, now.UTC().Format("200601"))
}

func (s *UsageStore) MonthlyTokens(ctx context.Context, apiKeyIDs []string, now time.Time) (map[string]int64, error) {
	usage := make(map[string]int64, len(apiKeyIDs))
	if len(apiKeyIDs) == 0 || s == nil || s.redis == nil {
		return usage, nil
	}
	pipe := s.redis.Pipeline()
	commands := make(map[string]*redis.StringCmd, len(apiKeyIDs))
	for _, id := range apiKeyIDs {
		commands[id] = pipe.Get(ctx, MonthlyTokenUsageKey(id, now))
	}
	_, err := pipe.Exec(ctx)
	if err != nil && err != redis.Nil {
		return nil, fmt.Errorf("%w: %v", ErrStore, err)
	}
	for id, command := range commands {
		value, commandErr := command.Int64()
		if commandErr == nil {
			usage[id] = max(value, 0)
		} else if commandErr != redis.Nil {
			return nil, fmt.Errorf("%w: %v", ErrStore, commandErr)
		}
	}
	return usage, nil
}
