// Gap Audit Engine Service
// Main gap scanning across multiverse systems, temporal ledgers, quantum chains, cognitive-intent layers, DLT/metaverse ecosystems

import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';
import { gapDetectionService } from './gap-detection.service';
import { moduleGeneratorService } from './module-generator.service';
import { recommendationsEngineService } from './recommendations-engine.service';


export interface GapAuditRequest {
  auditScope: Array<
    'multiverse' | 'temporal' | 'quantum' | 'cognitive' | 'dlt' | 'metaverse'
  >;
  includeRecommendations?: boolean;
}

export interface GapAuditResult {
  auditId: string;
  gapsFound: number;
  modulesGenerated: number;
  recommendationsCount: number;
  status: string;
}

export class GapAuditEngineService {
  /**
   * Execute comprehensive gap audit
   * Scans all DBIS systems for gaps
   */
  async executeGapAudit(
    request: GapAuditRequest
  ): Promise<GapAuditResult> {
    logger.info('Gap Audit: Starting comprehensive audit', { request });

    const auditId = `GAP-AUDIT-${uuidv4()}`;

    // Step 1: Create audit record
    const audit = await prisma.gap_audits.create({
      data: {
        id: uuidv4(),
        auditId,
        auditScope: request.auditScope as any,
        status: 'running',
        updatedAt: new Date(),
      },
    });

    try {
      // Step 2: Scan for gaps in each scope
      const allGaps: any[] = [];

      for (const scope of request.auditScope) {
        const gaps = await gapDetectionService.detectGaps(scope);
        allGaps.push(...gaps);

        // Save gap detections
        for (const gap of gaps) {
          await prisma.gap_detections.create({
            data: {
              id: uuidv4(),
              detectionId: `GAP-DET-${uuidv4()}`,
              auditId: audit.id, // Use the id field, not auditId
              gapType: gap.gapType,
              systemScope: scope,
              description: gap.description,
              severity: gap.severity,
              status: 'detected',
              updatedAt: new Date(),
            },
          });
        }
      }

      // Step 3: Generate modules for detected gaps
      let modulesGenerated = 0;
      for (const gap of allGaps) {
        if (gap.autoGenerate) {
          const moduleId = await moduleGeneratorService.generateModule(
            gap.gapType
          );
          if (moduleId) {
            modulesGenerated++;
          }
        }
      }

      // Step 4: Generate recommendations if requested
      let recommendationsCount = 0;
      if (request.includeRecommendations) {
        const recommendations =
          await recommendationsEngineService.generateRecommendations(allGaps);
        recommendationsCount = recommendations.length;

        for (const recommendation of recommendations) {
          await prisma.system_recommendations.create({
            data: {
              id: uuidv4(),
              recommendationId: `REC-${uuidv4()}`,
              auditId: audit.id, // Use the id field, not auditId
              recommendationType: recommendation.type,
              title: recommendation.title,
              description: recommendation.description,
              priority: recommendation.priority,
              status: 'pending',
              updatedAt: new Date(),
            },
          });
        }
      }

      // Step 5: Update audit status
      await prisma.gap_audits.update({
        where: { auditId },
        data: {
          status: 'completed',
          gapsFound: allGaps.length,
          modulesGenerated,
          recommendationsCount,
          completedAt: new Date(),
        },
      });

      logger.info('Gap Audit: Audit completed', {
        auditId,
        gapsFound: allGaps.length,
        modulesGenerated,
      });

      return {
        auditId,
        gapsFound: allGaps.length,
        modulesGenerated,
        recommendationsCount,
        status: 'completed',
      };
    } catch (error) {
      await prisma.gap_audits.update({
        where: { auditId },
        data: {
          status: 'failed',
        },
      });

      throw error;
    }
  }

  /**
   * Get audit by ID
   */
  async getAudit(auditId: string) {
    return await prisma.gap_audits.findUnique({
      where: { auditId },
      include: {
        gap_detections: true,
        system_recommendations: true,
      },
    });
  }

  /**
   * Get audit history
   */
  async getAuditHistory(limit: number = 100) {
    return await prisma.gap_audits.findMany({
      orderBy: { createdAt: 'desc' },
      take: limit,
      include: {
        gap_detections: true,
        system_recommendations: true,
      },
    });
  }
}

export const gapAuditEngineService = new GapAuditEngineService();

