/**
 * 性能监控工具
 */

// 性能指标接口
export interface PerformanceMetrics {
  // 页面加载时间
  pageLoadTime: number;
  // 首次内容绘制
  fcp: number;
  // 最大内容绘制
  lcp: number;
  // 首次输入延迟
  fid: number;
  // 累积布局偏移
  cls: number;
  // 内存使用情况
  memory?: {
    used: number;
    total: number;
    limit: number;
  };
}

// 性能监控类
export class PerformanceMonitor {
  private metrics: Partial<PerformanceMetrics> = {};
  private observers: PerformanceObserver[] = [];

  constructor() {
    this.init();
  }

  private init() {
    // 监听页面加载完成
    if (document.readyState === 'complete') {
      this.measurePageLoad();
    } else {
      window.addEventListener('load', () => this.measurePageLoad());
    }

    // 监听 Web Vitals
    this.observeWebVitals();
  }

  private measurePageLoad() {
    const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
    if (navigation) {
      this.metrics.pageLoadTime = navigation.loadEventEnd - navigation.fetchStart;
    }
  }

  private observeWebVitals() {
    // FCP (First Contentful Paint)
    this.observePerformance('paint', (entries) => {
      const fcpEntry = entries.find(entry => entry.name === 'first-contentful-paint');
      if (fcpEntry) {
        this.metrics.fcp = fcpEntry.startTime;
      }
    });

    // LCP (Largest Contentful Paint)
    this.observePerformance('largest-contentful-paint', (entries) => {
      const lcpEntry = entries[entries.length - 1];
      if (lcpEntry) {
        this.metrics.lcp = lcpEntry.startTime;
      }
    });

    // FID (First Input Delay)
    this.observePerformance('first-input', (entries) => {
      const fidEntry = entries[0];
      if (fidEntry) {
        this.metrics.fid = fidEntry.processingStart - fidEntry.startTime;
      }
    });

    // CLS (Cumulative Layout Shift)
    this.observePerformance('layout-shift', (entries) => {
      let clsValue = 0;
      entries.forEach(entry => {
        if (!entry.hadRecentInput) {
          clsValue += entry.value;
        }
      });
      this.metrics.cls = clsValue;
    });
  }

  private observePerformance(type: string, callback: (entries: PerformanceEntry[]) => void) {
    try {
      const observer = new PerformanceObserver((list) => {
        callback(list.getEntries());
      });
      observer.observe({ type, buffered: true });
      this.observers.push(observer);
    } catch (error) {
      console.warn(`Performance observer for ${type} not supported:`, error);
    }
  }

  // 获取内存使用情况
  getMemoryUsage(): PerformanceMetrics['memory'] | null {
    if ('memory' in performance) {
      const memory = (performance as any).memory;
      return {
        used: Math.round(memory.usedJSHeapSize / 1024 / 1024),
        total: Math.round(memory.totalJSHeapSize / 1024 / 1024),
        limit: Math.round(memory.jsHeapSizeLimit / 1024 / 1024)
      };
    }
    return null;
  }

  // 获取所有性能指标
  getMetrics(): PerformanceMetrics {
    return {
      ...this.metrics,
      memory: this.getMemoryUsage()
    } as PerformanceMetrics;
  }

  // 清理观察器
  disconnect() {
    this.observers.forEach(observer => observer.disconnect());
    this.observers = [];
  }
}

// 路由性能监控
export class RoutePerformanceMonitor {
  private routeStartTime: number = 0;
  private routeMetrics: Map<string, number[]> = new Map();

  startRouteTimer() {
    this.routeStartTime = performance.now();
  }

  endRouteTimer(routeName: string) {
    if (this.routeStartTime) {
      const duration = performance.now() - this.routeStartTime;
      
      if (!this.routeMetrics.has(routeName)) {
        this.routeMetrics.set(routeName, []);
      }
      
      const metrics = this.routeMetrics.get(routeName)!;
      metrics.push(duration);
      
      // 只保留最近10次记录
      if (metrics.length > 10) {
        metrics.shift();
      }
      
      this.routeStartTime = 0;
    }
  }

  getRouteMetrics(routeName: string) {
    const metrics = this.routeMetrics.get(routeName) || [];
    if (metrics.length === 0) return null;

    const avg = metrics.reduce((sum, time) => sum + time, 0) / metrics.length;
    const min = Math.min(...metrics);
    const max = Math.max(...metrics);

    return { avg, min, max, count: metrics.length };
  }

  getAllRouteMetrics() {
    const result: Record<string, any> = {};
    this.routeMetrics.forEach((metrics, routeName) => {
      result[routeName] = this.getRouteMetrics(routeName);
    });
    return result;
  }
}

// API 性能监控
export class ApiPerformanceMonitor {
  private apiMetrics: Map<string, number[]> = new Map();

  recordApiCall(url: string, duration: number) {
    if (!this.apiMetrics.has(url)) {
      this.apiMetrics.set(url, []);
    }
    
    const metrics = this.apiMetrics.get(url)!;
    metrics.push(duration);
    
    // 只保留最近20次记录
    if (metrics.length > 20) {
      metrics.shift();
    }
  }

  getApiMetrics(url: string) {
    const metrics = this.apiMetrics.get(url) || [];
    if (metrics.length === 0) return null;

    const avg = metrics.reduce((sum, time) => sum + time, 0) / metrics.length;
    const min = Math.min(...metrics);
    const max = Math.max(...metrics);

    return { avg, min, max, count: metrics.length };
  }

  getSlowApis(threshold: number = 1000) {
    const slowApis: Array<{ url: string; avgTime: number }> = [];
    
    this.apiMetrics.forEach((metrics, url) => {
      const avg = metrics.reduce((sum, time) => sum + time, 0) / metrics.length;
      if (avg > threshold) {
        slowApis.push({ url, avgTime: avg });
      }
    });
    
    return slowApis.sort((a, b) => b.avgTime - a.avgTime);
  }
}

// 全局性能监控实例
export const performanceMonitor = new PerformanceMonitor();
export const routePerformanceMonitor = new RoutePerformanceMonitor();
export const apiPerformanceMonitor = new ApiPerformanceMonitor();

// 性能报告生成器
export function generatePerformanceReport() {
  const metrics = performanceMonitor.getMetrics();
  const routeMetrics = routePerformanceMonitor.getAllRouteMetrics();
  const slowApis = apiPerformanceMonitor.getSlowApis();

  return {
    webVitals: metrics,
    routes: routeMetrics,
    slowApis,
    timestamp: new Date().toISOString()
  };
}

// 性能警告
export function checkPerformanceWarnings() {
  const metrics = performanceMonitor.getMetrics();
  const warnings: string[] = [];

  if (metrics.lcp && metrics.lcp > 2500) {
    warnings.push(`LCP 过慢: ${metrics.lcp.toFixed(2)}ms (建议 < 2500ms)`);
  }

  if (metrics.fid && metrics.fid > 100) {
    warnings.push(`FID 过慢: ${metrics.fid.toFixed(2)}ms (建议 < 100ms)`);
  }

  if (metrics.cls && metrics.cls > 0.1) {
    warnings.push(`CLS 过高: ${metrics.cls.toFixed(3)} (建议 < 0.1)`);
  }

  if (metrics.memory && metrics.memory.used > metrics.memory.limit * 0.8) {
    warnings.push(`内存使用过高: ${metrics.memory.used}MB / ${metrics.memory.limit}MB`);
  }

  return warnings;
}
