/**
 * Zulip账号关联性能监控工具
 *
 * 功能描述：
 * - 提供性能监控和指标收集功能
 * - 支持操作耗时统计和性能基准对比
 * - 集成告警机制和性能阈值监控
 * - 提供性能报告和分析工具
 *
 * 职责分离：
 * - 性能监控：记录和统计各种操作的性能指标
 * - 阈值管理：定义和管理性能阈值和告警规则
 * - 指标收集：收集和聚合性能数据
 * - 报告生成：生成性能报告和分析结果
 *
 * 最近修改：
 * - 2026-01-12: 初始创建 - 实现性能监控和指标收集功能
 *
 * @author angjustinl
 * @version 1.0.0
 * @since 2026-01-12
 * @lastModified 2026-01-12
 */

import { AppLoggerService } from '../../utils/logger/logger.service';

/**
 * 性能指标接口
 */
export interface PerformanceMetric {
  /** 操作名称 */
  operation: string;
  /** 执行时长（毫秒） */
  duration: number;
  /** 开始时间 */
  startTime: number;
  /** 结束时间 */
  endTime: number;
  /** 是否成功 */
  success: boolean;
  /** 上下文信息 */
  context?: Record<string, any>;
  /** 错误信息（如果失败） */
  error?: string;
}

/**
 * 性能统计信息
 */
export interface PerformanceStats {
  /** 操作名称 */
  operation: string;
  /** 总调用次数 */
  totalCalls: number;
  /** 成功次数 */
  successCalls: number;
  /** 失败次数 */
  failureCalls: number;
  /** 成功率 */
  successRate: number;
  /** 平均耗时 */
  avgDuration: number;
  /** 最小耗时 */
  minDuration: number;
  /** 最大耗时 */
  maxDuration: number;
  /** P95耗时 */
  p95Duration: number;
  /** P99耗时 */
  p99Duration: number;
  /** 最后更新时间 */
  lastUpdated: Date;
}

/**
 * 性能阈值配置
 */
export const PERFORMANCE_THRESHOLDS = {
  // 数据库操作阈值（毫秒）
  DATABASE: {
    QUERY_SINGLE: 50,      // 单条查询
    QUERY_BATCH: 200,      // 批量查询
    INSERT: 100,           // 插入操作
    UPDATE: 80,            // 更新操作
    DELETE: 60,            // 删除操作
    TRANSACTION: 300,      // 事务操作
  },

  // 缓存操作阈值（毫秒）
  CACHE: {
    GET: 5,                // 缓存读取
    SET: 10,               // 缓存写入
    DELETE: 8,             // 缓存删除
  },

  // 业务操作阈值（毫秒）
  BUSINESS: {
    CREATE_ACCOUNT: 500,   // 创建账号
    VERIFY_ACCOUNT: 200,   // 验证账号
    BATCH_UPDATE: 1000,    // 批量更新
    STATISTICS: 300,       // 统计查询
  },

  // API接口阈值（毫秒）
  API: {
    SIMPLE_QUERY: 100,     // 简单查询接口
    COMPLEX_QUERY: 500,    // 复杂查询接口
    CREATE_OPERATION: 800, // 创建操作接口
    UPDATE_OPERATION: 600, // 更新操作接口
  },
} as const;

/**
 * 性能监控器类
 */
export class ZulipAccountsPerformanceMonitor {
  private static instance: ZulipAccountsPerformanceMonitor;
  private metrics: Map<string, PerformanceMetric[]> = new Map();
  private stats: Map<string, PerformanceStats> = new Map();
  private logger: AppLoggerService;

  private constructor(logger: AppLoggerService) {
    this.logger = logger;
  }

  /**
   * 获取单例实例
   */
  static getInstance(logger: AppLoggerService): ZulipAccountsPerformanceMonitor {
    if (!ZulipAccountsPerformanceMonitor.instance) {
      ZulipAccountsPerformanceMonitor.instance = new ZulipAccountsPerformanceMonitor(logger);
    }
    return ZulipAccountsPerformanceMonitor.instance;
  }

  /**
   * 创建性能监控器
   *
   * @param operation 操作名称
   * @param context 上下文信息
   * @returns 性能监控器对象
   */
  createMonitor(operation: string, context?: Record<string, any>) {
    const startTime = Date.now();

    return {
      /**
       * 记录成功完成
       */
      success: (additionalContext?: Record<string, any>) => {
        const endTime = Date.now();
        const duration = endTime - startTime;

        const metric: PerformanceMetric = {
          operation,
          duration,
          startTime,
          endTime,
          success: true,
          context: { ...context, ...additionalContext },
        };

        this.recordMetric(metric);
        this.checkThreshold(metric);
      },

      /**
       * 记录失败完成
       */
      error: (error: unknown, additionalContext?: Record<string, any>) => {
        const endTime = Date.now();
        const duration = endTime - startTime;
        const errorMessage = error instanceof Error ? error.message : String(error);

        const metric: PerformanceMetric = {
          operation,
          duration,
          startTime,
          endTime,
          success: false,
          context: { ...context, ...additionalContext },
          error: errorMessage,
        };

        this.recordMetric(metric);
        this.checkThreshold(metric);
      },
    };
  }

  /**
   * 记录性能指标
   *
   * @param metric 性能指标
   * @private
   */
  private recordMetric(metric: PerformanceMetric): void {
    // 存储原始指标
    if (!this.metrics.has(metric.operation)) {
      this.metrics.set(metric.operation, []);
    }

    const operationMetrics = this.metrics.get(metric.operation)!;
    operationMetrics.push(metric);

    // 保持最近1000条记录
    if (operationMetrics.length > 1000) {
      operationMetrics.shift();
    }

    // 更新统计信息
    this.updateStats(metric.operation);

    // 记录日志
    this.logger.debug('性能指标记录', {
      module: 'ZulipAccountsPerformanceMonitor',
      operation: 'recordMetric',
      metric: {
        operation: metric.operation,
        duration: metric.duration,
        success: metric.success,
      },
    });
  }

