/**
 * Sniff-Check Gate System
 * Human verification at critical decision points
 */

import prisma from '@/lib/db';
import { AnomalyResult, SniffCheckPriority, DEFAULT_THRESHOLDS } from './types';

interface CreateSniffCheckParams {
  executionId?: string;
  actionId?: string;
  gateType: 'anomaly_review' | 'high_value_approval' | 'pattern_change' | 'manual_override';
  triggerReason: string;
  priority: SniffCheckPriority;
  entityType: string;
  entityId: string;
  entitySnapshot: Record<string, unknown>;
  proposedAction: Record<string, unknown>;
  autoApproveDelayMinutes?: number;
}

export async function createSniffCheck(params: CreateSniffCheckParams): Promise<string> {
  const {
    executionId,
    actionId,
    gateType,
    triggerReason,
    priority,
    entityType,
    entityId,
    entitySnapshot,
    proposedAction,
    autoApproveDelayMinutes,
  } = params;

  let autoApproveAt: Date | undefined;
  if (priority === 'low' || priority === 'normal') {
    const delay = autoApproveDelayMinutes || DEFAULT_THRESHOLDS.autoApproveDelayMinutes;
    autoApproveAt = new Date();
    autoApproveAt.setMinutes(autoApproveAt.getMinutes() + delay);
  }

  const expiresAt = new Date();
  if (priority === 'critical') {
    expiresAt.setHours(expiresAt.getHours() + 1);
  } else {
    expiresAt.setHours(expiresAt.getHours() + 24);
  }

  const gate = await prisma.sniffCheckGate.create({
    data: {
      executionId,
      actionId,
      gateType,
      triggerReason,
      priority,
      entityType,
      entityId,
      entitySnapshot: JSON.parse(JSON.stringify(entitySnapshot)),
      proposedAction: JSON.parse(JSON.stringify(proposedAction)),
      status: 'pending',
      autoApproveAt,
      expiresAt,
    },
  });

  return gate.id;
}

export async function resolveSniffCheck(
  gateId: string,
  reviewedBy: string,
  decision: 'approved' | 'rejected',
  notes?: string
): Promise<void> {
  await prisma.sniffCheckGate.update({
    where: { id: gateId },
    data: {
      status: decision,
      reviewedBy,
      reviewedAt: new Date(),
      reviewNotes: notes,
    },
  });
}

export async function getPendingSniffChecks(limit = 50) {
  return prisma.sniffCheckGate.findMany({
    where: { status: 'pending' },
    orderBy: [
      { priority: 'desc' },
      { createdAt: 'asc' },
    ],
    take: limit,
  });
}

export async function getSniffCheckStats() {
  const [pending, approved, rejected, autoApproved, expired] = await Promise.all([
    prisma.sniffCheckGate.count({ where: { status: 'pending' } }),
    prisma.sniffCheckGate.count({ where: { status: 'approved' } }),
    prisma.sniffCheckGate.count({ where: { status: 'rejected' } }),
    prisma.sniffCheckGate.count({ where: { status: 'auto_approved' } }),
    prisma.sniffCheckGate.count({ where: { status: 'expired' } }),
  ]);

  return { pending, approved, rejected, autoApproved, expired };
}

export function createSniffCheckFromAnomaly(
  anomaly: AnomalyResult,
  entityType: string,
  entityId: string,
  entitySnapshot: Record<string, unknown>,
  executionId?: string
): Promise<string> {
  return createSniffCheck({
    executionId,
    gateType: 'anomaly_review',
    triggerReason: `Anomaly detected: ${anomaly.type}`,
    priority: anomaly.severity,
    entityType,
    entityId,
    entitySnapshot,
    proposedAction: {
      action: 'continue_processing',
      anomalyType: anomaly.type,
      anomalyDetails: anomaly.details,
      confidence: anomaly.confidence,
    },
  });
}
