// Wallet Attestation Service
import { Prisma } from '@prisma/client';
// Device attestation (12-hour cycle)

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


export interface AttestationRequest {
  walletId: string;
  deviceAttestation: Record<string, unknown>;
}

export interface AttestationResult {
  waoId: string;
  attestationHash: string;
  attestationCycle: number;
  expiresAt: Date;
}

export class WalletAttestationService {
  /**
   * Create wallet attestation object (WAO)
   */
  async createAttestation(
    request: AttestationRequest
  ): Promise<AttestationResult> {
    const wallet = await prisma.quantumWallet.findUnique({
      where: { walletId: request.walletId },
    });

    if (!wallet) {
      throw new Error(`Wallet not found: ${request.walletId}`);
    }

    // Calculate attestation cycle (12-hour cycles since wallet creation)
    const walletCreated = wallet.createdAt;
    const now = new Date();
    const hoursSinceCreation = (now.getTime() - walletCreated.getTime()) / (1000 * 60 * 60);
    const attestationCycle = Math.floor(hoursSinceCreation / 12);

    // Generate attestation hash
    const attestationData = {
      walletId: request.walletId,
      deviceAttestation: request.deviceAttestation,
      attestationCycle,
      timestamp: now.toISOString(),
    };

    const attestationString = JSON.stringify(attestationData);
    const attestationHash = createHash('sha3-256').update(attestationString).digest('hex');

    // Calculate expiry (next 12-hour cycle)
    const expiresAt = new Date(walletCreated);
    expiresAt.setHours(expiresAt.getHours() + (attestationCycle + 1) * 12);

    // Create WAO
    const waoId = `WAO-${uuidv4()}`;
    const wao = await prisma.walletAttestationObject.create({
      data: {
        waoId,
        walletId: request.walletId,
        deviceAttestation: request.deviceAttestation as Prisma.InputJsonValue,
        attestationHash,
        attestationCycle,
        status: 'valid',
        expiresAt,
      },
    });

    // Update wallet with WAO reference
    await prisma.quantumWallet.update({
      where: { walletId: request.walletId },
      data: { waoId: wao.waoId },
    });

    return {
      waoId: wao.waoId,
      attestationHash: wao.attestationHash,
      attestationCycle: wao.attestationCycle,
      expiresAt: wao.expiresAt,
    };
  }

  /**
   * Verify attestation
   */
  async verifyAttestation(waoId: string): Promise<boolean> {
    const wao = await prisma.walletAttestationObject.findUnique({
      where: { waoId },
    });

    if (!wao) {
      return false;
    }

    // Check if expired
    if (new Date() > wao.expiresAt) {
      await prisma.walletAttestationObject.update({
        where: { waoId },
        data: { status: 'expired' },
      });
      return false;
    }

    // Check status
    return wao.status === 'valid';
  }

  /**
   * Revoke attestation
   */
  async revokeAttestation(waoId: string): Promise<void> {
    await prisma.walletAttestationObject.update({
      where: { waoId },
      data: { status: 'revoked' },
    });
  }

  /**
   * Get current attestation for wallet
   */
  async getCurrentAttestation(walletId: string): Promise<any | null> {
    const wao = await prisma.walletAttestationObject.findFirst({
      where: {
        walletId,
        status: 'valid',
      },
      orderBy: { attestedAt: 'desc' },
    });

    return wao;
  }

  /**
   * Check if attestation needs renewal
   */
  async needsRenewal(walletId: string): Promise<boolean> {
    const wao = await this.getCurrentAttestation(walletId);

    if (!wao) {
      return true;
    }

    // Check if expires within 1 hour
    const oneHourFromNow = new Date();
    oneHourFromNow.setHours(oneHourFromNow.getHours() + 1);

    return wao.expiresAt < oneHourFromNow;
  }
}

export const walletAttestationService = new WalletAttestationService();

