import { Injectable, ServiceUnavailableException } from '@nestjs/common';
import { createLogger } from '@core/observability/logging/config/winston.config';
import { createHash } from 'crypto';
import { PrismaService } from '@core/database/prisma/prisma.service';

const logger = createLogger('TrajectoryAnchorService');

/**
 * PR4c 异质外部锚定（两路）。
 *
 * **状态**：接口骨架已就位；实际跑通需外部基础设施（不在本 session 范围）：
 *
 *   路 A — **AWS S3 Object Lock (Compliance mode)**：
 *     周期性把当前 chain head（最新 eventHash + 时间戳）写入 S3 不可变 bucket。
 *     需要：AWS 凭证 + 已创建的 Object Lock bucket + IAM 写权限。
 *
 *   路 B — **第三方 TSA (RFC 3161 Time-Stamping Authority)**：
 *     把 chain head hash 提交 TSA → 拿带时间戳的签名 token 回来落库。
 *     需要：选定 TSA 服务（如 FreeTSA / DigiCert）+ 网络白名单。
 *
 * 两路独立，任一被攻陷另一路仍可独立校验，提升 evidence trustworthiness。
 * 详见 docs/modules/agent/02-architecture.md §1.13（如已建）/ PRD PR4c。
 *
 * **本 session 不跑 anchor**——`isConfigured()` 永远 false，调用端跳过。
 * 落 AWS/TSA 凭证 + feature flag `FFAI_ANCHOR_ENABLED=true` 后才启用。
 */
@Injectable()
export class TrajectoryAnchorService {
  constructor(private readonly prisma: PrismaService) {}

  isConfigured(): boolean {
    const s3 = !!process.env.FFAI_ANCHOR_S3_BUCKET && !!process.env.AWS_REGION;
    const tsa = !!process.env.FFAI_ANCHOR_TSA_URL;
    const enabled = process.env.FFAI_ANCHOR_ENABLED === 'true';
    return enabled && (s3 || tsa);
  }

  /**
   * 计算"当前 organization 全 chain head 摘要"——把所有 session 最新 eventHash
   * 按 sessionId 排序拼接后 sha256，作为 anchor 候选。
   */
  async computeOrgChainHead(organizationId: string): Promise<{
    head: string;
    sessionCount: number;
    capturedAt: Date;
  }> {
    const heads = await this.prisma.$queryRawUnsafe<Array<{ sessionId: string; eventHash: string }>>(
      `SELECT DISTINCT ON ("sessionId") "sessionId", "eventHash"
       FROM "platform_ai"."agent_trajectory_events"
       WHERE "organizationId" = $1::uuid
       ORDER BY "sessionId", "sequenceInSession" DESC`,
      organizationId,
    );
    heads.sort((a, b) => a.sessionId.localeCompare(b.sessionId));
    const concat = heads.map((h) => h.sessionId + ':' + h.eventHash).join('|');
    const head = createHash('sha256').update(concat).digest('hex');
    return { head, sessionCount: heads.length, capturedAt: new Date() };
  }

  async anchorS3(_organizationId: string, _head: string): Promise<{ anchorId: string }> {
    if (!this.isConfigured()) {
      throw new ServiceUnavailableException(
        'TrajectoryAnchor not configured (need FFAI_ANCHOR_ENABLED + AWS_REGION + S3 bucket)',
      );
    }
    // TODO: putObject with Object Lock retention; return ETag as anchorId
    throw new Error('not yet implemented — needs aws-sdk integration + bucket setup');
  }

  async anchorTSA(_head: string): Promise<{ anchorId: string; signedTokenBase64: string }> {
    if (!this.isConfigured()) {
      throw new ServiceUnavailableException('TrajectoryAnchor not configured');
    }
    // TODO: POST request to TSA URL with hash → store returned RFC3161 token
    throw new Error('not yet implemented — needs TSA URL + RFC 3161 client');
  }

  /**
   * 定期任务入口：每天/每小时把所有 org 的 chain head 双路锚定。
   * 由 @Cron 在调度模块里挂时间表（PR4c 后续 + Ops dashboard）。
   */
  async anchorAllOrganizations(): Promise<void> {
    if (!this.isConfigured()) {
      logger.warn('anchorAllOrganizations skipped — TrajectoryAnchor not configured');
      return;
    }
    // TODO: 列 active organizations → 串行/限速 anchor S3 + TSA
    logger.warn('anchorAllOrganizations stub — implementation pending external infra');
  }
}
