import { Injectable, Logger } from '@nestjs/common';
import type { Prisma } from '@prisma/client';
import {
  ResultProjector,
  ProjectionContext,
  ArtifactReference,
} from './result-projector.interface';

/**
 * M-AI-03-09: Synthetic Result Projector（仅测试环境注册）
 *
 * 将 synthetic_job 的 validatedOutput 写入测试用的 AiLearningAnalysis 表，
 * 作为 Projector 框架的端到端验证。
 *
 * 生产环境不注册此 Projector（不注册 synthetic_job Definition）。
 */
@Injectable()
export class SyntheticResultProjector implements ResultProjector {
  readonly key = 'synthetic_projector';
  private readonly logger = new Logger(SyntheticResultProjector.name);

  async project(
    tx: Prisma.TransactionClient,
    context: ProjectionContext,
  ): Promise<ArtifactReference[]> {
    const { job, validatedOutput } = context;

    // 幂等：如果此 job 已有 artifact，直接返回
    const existing = await tx.aiJobArtifact.findMany({
      where: { jobId: job.id },
      orderBy: { ordinal: 'asc' },
    });
    if (existing.length > 0) {
      this.logger.log(`Synthetic projector: returning ${existing.length} existing artifact(s) for job=${job.id}`);
      return existing.map((a) => ({
        artifactType: a.artifactType,
        artifactId: a.artifactId,
        ordinal: a.ordinal,
      }));
    }

    const artifacts: ArtifactReference[] = [];

    // 写入测试分析结果
    if (validatedOutput) {
      const analysis = await tx.aiLearningAnalysis.create({
        data: {
          userId: job.userId,
          jobId: job.id,
          snapshotId: job.snapshotId,
          targetType: job.targetType ?? 'synthetic',
          targetId: job.targetId ?? 'test',
          learningState: validatedOutput.learningState ?? null,
          summary: validatedOutput.summary ?? 'Synthetic test result',
          riskLevel: validatedOutput.riskLevel ?? 'low',
          confidence: validatedOutput.confidence ?? 0.9,
          evidence: validatedOutput.evidence ?? undefined,
          promptVersion: job.promptVersion,
          schemaVersion: job.outputSchemaVersion,
        },
      });

      // 写入 Artifact 引用
      await tx.aiJobArtifact.create({
        data: {
          jobId: job.id,
          artifactType: 'AiLearningAnalysis',
          artifactId: analysis.id,
          ordinal: 0,
          metadata: { generatedBy: 'synthetic_projector' } as any,
        },
      });
      artifacts.push({
        artifactType: 'AiLearningAnalysis',
        artifactId: analysis.id,
        ordinal: 0,
      });
    }

    this.logger.log(`Synthetic projector: created ${artifacts.length} artifact(s) for job=${job.id}`);
    return artifacts;
  }
}
