import type {
  IPerformanceStorage,
  IPerformanceMetrics,
  IAggregatedPerformanceStats,
} from '../types';

export class MemoryPerformanceStorage implements IPerformanceStorage {
  private entries: IPerformanceMetrics[] = [];
  private maxEntries: number;

  constructor(maxEntries: number = 5000) {
    this.maxEntries = maxEntries;
  }

  async save(entry: IPerformanceMetrics): Promise<void> {
    if (this.entries.length >= this.maxEntries) {
      this.entries = this.entries.slice(-this.maxEntries + 1);
    }
    this.entries.push({ ...entry });
  }

  async getMetrics(
    operation?: string,
    timeRange?: { start: Date; end: Date },
  ): Promise<IPerformanceMetrics[]> {
    let filtered = [...this.entries];
    if (operation) {
      filtered = filtered.filter((entry) => entry.operation === operation);
    }
    if (timeRange) {
      filtered = filtered.filter(
        (entry) => entry.timestamp >= timeRange.start && entry.timestamp <= timeRange.end,
      );
    }
    return filtered;
  }

  async getAggregatedStats(timeRange?: {
    start: Date;
    end: Date;
  }): Promise<IAggregatedPerformanceStats> {
    const metrics = await this.getMetrics(undefined, timeRange);

    if (metrics.length === 0) {
      return {
        totalOperations: 0,
        averageDuration: 0,
        minDuration: 0,
        maxDuration: 0,
        successRate: 0,
        errorRate: 0,
        operationStats: {},
        timeRangeStats: {
          startTime: timeRange?.start || new Date(),
          endTime: timeRange?.end || new Date(),
          period: 'empty',
        },
      };
    }

    const durations = metrics.map((m) => m.duration);
    const successCount = metrics.filter((m) => m.success).length;
    const errorCount = metrics.reduce((sum, m) => sum + m.errorCount, 0);

    return {
      totalOperations: metrics.length,
      averageDuration: durations.reduce((sum, d) => sum + d, 0) / durations.length,
      minDuration: Math.min(...durations),
      maxDuration: Math.max(...durations),
      successRate: successCount / metrics.length,
      errorRate: errorCount / metrics.length,
      operationStats: {},
      timeRangeStats: {
        startTime: timeRange?.start || metrics[0]?.timestamp || new Date(),
        endTime: timeRange?.end || metrics[metrics.length - 1]?.timestamp || new Date(),
        period: 'memory',
      },
    };
  }

  async clear(): Promise<void> {
    this.entries = [];
  }

  async flush(): Promise<void> {
    // Memory storage doesn't need flushing
  }

  async close(): Promise<void> {
    // Memory storage doesn't need closing
  }
}
