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

/**
 * M-AI-05-06: Feynman 可观测性服务
 *
 * 提供结构化日志和内存计数器，满足验收标准：
 * - 日志可关联完整链路（requestId → jobId → knowledgeItemId → submissionId）
 * - 统计 Legacy/Unified 请求量、成功率、耗时、重试、回滚
 * - FocusItem/ReviewCard 创建数量
 *
 * 计数器为内存级（不持久化），用于 Admin 查询和告警。
 * 生产环境建议对接 Prometheus/Grafana 或 Admin 指标接口。
 *
 * 约束：
 * - 不记录完整用户解释（userExplanation）
 * - 不记录完整模型输出（validatedOutput / rawResult）
 * - 不记录内部堆栈或 Credential
 */

export interface FeynmanRequestLog {
  requestId: string;
  jobId?: string;
  knowledgeItemId: string;
  userId: string;
  engineMode: 'legacy' | 'unified';
  jobType: string;
  queueName: string;
  submissionId?: string;
  durationMs?: number;
  lifecycleStatus?: string;
  errorCode?: string;
  attemptCount?: number;
  focusItemCount?: number;
  reviewCardCount?: number;
}

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

  // ── 内存计数器 ──

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

  // ── 结构化日志 ──

  /**
   * 记录 Feynman 请求（HTTP 入口）。
   * 不记录用户完整解释内容。
   */
  logRequest(log: FeynmanRequestLog): void {
    this.logger.log(
      `[Feynman] request: requestId=${log.requestId} ` +
      `knowledgeItemId=${log.knowledgeItemId} userId=${log.userId} ` +
      `engine=${log.engineMode} jobType=${log.jobType} submissionId=${log.submissionId || 'N/A'}`,
    );
  }

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

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

  /**
   * 记录执行完成。
   * 不记录 validatedOutput 或 rawResult。
   */
  logExecutionCompleted(log: FeynmanRequestLog): void {
    this.logger.log(
      `[Feynman] execution_completed: jobId=${log.jobId} ` +
      `knowledgeItemId=${log.knowledgeItemId} userId=${log.userId} ` +
      `durationMs=${log.durationMs} lifecycleStatus=${log.lifecycleStatus} ` +
      `attemptCount=${log.attemptCount} ` +
      `focusItems=${log.focusItemCount ?? 0} reviewCards=${log.reviewCardCount ?? 0}`,
    );
  }

  /**
   * 记录执行失败。
   * 不记录内部堆栈或 Snapshot。
   */
  logExecutionFailed(log: FeynmanRequestLog, error: string): void {
    this.logger.warn(
      `[Feynman] execution_failed: jobId=${log.jobId} ` +
      `knowledgeItemId=${log.knowledgeItemId} userId=${log.userId} ` +
      `errorCode=${log.errorCode} error=${error}`,
    );
  }

  /**
   * 记录回滚事件。
   */
  logRollback(userId: string, reason: string): void {
    this.logger.warn(
      `[Feynman] 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++; }

  addFocusItemCreated(count: number): void { this.counters.focusItemCreated += count; }
  addReviewCardCreated(count: number): void { this.counters.reviewCardCreated += count; }

  // ── 查询 ──

  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,
      focusItemCreated: 0,
      reviewCardCreated: 0,
      rollbackCount: 0,
    };
  }
}
