import { logger } from "./logger";

export interface PerformanceMetric {
  name: string;
  duration: number;
  timestamp: number;
  metadata?: Record<string, unknown>;
}

class PerformanceMonitor {
  private metrics: PerformanceMetric[] = [];
  private maxMetrics = 1000;

  /**
   * 测量函数执行时间
   */
  async measure<T>(
    name: string,
    fn: () => Promise<T>,
    metadata?: Record<string, unknown>
  ): Promise<T> {
    const startTime = Date.now();

    try {
      const result = await fn();
      const duration = Date.now() - startTime;

      this.recordMetric(name, duration, metadata);

      return result;
    } catch (error) {
      const duration = Date.now() - startTime;
      this.recordMetric(`${name}_error`, duration, {
        ...metadata,
        error: true,
      });
      throw error;
    }
  }

  /**
   * 同步测量函数执行时间
   */
  measureSync<T>(
    name: string,
    fn: () => T,
    metadata?: Record<string, unknown>
  ): T {
    const startTime = Date.now();

    try {
      const result = fn();
      const duration = Date.now() - startTime;

      this.recordMetric(name, duration, metadata);

      return result;
    } catch (error) {
      const duration = Date.now() - startTime;
      this.recordMetric(`${name}_error`, duration, {
        ...metadata,
        error: true,
      });
      throw error;
    }
  }

  /**
   * 记录性能指标
   */
  recordMetric(
    name: string,
    duration: number,
    metadata?: Record<string, unknown>
  ): void {
    const metric: PerformanceMetric = {
      name,
      duration,
      timestamp: Date.now(),
      metadata,
    };

    this.metrics.push(metric);

    // 限制指标数量
    if (this.metrics.length > this.maxMetrics) {
      this.metrics = this.metrics.slice(-this.maxMetrics / 2);
    }

    // 记录慢查询
    if (duration > 1000) {
      logger.warn("Slow operation detected", {
        name,
        duration,
        metadata,
      });
    }
  }

  /**
   * 获取性能统计
   */
  getStats(): {
    totalMetrics: number;
    averageDuration: number;
    slowestOperations: PerformanceMetric[];
    fastestOperations: PerformanceMetric[];
    operationCounts: Record<string, number>;
  } {
    if (this.metrics.length === 0) {
      return {
        totalMetrics: 0,
        averageDuration: 0,
        slowestOperations: [],
        fastestOperations: [],
        operationCounts: {},
      };
    }

    const totalDuration = this.metrics.reduce(
      (sum, metric) => sum + metric.duration,
      0
    );
    const averageDuration = totalDuration / this.metrics.length;

    // 按名称分组统计
    const operationCounts: Record<string, number> = {};
    this.metrics.forEach((metric) => {
      operationCounts[metric.name] = (operationCounts[metric.name] || 0) + 1;
    });

    // 获取最慢的操作
    const slowestOperations = [...this.metrics]
      .sort((a, b) => b.duration - a.duration)
      .slice(0, 10);

    // 获取最快的操作
    const fastestOperations = [...this.metrics]
      .sort((a, b) => a.duration - b.duration)
      .slice(0, 10);

    return {
      totalMetrics: this.metrics.length,
      averageDuration,
      slowestOperations,
      fastestOperations,
      operationCounts,
    };
  }

  /**
   * 清理旧指标
   */
  cleanup(maxAge: number = 24 * 60 * 60 * 1000): void {
    const cutoff = Date.now() - maxAge;
    this.metrics = this.metrics.filter((metric) => metric.timestamp > cutoff);
  }

  /**
   * 导出性能报告
   */
  generateReport(): string {
    const stats = this.getStats();

    return `
Performance Report
==================

Total Metrics: ${stats.totalMetrics}
Average Duration: ${stats.averageDuration.toFixed(2)}ms

Slowest Operations:
${stats.slowestOperations
  .map((op) => `  ${op.name}: ${op.duration}ms`)
  .join("\n")}

Operation Counts:
${Object.entries(stats.operationCounts)
  .sort(([, a], [, b]) => b - a)
  .map(([name, count]) => `  ${name}: ${count}`)
  .join("\n")}
    `.trim();
  }
}

export const performanceMonitor = new PerformanceMonitor();

// 定期清理旧指标
if (typeof window === "undefined") {
  setInterval(() => {
    performanceMonitor.cleanup();
  }, 60 * 60 * 1000); // 每小时清理一次
}
