// PQC Key Manager Service
// CRYSTALS-Kyber/Dilithium key lifecycle management

import prisma from '@/shared/database/prisma';
import { quantumCryptoService } from './quantum-crypto.service';


export interface KeyLifecycleEvent {
  keyId: string;
  event: 'created' | 'activated' | 'rotated' | 'revoked' | 'expired';
  timestamp: Date;
  metadata?: Record<string, unknown>;
}

export class PQCKeyManagerService {
  /**
   * Create CRYSTALS-Kyber key pair for key exchange
   */
  async createKyberKeyPair(keyPurpose: string) {
    return await quantumCryptoService.generatePQCKeyPair('CRYSTALS-Kyber', keyPurpose);
  }

  /**
   * Create CRYSTALS-Dilithium key pair for signatures
   */
  async createDilithiumKeyPair(keyPurpose: string) {
    return await quantumCryptoService.generatePQCKeyPair('CRYSTALS-Dilithium', keyPurpose);
  }

  /**
   * Get key by ID
   */
  async getKey(keyId: string) {
    return await prisma.cryptographic_keys.findUnique({
      where: { keyId },
    });
  }

  /**
   * Get keys by purpose
   */
  async getKeysByPurpose(keyPurpose: string) {
    return await prisma.cryptographic_keys.findMany({
      where: {
        keyPurpose,
        status: 'active',
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  /**
   * Get keys by type
   */
  async getKeysByType(keyType: string) {
    return await prisma.cryptographic_keys.findMany({
      where: {
        keyType,
        status: 'active',
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  /**
   * Rotate key
   */
  async rotateKey(keyId: string, newKeyPurpose?: string) {
    const oldKey = await prisma.cryptographic_keys.findUnique({
      where: { keyId },
    });

    if (!oldKey) {
      throw new Error(`Key not found: ${keyId}`);
    }

    // Determine algorithm from key type
    let algorithm: 'CRYSTALS-Kyber' | 'CRYSTALS-Dilithium';
    if (oldKey.keyType === 'pqc_kyber') {
      algorithm = 'CRYSTALS-Kyber';
    } else if (oldKey.keyType === 'pqc_dilithium') {
      algorithm = 'CRYSTALS-Dilithium';
    } else {
      throw new Error(`Key type ${oldKey.keyType} is not a PQC key`);
    }

    // Generate new key
    const newKey = await quantumCryptoService.generatePQCKeyPair(
      algorithm,
      newKeyPurpose || oldKey.keyPurpose
    );

    // Mark old key as rotated
    await prisma.cryptographic_keys.update({
      where: { keyId },
      data: {
        status: 'rotated',
        rotatedAt: new Date(),
      },
    });

    return newKey;
  }

  /**
   * Revoke key
   */
  async revokeKey(keyId: string, reason?: string) {
    return await prisma.cryptographic_keys.update({
      where: { keyId },
      data: {
        status: 'revoked',
      },
    });
  }

  /**
   * Check key expiration
   */
  async checkKeyExpiration(keyId: string): Promise<boolean> {
    const key = await prisma.cryptographic_keys.findUnique({
      where: { keyId },
    });

    if (!key || !key.expiresAt) {
      return false;
    }

    return key.expiresAt < new Date();
  }

  /**
   * Get expiring keys
   */
  async getExpiringKeys(daysAhead: number = 30) {
    const thresholdDate = new Date();
    thresholdDate.setDate(thresholdDate.getDate() + daysAhead);

    return await prisma.cryptographic_keys.findMany({
      where: {
        status: 'active',
        expiresAt: {
          lte: thresholdDate,
          gte: new Date(),
        },
      },
      orderBy: { expiresAt: 'asc' },
    });
  }

  /**
   * Update sovereign identity with quantum key
   */
  async updateSovereignIdentityWithQuantumKey(
    sovereignIdentityId: string,
    quantumKeyId: string
  ) {
    const key = await prisma.cryptographic_keys.findUnique({
      where: { keyId: quantumKeyId },
    });

    if (!key) {
      throw new Error(`Quantum key not found: ${quantumKeyId}`);
    }

    if (!key.keyType.startsWith('pqc_') && key.keyType !== 'hybrid') {
      throw new Error(`Key ${quantumKeyId} is not a quantum-safe key`);
    }

    return await prisma.sovereign_identities.update({
      where: { id: sovereignIdentityId },
      data: {
        quantumKeyId,
        isQuantumEnabled: true,
      },
    });
  }

  /**
   * Get quantum-enabled identities
   */
  async getQuantumEnabledIdentities() {
    return await prisma.sovereign_identities.findMany({
      where: {
        isQuantumEnabled: true,
        status: 'active',
      },
      include: {
        sovereign_banks: true,
      },
    });
  }
}

export const pqcKeyManagerService = new PQCKeyManagerService();

