// ============================================================
// Token Bucket Rate Limiter fuer Lexware Office API
// ============================================================
// Max 2 Requests/Sekunde (Lexware Limit)
// ============================================================

export class RateLimiter {
  private tokens: number;
  private lastRefill: number;
  private readonly maxTokens: number;
  private readonly refillRate: number; // Tokens pro Sekunde

  constructor(maxTokens = 2, refillRate = 2) {
    this.maxTokens = maxTokens;
    this.refillRate = refillRate;
    this.tokens = maxTokens;
    this.lastRefill = Date.now();
  }

  /**
   * Wartet bis ein Token verfuegbar ist, dann wird er verbraucht.
   * Blockiert maximal 5 Sekunden.
   */
  async acquire(): Promise<void> {
    this.refill();

    if (this.tokens >= 1) {
      this.tokens -= 1;
      return;
    }

    // Berechne Wartezeit bis naechster Token verfuegbar
    const deficit = 1 - this.tokens;
    const waitMs = Math.ceil((deficit / this.refillRate) * 1000);

    // Max 5 Sekunden warten
    const clampedWait = Math.min(waitMs, 5000);
    await new Promise((resolve) => setTimeout(resolve, clampedWait));

    this.refill();
    this.tokens = Math.max(0, this.tokens - 1);
  }

  /**
   * Fuellt Tokens basierend auf vergangener Zeit auf.
   */
  private refill(): void {
    const now = Date.now();
    const elapsed = (now - this.lastRefill) / 1000;
    this.tokens = Math.min(
      this.maxTokens,
      this.tokens + elapsed * this.refillRate,
    );
    this.lastRefill = now;
  }

  /**
   * Aktuelle Token-Anzahl (fuer Monitoring).
   */
  getTokens(): number {
    this.refill();
    return this.tokens;
  }
}
