// Credentialing Service
// HSM-secured credentials, identity badges

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


export interface CredentialData {
  employeeName: string;
  email: string;
  roleId: string;
  securityClearance: string;
}

export class CredentialingService {
  /**
   * Issue credential
   */
  async issueCredential(data: CredentialData, expiresInDays: number = 365) {
    const role = await prisma.dbisRole.findUnique({
      where: { roleId: data.roleId },
    });

    if (!role) {
      throw new Error(`Role not found: ${data.roleId}`);
    }

    // Generate cryptographic badge ID
    const cryptographicBadgeId = `badge_${uuidv4()}`;

    // Generate HSM credential ID (would be stored in HSM in production)
    const hsmCredentialId = `hsm_${uuidv4()}`;

    const expiresAt = new Date();
    expiresAt.setDate(expiresAt.getDate() + expiresInDays);

    const credential = await prisma.employeeCredential.create({
      data: {
        id: uuidv4(),
        employeeId: uuidv4(),
        roleId: data.roleId,
        employeeName: data.employeeName,
        email: data.email,
        securityClearance: data.securityClearance,
        cryptographicBadgeId,
        hsmCredentialId,
        status: 'active',
        issuedAt: new Date(),
        expiresAt,
      },
    });

    return credential;
  }

  /**
   * Get credential by employee ID
   */
  async getCredential(employeeId: string) {
    return await prisma.employeeCredential.findUnique({
      where: { employeeId },
      include: { role: true },
    });
  }

  /**
   * Get credential by cryptographic badge ID
   */
  async getCredentialByBadge(badgeId: string) {
    return await prisma.employeeCredential.findFirst({
      where: { cryptographicBadgeId: badgeId },
      include: { role: true },
    });
  }

  /**
   * Verify credential
   */
  async verifyCredential(employeeId: string): Promise<{
    valid: boolean;
    reason?: string;
  }> {
    const credential = await this.getCredential(employeeId);

    if (!credential) {
      return { valid: false, reason: 'Credential not found' };
    }

    if (credential.status !== 'active') {
      return { valid: false, reason: `Credential status: ${credential.status}` };
    }

    if (credential.expiresAt && credential.expiresAt < new Date()) {
      return { valid: false, reason: 'Credential expired' };
    }

    return { valid: true };
  }

  /**
   * Revoke credential
   */
  async revokeCredential(employeeId: string, reason?: string) {
    return await prisma.employeeCredential.update({
      where: { employeeId },
      data: {
        status: 'revoked',
        revokedAt: new Date(),
      },
    });
  }

  /**
   * Renew credential
   */
  async renewCredential(employeeId: string, expiresInDays: number = 365) {
    const credential = await this.getCredential(employeeId);

    if (!credential) {
      throw new Error(`Credential not found: ${employeeId}`);
    }

    const expiresAt = new Date();
    expiresAt.setDate(expiresAt.getDate() + expiresInDays);

    return await prisma.employeeCredential.update({
      where: { employeeId },
      data: {
        expiresAt,
        status: 'active',
      },
    });
  }

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

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

  /**
   * Get credentials by security clearance
   */
  async getCredentialsByClearance(securityClearance: string) {
    return await prisma.employeeCredential.findMany({
      where: {
        securityClearance,
        status: 'active',
      },
      include: { role: true },
    });
  }

  /**
   * Update security clearance
   */
  async updateSecurityClearance(employeeId: string, newClearance: string) {
    return await prisma.employeeCredential.update({
      where: { employeeId },
      data: {
        securityClearance: newClearance,
      },
    });
  }
}

export const credentialingService = new CredentialingService();