  /**
   * 更新统计信息
   *
   * @param operation 操作名称
   * @private
   */
  private updateStats(operation: string): void {
    const metrics = this.metrics.get(operation) || [];
    if (metrics.length === 0) return;

    const successMetrics = metrics.filter(m => m.success);
    const durations = metrics.map(m => m.duration).sort((a, b) => a - b);

    const stats: PerformanceStats = {
      operation,
      totalCalls: metrics.length,
      successCalls: successMetrics.length,
      failureCalls: metrics.length - successMetrics.length,
      successRate: (successMetrics.length / metrics.length) * 100,
      avgDuration: durations.reduce((sum, d) => sum + d, 0) / durations.length,
      minDuration: durations[0],
      maxDuration: durations[durations.length - 1],
      p95Duration: durations[Math.floor(durations.length * 0.95)],
      p99Duration: durations[Math.floor(durations.length * 0.99)],
      lastUpdated: new Date(),
    };

    this.stats.set(operation, stats);
  }

  /**
   * 检查性能阈值
   *
   * @param metric 性能指标
   * @private
   */
  private checkThreshold(metric: PerformanceMetric): void {
    const threshold = this.getThreshold(metric.operation);
    if (!threshold) return;

    if (metric.duration > threshold) {
      this.logger.warn('性能阈值超标', {
        module: 'ZulipAccountsPerformanceMonitor',
        operation: 'checkThreshold',
        metric: {
          operation: metric.operation,
          duration: metric.duration,
          threshold,
          exceeded: metric.duration - threshold,
        },
        context: metric.context,
      });
    }
  }

  /**
   * 获取操作的性能阈值
   *
   * @param operation 操作名称
   * @returns 阈值（毫秒）或null
   * @private
   */
  private getThreshold(operation: string): number | null {
    // 根据操作名称匹配阈值
    if (operation.includes('query') || operation.includes('find')) {
      if (operation.includes('batch') || operation.includes('many')) {
        return PERFORMANCE_THRESHOLDS.DATABASE.QUERY_BATCH;
      }
      return PERFORMANCE_THRESHOLDS.DATABASE.QUERY_SINGLE;
    }

    if (operation.includes('create')) {
      return PERFORMANCE_THRESHOLDS.DATABASE.INSERT;
    }

    if (operation.includes('update')) {
      return PERFORMANCE_THRESHOLDS.DATABASE.UPDATE;
    }

    if (operation.includes('delete')) {
      return PERFORMANCE_THRESHOLDS.DATABASE.DELETE;
    }

    if (operation.includes('transaction')) {
      return PERFORMANCE_THRESHOLDS.DATABASE.TRANSACTION;
    }

    if (operation.includes('cache')) {
      return PERFORMANCE_THRESHOLDS.CACHE.GET;
    }

    if (operation.includes('statistics')) {
      return PERFORMANCE_THRESHOLDS.BUSINESS.STATISTICS;
    }

    // 默认阈值
    return 1000;
  }

  /**
   * 获取操作的统计信息
   *
   * @param operation 操作名称
   * @returns 统计信息或null
   */
  getStats(operation: string): PerformanceStats | null {
    return this.stats.get(operation) || null;
  }

  /**
   * 获取所有统计信息
   *
   * @returns 所有统计信息
   */
  getAllStats(): PerformanceStats[] {
    return Array.from(this.stats.values());
  }

  /**
   * 获取性能报告
   *
   * @returns 性能报告
   */
  getPerformanceReport(): {
    summary: {
      totalOperations: number;
      avgSuccessRate: number;
      slowestOperations: Array<{ operation: string; avgDuration: number }>;
    };
    details: PerformanceStats[];
  } {
    const allStats = this.getAllStats();

    const summary = {
      totalOperations: allStats.length,
      avgSuccessRate: allStats.reduce((sum, s) => sum + s.successRate, 0) / allStats.length || 0,
      slowestOperations: allStats
        .sort((a, b) => b.avgDuration - a.avgDuration)
        .slice(0, 5)
        .map(s => ({ operation: s.operation, avgDuration: s.avgDuration })),
    };

    return {
      summary,
      details: allStats,
    };
  }

  /**
   * 清除历史数据
   *
   * @param operation 操作名称（可选，不提供则清除所有）
   */
  clearHistory(operation?: string): void {
    if (operation) {
      this.metrics.delete(operation);
      this.stats.delete(operation);
    } else {
      this.metrics.clear();
      this.stats.clear();
    }

    this.logger.info('性能监控历史数据已清除', {
      module: 'ZulipAccountsPerformanceMonitor',
      operation: 'clearHistory',
      clearedOperation: operation || 'all',
    });
  }
}

/**
 * 性能监控装饰器
 *
 * @param operation 操作名称
 * @returns 方法装饰器
 */
export function PerformanceMonitor(operation: string) {
  return function (_target: any, propertyName: string, descriptor: PropertyDescriptor) {
    const method = descriptor.value;

    descriptor.value = async function (...args: any[]) {
      const logger = (this as any).logger as AppLoggerService;
      if (!logger) {
        // 如果没有logger，直接执行原方法
        return method.apply(this, args);
      }

      const monitor = ZulipAccountsPerformanceMonitor
        .getInstance(logger)
        .createMonitor(operation, { method: propertyName });

      try {
        const result = await method.apply(this, args);
        monitor.success();
        return result;
      } catch (error) {
        monitor.error(error);
        throw error;
      }
    };

    return descriptor;
  };
}