import { Injectable, Logger } from '@nestjs/common';

/**
 * M-AI-04-06: Active Recall 可观测性服务
 *
 * 提供结构化日志和内存计数器，满足验收标准：
 * - 日志可关联完整链路（requestId → jobId → activeRecallId）
 * - 统计 Legacy/Unified 请求量、成功率、耗时、重试、回滚
 *
 * 计数器为内存级（不持久化），用于 Admin 查询和告警。
 * 生产环境建议对接 Prometheus/Grafana 或 Admin 指标接口。
 */

export interface ActiveRecallRequestLog {
  requestId: string;
  jobId?: string;
  activeRecallId: string;
  userId: string;
  engineMode: 'legacy' | 'unified';
  jobType: string;
  queueName: string;
  durationMs?: number;
  lifecycleStatus?: string;
  errorCode?: string;
  attemptCount?: number;
}

@Injectable()
export class ActiveRecallObservabilityService {
  private readonly logger = new Logger(ActiveRecallObservabilityService.name);

  // ── 内存计数器 ──

  private counters = {
    legacyRequests: 0,
    unifiedRequests: 0,
    unifiedCreateFailed: 0,
    unifiedExecuteSuccess: 0,
    unifiedExecuteFailed: 0,
    unifiedTotalDurationMs: 0,
    unifiedExecuteCount: 0,
    unifiedRetryCount: 0,
    projectorFailed: 0,
    rollbackCount: 0,
  };

  // ── 结构化日志 ──

  /**
   * 记录 Active Recall 请求（HTTP 入口）。
   * 不记录用户完整答案。
   */
  logRequest(log: ActiveRecallRequestLog): void {
    this.logger.log(
      `[ActiveRecall] request: requestId=${log.requestId} ` +
      `activeRecallId=${log.activeRecallId} userId=${log.userId} ` +
      `engine=${log.engineMode} jobType=${log.jobType}`,
    );
  }

  /**
   * 记录 Job 创建成功。
   */
  logJobCreated(log: ActiveRecallRequestLog): void {
    this.logger.log(
      `[ActiveRecall] job_created: requestId=${log.requestId} ` +
      `jobId=${log.jobId} activeRecallId=${log.activeRecallId} ` +
      `engine=${log.engineMode} queueName=${log.queueName}`,
    );
  }

  /**
   * 记录 Job 创建失败。
   * 使用 warn 级别 — 不记录用户完整答案。
   */
  logJobCreateFailed(log: ActiveRecallRequestLog, error: string): void {
    this.logger.warn(
      `[ActiveRecall] job_create_failed: requestId=${log.requestId} ` +
      `activeRecallId=${log.activeRecallId} userId=${log.userId} ` +
      `engine=${log.engineMode} error=${error}`,
    );
  }

  /**
   * 记录执行完成。
   */
  logExecutionCompleted(log: ActiveRecallRequestLog): void {
    this.logger.log(
      `[ActiveRecall] execution_completed: jobId=${log.jobId} ` +
      `activeRecallId=${log.activeRecallId} userId=${log.userId} ` +
      `durationMs=${log.durationMs} lifecycleStatus=${log.lifecycleStatus} ` +
      `attemptCount=${log.attemptCount}`,
    );
  }

  /**
   * 记录执行失败。
   */
  logExecutionFailed(log: ActiveRecallRequestLog, error: string): void {
    this.logger.warn(
      `[ActiveRecall] execution_failed: jobId=${log.jobId} ` +
      `activeRecallId=${log.activeRecallId} userId=${log.userId} ` +
      `errorCode=${log.errorCode} error=${error}`,
    );
  }

  /**
   * 记录回滚事件。
   */
  logRollback(userId: string, reason: string): void {
    this.logger.warn(
      `[ActiveRecall] rollback: userId=${userId} reason=${reason}`,
    );
  }

  // ── 计数器操作 ──

  incrementLegacyRequests(): void {
    this.counters.legacyRequests++;
  }

  incrementUnifiedRequests(): void {
    this.counters.unifiedRequests++;
  }

  incrementUnifiedCreateFailed(): void {
    this.counters.unifiedCreateFailed++;
  }

  incrementUnifiedExecuteSuccess(durationMs: number): void {
    this.counters.unifiedExecuteSuccess++;
    this.counters.unifiedTotalDurationMs += durationMs;
    this.counters.unifiedExecuteCount++;
  }

  incrementUnifiedExecuteFailed(): void {
    this.counters.unifiedExecuteFailed++;
  }

  incrementUnifiedRetry(): void {
    this.counters.unifiedRetryCount++;
  }

  incrementProjectorFailed(): void {
    this.counters.projectorFailed++;
  }

  incrementRollback(): void {
    this.counters.rollbackCount++;
  }

  // ── 查询 ──

  getCounters() {
    return {
      ...this.counters,
      unifiedAvgDurationMs:
        this.counters.unifiedExecuteCount > 0
          ? Math.round(this.counters.unifiedTotalDurationMs / this.counters.unifiedExecuteCount)
          : 0,
    };
  }

  resetCounters(): void {
    this.counters = {
      legacyRequests: 0,
      unifiedRequests: 0,
      unifiedCreateFailed: 0,
      unifiedExecuteSuccess: 0,
      unifiedExecuteFailed: 0,
      unifiedTotalDurationMs: 0,
      unifiedExecuteCount: 0,
      unifiedRetryCount: 0,
      projectorFailed: 0,
      rollbackCount: 0,
    };
  }
}
