// GPU Edge Integration Service
// Integration with GPU edge nodes for metaverse rendering and compute
// Supplement B: MetaverseDubai Integration Framework

import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';
import { gpuEdgeRoutingService } from '@/infrastructure/compute/gpu-edge/gpu-edge-routing.service';


export interface GpuEdgeIntegrationRequest {
  metaverseNodeId: string;
  taskType: 'metaverse' | 'quantum' | 'zk' | 'ai';
  regionId?: string;
  latencyRequirement?: number; // milliseconds
  gpuRequirement?: number; // GPU units
}

export interface GpuEdgeIntegrationResult {
  computeNodeId: string;
  nodeType: string;
  regionId: string;
  latency: number;
  status: string;
}

export class GpuEdgeIntegrationService {
  /**
   * Allocate GPU edge node for metaverse operations
   */
  async allocateGpuEdgeNode(
    request: GpuEdgeIntegrationRequest
  ): Promise<GpuEdgeIntegrationResult> {
    logger.info('GPU Edge: Allocating GPU edge node', { request });

    // Step 1: Find available compute node
    const computeNode = await this.findAvailableComputeNode(request);

    if (!computeNode) {
      throw new Error('No available GPU edge node found');
    }

    // Step 2: Route task to GPU edge node
    const routingResult = await gpuEdgeRoutingService.routeTask({
      taskType: request.taskType,
      regionId: computeNode.regionId,
      priority: 'high',
      metadata: {
        metaverseNodeId: request.metaverseNodeId,
      },
    });

    logger.info('GPU Edge: GPU edge node allocated', {
      computeNodeId: computeNode.nodeId,
      routingResult,
    });

    return {
      computeNodeId: computeNode.nodeId,
      nodeType: computeNode.nodeType,
      regionId: computeNode.regionId,
      latency: computeNode.latency,
      status: 'allocated',
    };
  }

  /**
   * Find available compute node
   */
  private async findAvailableComputeNode(
    request: GpuEdgeIntegrationRequest
  ) {
    const where: any = {
      status: 'active',
    };

    // Filter by node type based on task type
    if (request.taskType === 'metaverse') {
      where.nodeType = 'MGN'; // Metaverse GPU Node
    } else if (request.taskType === 'zk') {
      where.nodeType = 'ZKN'; // Zero-Knowledge Node
    } else if (request.taskType === 'quantum') {
      where.nodeType = 'QGN'; // Quantum Gateway Node
    } else if (request.taskType === 'ai') {
      where.nodeType = 'SAN'; // Sovereign AI Node
    }

    // Filter by region if specified
    if (request.regionId) {
      where.regionId = request.regionId;
    }

    // Filter by latency requirement
    if (request.latencyRequirement) {
      where.latency = { lte: request.latencyRequirement };
    }

    // Filter by GPU capacity
    if (request.gpuRequirement) {
      where.gpuCapacity = { gte: request.gpuRequirement };
    }

    // Find available node
    const computeNode = await prisma.metaverse_compute_nodes.findFirst({
      where,
      orderBy: [
        { latency: 'asc' }, // Prefer lower latency
        { gpuCapacity: 'desc' }, // Prefer higher capacity
      ],
    });

    return computeNode;
  }

  /**
   * Get compute node by ID
   */
  async getComputeNode(nodeId: string) {
    return await prisma.metaverse_compute_nodes.findUnique({
      where: { nodeId },
      include: {
        node: true,
      },
    });
  }

  /**
   * Get compute nodes for metaverse node
   */
  async getComputeNodesForMetaverse(metaverseNodeId: string) {
    return await prisma.metaverse_compute_nodes.findMany({
      where: { metaverseNodeId, status: 'active' },
      orderBy: { latency: 'asc' },
    });
  }
}

export const gpuEdgeIntegrationService = new GpuEdgeIntegrationService();

