import { Injectable, Logger, NotFoundException, ForbiddenException } from '@nestjs/common';
import * as crypto from 'crypto';
import { ActiveRecallRepository } from './active-recall.repository';
import { AiAnalysisService } from '../ai-analysis/ai-analysis.service';
import { AiJobCreationService } from '../ai-job/ai-job-creation.service';
import { ActiveRecallExecutionRouter } from '../ai-job/active-recall-execution-router';
import { ActiveRecallObservabilityService } from '../ai-job/active-recall-observability.service';
import type { PaginationDto } from '../../common/dto/pagination.dto';

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

  constructor(
    private readonly repository: ActiveRecallRepository,
    private readonly analysisService: AiAnalysisService,
    private readonly jobCreationService: AiJobCreationService,
    private readonly router: ActiveRecallExecutionRouter,
    private readonly observability: ActiveRecallObservabilityService,
  ) {}

  async findByUserId(userId: string, pagination: PaginationDto) {
    return this.repository.findByUserId(userId, pagination);
  }

  async submit(userId: string, questionId: string, body: { answerText: string }) {
    const requestId = crypto.randomUUID();
    const startTime = Date.now();

    const question = await this.repository.findById(questionId);
    if (!question) throw new NotFoundException('问题不存在');

    // M-AI-04-01 关键发现 #2 P0 修复：校验 question 所有权
    if (question.userId !== userId) {
      throw new ForbiddenException('无权提交此问题的回答');
    }

    const answer = await this.repository.createAnswer(userId, questionId, body);

    // M-AI-04-05: 分支路由 — 由单一 Router 决定 Legacy vs Unified
    const useUnified = await this.router.shouldUseUnified(userId);
    const engineMode = useUnified ? 'unified' : 'legacy';

    if (useUnified) {
      // ── Unified 路径（AiJobCreationService → Unified Job Engine）──
      this.observability.incrementUnifiedRequests();

      const logBase = {
        requestId,
        activeRecallId: question.id,
        userId,
        engineMode: 'unified' as const,
        jobType: 'active_recall',
        queueName: 'ai-interactive',
      };

      this.observability.logRequest(logBase);

      try {
        const idempotencyKey = `active-recall:${answer.id}`;
        const job = await this.jobCreationService.createJob({
          userId,
          jobType: 'active_recall',
          triggerType: 'user_api',
          targetType: 'active_recall_answer',
          targetId: answer.id,
          idempotencyKey,
        });

        const durationMs = Date.now() - startTime;

        this.observability.logJobCreated({ ...logBase, jobId: job.id, durationMs });
        this.logger.log(
          `Unified job created: requestId=${requestId} jobId=${job.id} ` +
          `answerId=${answer.id} durationMs=${durationMs}`,
        );

        return {
          ...answer,
          jobId: job.id,
          engine: 'unified' as const,
        };
      } catch (err: any) {
        this.observability.incrementUnifiedCreateFailed();
        this.observability.logJobCreateFailed(logBase, err.message);
        this.logger.error(
          `Unified job creation failed: requestId=${requestId} ` +
          `answerId=${answer.id} error=${err.message}`,
        );
        // 失败不降级到 Legacy（防止双写），返回 answer + 错误标记
        return {
          ...answer,
          jobId: null,
          engine: 'unified' as const,
          error: 'AI analysis queuing failed',
        };
      }
    }

    // ── Legacy 路径（原有 AiAnalysisService，行为不变）──
    this.observability.incrementLegacyRequests();

    try {
      const { jobId } = await this.analysisService.analyze(userId, {
        questionText: question.questionText,
        knowledgeItemContent: '',
        userAnswer: body.answerText,
        answerId: answer.id,
      });

      const durationMs = Date.now() - startTime;
      this.logger.log(
        `Legacy AI analysis queued: requestId=${requestId} ` +
        `answerId=${answer.id} jobId=${jobId} durationMs=${durationMs}`,
      );

      return { ...answer, jobId, engine: 'legacy' as const };
    } catch (err: any) {
      this.logger.error(
        `Legacy analysis failed: requestId=${requestId} ` +
        `answerId=${answer.id} error=${err.message}`,
      );
    }

    return answer;
  }
}
