package com.micer.easyball.config;

import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class RateLimitingConfig {

    private final ConcurrentHashMap<String, Bucket> buckets = new ConcurrentHashMap<>();

    public Bucket resolveBucket(String key, String apiPath, long capacity, long refillTokens, Duration refillDuration) {
        return buckets.computeIfAbsent(key + ":" + apiPath, k -> new Bucket(capacity, refillTokens, refillDuration.toMillis()));
    }

    public static class Bucket {
        private final long capacity;
        private final long refillTokens;
        private final long refillDurationMillis;

        private double tokens;
        private long lastRefillTime;

        public Bucket(long capacity, long refillTokens, long refillDurationMillis) {
            this.capacity = capacity;
            this.refillTokens = refillTokens;
            this.refillDurationMillis = refillDurationMillis;
            this.tokens = capacity;
            this.lastRefillTime = System.currentTimeMillis();
        }

        public synchronized boolean tryConsume(long numTokens) {
            refill();
            if (tokens >= numTokens) {
                tokens -= numTokens;
                return true;
            }
            return false;
        }

        private void refill() {
            long now = System.currentTimeMillis();
            if (now <= lastRefillTime) return;
            long elapsed = now - lastRefillTime;
            if (elapsed <= 0) return;
            double periods = (double) elapsed / (double) refillDurationMillis;
            if (periods <= 0) return;
            double added = periods * refillTokens;
            if (added > 0) {
                tokens = Math.min(capacity, tokens + added);
                lastRefillTime = now;
            }
        }
    }
}
