// SDIP Verification Service

import prisma from '@/shared/database/prisma';
import { SDIPVerificationResult, SDIPPassport, TrustLevel } from './types';
import { quantumCryptoService } from '@/infrastructure/quantum/quantum-crypto.service';
import { logger } from '@/infrastructure/monitoring/logger';


export class SDIPVerificationService {
  /**
   * Verify SDIP passport
   */
  async verifyPassport(passportId: string): Promise<SDIPVerificationResult> {
    const passport = await prisma.sovereign_digital_identity_passports.findUnique({
      where: { passportId },
    });

    if (!passport) {
      return {
        valid: false,
        passport: null,
        trustLevel: 'TL0' as TrustLevel,
        errors: [`Passport not found: ${passportId}`],
        warnings: [],
      };
    }

    const errors: string[] = [];
    const warnings: string[] = [];

    // Check expiry
    if (passport.expiry < new Date()) {
      errors.push(`Passport expired on ${passport.expiry.toISOString()}`);
    }

    // Check revocation status
    if (passport.revocationStatus === 'REVOKED') {
      errors.push(`Passport has been revoked`);
    }

    // Verify HSM signature (root cert)
    const rootCertValid = await this.verifyHSMSignature(passport.passportId, passport.rootCert);
    if (!rootCertValid) {
      errors.push(`Invalid root certificate signature`);
    }

    // Verify PQ signature
    const pqSignatureValid = await this.verifyPQSignature(passport.passportId, passport.pqSignature);
    if (!pqSignatureValid) {
      errors.push(`Invalid PQ signature`);
    }

    // Verify sovereign issuer
    const sovereignBank = await prisma.sovereign_banks.findUnique({
      where: { sovereignCode: passport.sovereignIssuer },
    });

    if (!sovereignBank || sovereignBank.status !== 'active') {
      errors.push(`Sovereign issuer is not active: ${passport.sovereignIssuer}`);
    }

    // Check trust level validity
    if (passport.trustLevel === 'TL0') {
      warnings.push(`Passport has minimal trust level (TL0)`);
    }

    const valid = errors.length === 0;

    logger.info(`SDIP verification completed`, {
      passportId,
      valid,
      errors: errors.length,
    });

    return {
      valid,
      passport: this.mapToSDIPPassport(passport),
      trustLevel: passport.trustLevel as TrustLevel,
      errors,
      warnings,
    };
  }

  /**
   * Verify HSM signature
   */
  private async verifyHSMSignature(passportId: string, signature: string): Promise<boolean> {
    // In production, this would verify against HSM
    // For now, basic validation
    return signature.startsWith('HSM_SIG:');
  }

  /**
   * Verify PQ signature
   */
  private async verifyPQSignature(passportId: string, signature: string): Promise<boolean> {
    // In production, this would verify Dilithium signature
    // For now, basic validation
    return signature.startsWith('DILITHIUM_SIG:');
  }

  /**
   * Get passport by ID
   */
  async getPassport(passportId: string): Promise<SDIPPassport | null> {
    const passport = await prisma.sovereign_digital_identity_passports.findUnique({
      where: { passportId },
    });

    if (!passport) {
      return null;
    }

    return this.mapToSDIPPassport(passport);
  }

  /**
   * Get passports by entity ID
   */
  async getPassportsByEntity(entityId: string): Promise<SDIPPassport[]> {
    const passports = await prisma.sovereign_digital_identity_passports.findMany({
      where: { entityId },
      orderBy: { createdAt: 'desc' },
    });

    return passports.map((p) => this.mapToSDIPPassport(p));
  }

  /**
   * Calculate trust score based on passport
   */
  async calculateTrustScore(passportId: string): Promise<number> {
    const verification = await this.verifyPassport(passportId);

    if (!verification.valid) {
      return 0;
    }

    // Base trust score from trust level
    const trustLevelScores: Record<TrustLevel, number> = {
      TL0: 0,
      TL1: 25,
      TL2: 50,
      TL3: 75,
      TL4: 100,
    };

    let score = trustLevelScores[verification.trustLevel] || 0;

    // Deduct for warnings
    score -= verification.warnings.length * 5;

    // Deduct for expiry proximity (within 30 days)
    if (verification.passport) {
      const daysUntilExpiry = Math.floor(
        (verification.passport.expiry.getTime() - Date.now()) / (1000 * 60 * 60 * 24)
      );
      if (daysUntilExpiry < 30) {
        score -= 10;
      }
    }

    return Math.max(0, Math.min(100, score));
  }

  private mapToSDIPPassport(passport: any): SDIPPassport {
    return {
      id: passport.id,
      passportId: passport.passportId,
      entityType: passport.entityType as any,
      entityId: passport.entityId,
      sovereignIssuer: passport.sovereignIssuer,
      rootCert: passport.rootCert,
      pqSignature: passport.pqSignature,
      trustLevel: passport.trustLevel as TrustLevel,
      expiry: passport.expiry,
      revocationStatus: passport.revocationStatus as any,
      attributes: passport.attributes as Record<string, unknown>,
      createdAt: passport.createdAt,
      updatedAt: passport.updatedAt,
    };
  }
}

export const sdipVerificationService = new SDIPVerificationService();

