/**
 * AI intervention encryption helpers — input + output ciphertext columns.
 * Both columns are nullable in the schema; callers pass null when nothing
 * to store (e.g. a tool call with no user-visible output).
 */

import { sql, eq, and, desc } from 'drizzle-orm';
import type { SQL } from 'drizzle-orm';
import { aiInterventions } from '@/server/db/schema';
import type { DrizzleClient } from '@/server/db/client';

export function encryptInterventionInput(plaintext: string, key: string): SQL {
  return sql`pgp_sym_encrypt(${plaintext}, ${key})`;
}
export function encryptInterventionOutput(plaintext: string, key: string): SQL {
  return sql`pgp_sym_encrypt(${plaintext}, ${key})`;
}

export interface DecryptedIntervention {
  id: string;
  parentType: 'ticket' | 'case' | 'return' | 'pending_return';
  parentId: string;
  agentName: string;
  toolName: string;
  input: string | null;
  output: string | null;
  confidence: number | null;
  decision: string;
  tokensIn: number | null;
  tokensOut: number | null;
  latencyMs: number | null;
  costUsd: string | null;
  createdAt: string;
}

export async function listDecryptedByParent(
  db: DrizzleClient,
  parentType: 'ticket' | 'case',
  parentId: string,
  key: string,
): Promise<DecryptedIntervention[]> {
  const rows = await db
    .select({
      id: aiInterventions.id,
      parentType: aiInterventions.parentType,
      parentId: aiInterventions.parentId,
      agentName: aiInterventions.agentName,
      toolName: aiInterventions.toolName,
      input: sql<
        string | null
      >`CASE WHEN ${aiInterventions.inputEncrypted} IS NULL THEN NULL ELSE pgp_sym_decrypt(CASE WHEN substring(${aiInterventions.inputEncrypted}::text, 1, 2) = '\\x' THEN ${aiInterventions.inputEncrypted}::bytea ELSE decode(${aiInterventions.inputEncrypted}::text, 'base64') END, ${key})::text END`,
      output: sql<
        string | null
      >`CASE WHEN ${aiInterventions.outputEncrypted} IS NULL THEN NULL ELSE pgp_sym_decrypt(CASE WHEN substring(${aiInterventions.outputEncrypted}::text, 1, 2) = '\\x' THEN ${aiInterventions.outputEncrypted}::bytea ELSE decode(${aiInterventions.outputEncrypted}::text, 'base64') END, ${key})::text END`,
      confidence: aiInterventions.confidence,
      decision: aiInterventions.decision,
      tokensIn: aiInterventions.tokensIn,
      tokensOut: aiInterventions.tokensOut,
      latencyMs: aiInterventions.latencyMs,
      costUsd: aiInterventions.costUsd,
      createdAt: aiInterventions.createdAt,
    })
    .from(aiInterventions)
    .where(and(eq(aiInterventions.parentType, parentType), eq(aiInterventions.parentId, parentId)))
    .orderBy(desc(aiInterventions.createdAt));

  return rows.map((r) => ({
    id: r.id,
    parentType: r.parentType,
    parentId: r.parentId,
    agentName: r.agentName,
    toolName: r.toolName,
    input: r.input,
    output: r.output,
    confidence: r.confidence != null ? Number(r.confidence) : null,
    decision: r.decision,
    tokensIn: r.tokensIn,
    tokensOut: r.tokensOut,
    latencyMs: r.latencyMs,
    costUsd: r.costUsd,
    createdAt: r.createdAt.toISOString(),
  }));
}
