import type { BatchedEvent } from './types';

export class BatchQueue {
  private queue: BatchedEvent[] = [];
  private batchSize: number;
  private batchInterval: number;
  private flushCallback: (events: BatchedEvent[]) => Promise<void>;
  private intervalId?: ReturnType<typeof setInterval>;
  private debugLogging: boolean;

  constructor(
    batchSize: number,
    batchInterval: number,
    flushCallback: (events: BatchedEvent[]) => Promise<void>,
    debugLogging = false,
  ) {
    this.batchSize = batchSize;
    this.batchInterval = batchInterval;
    this.flushCallback = flushCallback;
    this.debugLogging = debugLogging;
    this.startInterval();
  }

  add(event: BatchedEvent): void {
    this.queue.push(event);

    if (this.debugLogging) {
      console.log('[Analytics] Event queued:', event.type, this.queue.length);
    }

    if (this.queue.length >= this.batchSize) {
      this.flush();
    }
  }

  async flush(): Promise<void> {
    if (this.queue.length === 0) {
      return;
    }

    const eventsToFlush = [...this.queue];
    this.queue = [];

    if (this.debugLogging) {
      console.log('[Analytics] Flushing batch:', eventsToFlush.length, 'events');
    }

    try {
      await this.flushCallback(eventsToFlush);

      if (this.debugLogging) {
        console.log('[Analytics] Batch flushed successfully');
      }
    } catch (error) {
      if (this.debugLogging) {
        console.error('[Analytics] Batch flush failed:', error);
      }
      // Re-queue failed events
      this.queue.unshift(...eventsToFlush);
    }
  }

  private startInterval(): void {
    this.intervalId = setInterval(() => {
      this.flush();
    }, this.batchInterval);
  }

  destroy(): void {
    if (this.intervalId) {
      clearInterval(this.intervalId);
    }
    this.flush();
  }
}
