// GPU Edge Routing Service
// 6G network routing with ultra-low latency (<1ms)

import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';


export interface GpuEdgeRoutingRequest {
  sourceRegionId: string;
  targetRegionId: string;
  taskType: 'metaverse' | 'quantum' | 'zk' | 'ai';
  latencyRequirement?: number; // Milliseconds (default: <1ms)
}

export interface GpuEdgeRoutingResult {
  routeId: string;
  path: string[];
  estimatedLatency: number;
  quantumSafe: boolean;
}

export class GpuEdgeRoutingService {
  /**
   * Calculate optimal 6G route for GPU edge task
   * Ultra-low latency requirement: <1ms
   */
  async calculateOptimalRoute(
    request: GpuEdgeRoutingRequest
  ): Promise<GpuEdgeRoutingResult> {
    logger.info('GPU Edge: Calculating optimal 6G route', { request });

    const latencyRequirement = request.latencyRequirement || 1; // <1ms default

    // Step 1: Get available nodes in source and target regions
    const sourceNodes = await prisma.gpuEdgeNode.findMany({
      where: {
        regionId: request.sourceRegionId,
        status: 'active',
      },
    });

    const targetNodes = await prisma.gpuEdgeNode.findMany({
      where: {
        regionId: request.targetRegionId,
        status: 'active',
      },
    });

    if (sourceNodes.length === 0 || targetNodes.length === 0) {
      throw new Error('No nodes available in source or target region');
    }

    // Step 2: Select appropriate node type based on task
    const nodeTypeMap: Record<string, string> = {
      metaverse: 'MGN',
      quantum: 'QGN',
      zk: 'ZKN',
      ai: 'SAN',
    };

    const requiredNodeType = nodeTypeMap[request.taskType] || 'MGN';

    // Step 3: Find nodes with required type
    const sourceNode = sourceNodes.find((n) => n.nodeType === requiredNodeType);
    const targetNode = targetNodes.find((n) => n.nodeType === requiredNodeType);

    if (!sourceNode || !targetNode) {
      throw new Error(`No ${requiredNodeType} nodes available`);
    }

    // Step 4: Calculate route path (6G network)
    const path = [sourceNode.nodeId, targetNode.nodeId];

    // Step 5: Estimate latency (6G ultra-low latency: <1ms)
    const estimatedLatency = 0.5; // 0.5ms for 6G

    // Step 6: Check quantum-safe tunneling
    const quantumSafe =
      sourceNode.quantumSafeTunnelingEnabled &&
      targetNode.quantumSafeTunnelingEnabled;

    // Step 7: Create route record
    const routeId = `GPU-ROUTE-${uuidv4()}`;

    await prisma.gpuEdgeNetwork.create({
      data: {
        routeId,
        sourceRegionId: request.sourceRegionId,
        targetRegionId: request.targetRegionId,
        sourceNodeId: sourceNode.nodeId,
        targetNodeId: targetNode.nodeId,
        path: path as any,
        estimatedLatency,
        quantumSafe,
        latencyRequirement,
        status: 'active',
      },
    });

    logger.info('GPU Edge: Route calculated', {
      routeId,
      estimatedLatency,
    });

    return {
      routeId,
      path,
      estimatedLatency,
      quantumSafe,
    };
  }

  /**
   * Get route by ID
   */
  async getRoute(routeId: string) {
    return await prisma.gpuEdgeNetwork.findUnique({
      where: { routeId },
    });
  }

  /**
   * Get routes for region pair
   */
  async getRoutesForRegionPair(
    sourceRegionId: string,
    targetRegionId: string
  ) {
    return await prisma.gpuEdgeNetwork.findMany({
      where: {
        sourceRegionId,
        targetRegionId,
        status: 'active',
      },
      orderBy: { estimatedLatency: 'asc' },
    });
  }
}

export const gpuEdgeRoutingService = new GpuEdgeRoutingService();

