// ${VOCAB.factory} Integration
// Connects artifact generation to agent workflows

import prisma from '@/lib/db';
import { logSimpleAction } from './agent-logger';
import { VOCAB } from '@/lib/white-label/constants';

export type JobType = 
  | 'artifact_generation'
  | 'report_creation'
  | 'data_analysis'
  | 'document_generation'
  | 'email_campaign'
  | 'compliance_check';

export type TriggerSource =
  | 'inventory_alert'
  | 'ar_overdue'
  | 'ap_overdue'
  | 'expense_anomaly'
  | 'order_completed'
  | 'scheduled'
  | 'manual';

export interface JobInput {
  jobType: JobType;
  triggerSource: TriggerSource;
  triggerId?: string;
  input: Record<string, unknown>;
}

// Queue a new ${VOCAB.factory} job
export async function queueDarkFactoryJob(input: JobInput): Promise<string> {
  const job = await prisma.darkFactoryJob.create({
    data: {
      jobType: input.jobType,
      triggerSource: input.triggerSource,
      triggerId: input.triggerId,
      input: JSON.parse(JSON.stringify(input.input)),
      status: 'queued',
    },
  });
  
  await logSimpleAction({
    actionType: 'create_transaction',
    targetEntity: 'DarkFactoryJob',
    targetId: job.id,
    input: { jobType: input.jobType, triggerSource: input.triggerSource },
    output: { status: 'queued' },
    confidence: 1.0,
  });
  
  return job.id;
}

// Process a queued job (simulated - in production would call ${VOCAB.factory} API)
export async function processJob(jobId: string): Promise<void> {
  const job = await prisma.darkFactoryJob.findUnique({
    where: { id: jobId },
  });
  
  if (!job || job.status !== 'queued') return;
  
  const startTime = Date.now();
  
  await prisma.darkFactoryJob.update({
    where: { id: jobId },
    data: {
      status: 'processing',
      startedAt: new Date(),
    },
  });
  
  try {
    // Simulate job processing based on type
    let output: Record<string, unknown> = {};
    let artifactIds: string[] = [];
    
    switch (job.jobType) {
      case 'report_creation':
        // Generate a report artifact
        output = {
          reportType: (job.input as Record<string, unknown>).reportType || 'summary',
          generatedAt: new Date().toISOString(),
          format: 'pdf',
        };
        artifactIds = [`artifact-${Date.now()}`];
        break;
        
      case 'data_analysis':
        output = {
          analysisType: (job.input as Record<string, unknown>).analysisType || 'general',
          insights: [
            'Trend analysis complete',
            'Anomalies detected: 0',
            'Recommendations generated',
          ],
        };
        break;
        
      case 'document_generation':
        output = {
          documentType: (job.input as Record<string, unknown>).documentType,
          generatedAt: new Date().toISOString(),
        };
        artifactIds = [`doc-${Date.now()}`];
        break;
        
      case 'compliance_check':
        output = {
          checkType: (job.input as Record<string, unknown>).checkType,
          passed: true,
          issues: [],
        };
        break;
        
      default:
        output = { processed: true };
    }
    
    const executionTime = Date.now() - startTime;
    
    await prisma.darkFactoryJob.update({
      where: { id: jobId },
      data: {
        status: 'completed',
        output: JSON.parse(JSON.stringify(output)),
        artifactIds: JSON.parse(JSON.stringify(artifactIds)),
        completedAt: new Date(),
        executionTimeMs: executionTime,
      },
    });
    
    await logSimpleAction({
      actionType: 'confirm_payment', // Using existing action type
      targetEntity: 'DarkFactoryJob',
      targetId: jobId,
      input: { jobType: job.jobType },
      output: { status: 'completed', executionTimeMs: executionTime },
      confidence: 1.0,
    });
    
  } catch (error) {
    await prisma.darkFactoryJob.update({
      where: { id: jobId },
      data: {
        status: 'failed',
        error: String(error),
        completedAt: new Date(),
        executionTimeMs: Date.now() - startTime,
      },
    });
  }
}

// Process all queued jobs
export async function processQueuedJobs(): Promise<{
  processed: number;
  completed: number;
  failed: number;
}> {
  const queuedJobs = await prisma.darkFactoryJob.findMany({
    where: { status: 'queued' },
    orderBy: { createdAt: 'asc' },
    take: 10,
  });
  
  let completed = 0;
  let failed = 0;
  
  for (const job of queuedJobs) {
    try {
      await processJob(job.id);
      const updated = await prisma.darkFactoryJob.findUnique({ where: { id: job.id } });
      if (updated?.status === 'completed') completed++;
      else if (updated?.status === 'failed') failed++;
    } catch {
      failed++;
    }
  }
  
  return {
    processed: queuedJobs.length,
    completed,
    failed,
  };
}

// Trigger jobs based on events
export async function triggerInventoryReorderReport(
  alertId: string,
  productName: string,
  currentStock: number
): Promise<string> {
  return queueDarkFactoryJob({
    jobType: 'report_creation',
    triggerSource: 'inventory_alert',
    triggerId: alertId,
    input: {
      reportType: 'inventory_reorder',
      productName,
      currentStock,
      timestamp: new Date().toISOString(),
    },
  });
}

export async function triggerARAgingReport(): Promise<string> {
  return queueDarkFactoryJob({
    jobType: 'report_creation',
    triggerSource: 'ar_overdue',
    input: {
      reportType: 'ar_aging',
      timestamp: new Date().toISOString(),
    },
  });
}

export async function triggerExpenseAnalysis(): Promise<string> {
  return queueDarkFactoryJob({
    jobType: 'data_analysis',
    triggerSource: 'scheduled',
    input: {
      analysisType: 'expense_trends',
      timestamp: new Date().toISOString(),
    },
  });
}

export async function getJobStats(): Promise<{
  totalJobs: number;
  queued: number;
  processing: number;
  completed: number;
  failed: number;
  avgExecutionTime: number;
}> {
  const [statusCounts, avgTime] = await Promise.all([
    prisma.darkFactoryJob.groupBy({
      by: ['status'],
      _count: true,
    }),
    prisma.darkFactoryJob.aggregate({
      where: { status: 'completed' },
      _avg: { executionTimeMs: true },
    }),
  ]);
  
  const result = {
    totalJobs: 0,
    queued: 0,
    processing: 0,
    completed: 0,
    failed: 0,
    avgExecutionTime: avgTime._avg.executionTimeMs || 0,
  };
  
  for (const sc of statusCounts) {
    result.totalJobs += sc._count;
    if (sc.status === 'queued') result.queued = sc._count;
    if (sc.status === 'processing') result.processing = sc._count;
    if (sc.status === 'completed') result.completed = sc._count;
    if (sc.status === 'failed') result.failed = sc._count;
  }
  
  return result;
}

export async function getRecentJobs(limit: number = 20): Promise<Array<{
  id: string;
  jobType: string;
  triggerSource: string;
  status: string;
  executionTimeMs: number | null;
  createdAt: Date;
  completedAt: Date | null;
}>> {
  return prisma.darkFactoryJob.findMany({
    orderBy: { createdAt: 'desc' },
    take: limit,
  });
}
