// Quantum Migration Roadmap Service
// Phase tracking, component migration status

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


export interface PhaseData {
  phaseNumber: number;
  phaseName: string;
  description: string;
  targetComponents: string[];
}

export interface MigrationStatus {
  phaseId: string;
  componentType: string;
  componentId: string;
  migrationStatus: string;
  oldKeyId?: string;
  newKeyId?: string;
}

export class MigrationRoadmapService {
  /**
   * Initialize migration phases
   */
  async initializePhases() {
    const phases: PhaseData[] = [
      {
        phaseNumber: 1,
        phaseName: 'Phase I - Hybrid Cryptography Integration',
        description:
          'DBIS implements ECC-521 + PQC dual signatures, SHA-3 + XMSS hash chains, Hybrid TLS (ECDHE + Kyber)',
        targetComponents: ['ledger', 'api', 'cbdc', 'smart_contract', 'identity'],
      },
      {
        phaseNumber: 2,
        phaseName: 'Phase II - Full PQC Transition',
        description:
          'Migration to CRYSTALS-Kyber for key exchange, CRYSTALS-Dilithium for signatures, XMSS or SPHINCS+ for ledger notarization, PQ-HSM modules',
        targetComponents: ['ledger', 'api', 'cbdc', 'smart_contract', 'identity'],
      },
      {
        phaseNumber: 3,
        phaseName: 'Phase III - Quantum-Native Ledger Protocol',
        description:
          'Quantum-resistant state commitments, PQ smart contract signatures, CBDC quantum envelope protocol',
        targetComponents: ['ledger', 'cbdc', 'smart_contract'],
      },
    ];

    for (const phaseData of phases) {
      const existing = await prisma.quantum_migration_phases.findFirst({
        where: { phaseNumber: phaseData.phaseNumber },
      });

      if (!existing) {
        await prisma.quantum_migration_phases.create({
          data: {
            id: uuidv4(),
            phaseNumber: phaseData.phaseNumber,
            phaseName: phaseData.phaseName,
            description: phaseData.description,
            targetComponents: phaseData.targetComponents,
            status: phaseData.phaseNumber === 1 ? 'in_progress' : 'planned',
          },
        });
      }
    }
  }

  /**
   * Get phase by number
   */
  async getPhase(phaseNumber: number) {
    return await prisma.quantum_migration_phases.findFirst({
      where: { phaseNumber },
      include: { migrations: true },
    });
  }

  /**
   * Get all phases
   */
  async getAllPhases() {
    return await prisma.quantum_migration_phases.findMany({
      include: { migrations: true },
      orderBy: { phaseNumber: 'asc' },
    });
  }

  /**
   * Start phase
   */
  async startPhase(phaseNumber: number) {
    const phase = await prisma.quantum_migration_phases.findFirst({
      where: { phaseNumber },
    });

    if (!phase) {
      throw new Error(`Phase ${phaseNumber} not found`);
    }

    return await prisma.quantum_migration_phases.update({
      where: { id: phase.id },
      data: {
        status: 'in_progress',
        startDate: new Date(),
      },
    });
  }

  /**
   * Complete phase
   */
  async completePhase(phaseNumber: number) {
    const phase = await prisma.quantum_migration_phases.findFirst({
      where: { phaseNumber },
      include: { migrations: true },
    });

    if (!phase) {
      throw new Error(`Phase ${phaseNumber} not found`);
    }

    // Check if all migrations are completed
    const incompleteMigrations = phase.migrations.filter(
      (m) => m.migrationStatus !== 'completed'
    );

    if (incompleteMigrations.length > 0) {
      throw new Error(
        `Cannot complete phase: ${incompleteMigrations.length} migrations still incomplete`
      );
    }

    return await prisma.quantum_migration_phases.update({
      where: { id: phase.id },
      data: {
        status: 'completed',
        completionDate: new Date(),
      },
    });
  }

  /**
   * Register component migration
   */
  async registerMigration(data: MigrationStatus) {
    const phase = await prisma.quantum_migration_phases.findUnique({
      where: { id: data.phaseId },
    });

    if (!phase) {
      throw new Error(`Phase not found: ${data.phaseId}`);
    }

    const migration = await prisma.migration_audits.create({
      data: {
        id: uuidv4(),
        phaseId: data.phaseId,
        componentType: data.componentType,
        componentId: data.componentId,
        migrationStatus: data.migrationStatus,
        oldKeyId: data.oldKeyId,
        newKeyId: data.newKeyId,
      },
    });

    return migration;
  }

  /**
   * Update migration status
   */
  async updateMigrationStatus(
    migrationId: string,
    status: string,
    newKeyId?: string
  ) {
    const updateData: {
      migrationStatus: string;
      newKeyId?: string;
      migrationDate?: Date;
    } = {
      migrationStatus: status,
    };

    if (newKeyId) {
      updateData.newKeyId = newKeyId;
    }

    if (status === 'completed') {
      updateData.migrationDate = new Date();
    }

    return await prisma.migration_audits.update({
      where: { id: migrationId },
      data: updateData,
    });
  }

  /**
   * Get migration status for component
   */
  async getComponentMigrationStatus(componentType: string, componentId: string) {
    return await prisma.migration_audits.findMany({
      where: {
        componentType,
        componentId,
      },
      include: {
        phase: true,
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  /**
   * Get overall migration progress
   */
  async getMigrationProgress() {
    const phases = await this.getAllPhases();
    const totalComponents = phases.reduce(
      (sum, phase) => sum + (phase.targetComponents as string[]).length,
      0
    );

    const allMigrations = await prisma.migration_audits.findMany();
    const completedMigrations = allMigrations.filter(
      (m) => m.migrationStatus === 'completed'
    ).length;

    return {
      totalPhases: phases.length,
      completedPhases: phases.filter((p) => p.status === 'completed').length,
      totalComponents,
      completedMigrations,
      progressPercentage: totalComponents > 0 ? (completedMigrations / totalComponents) * 100 : 0,
    };
  }
}

export const migrationRoadmapService = new MigrationRoadmapService();

