// CDT Service
// CDT tokenization from physical reserves
// Reserve certificate verification
// CDT structure: {commodity_type, weight, reserve_certificate, custodian, sovereign_issuer, timestamp, signature}
// CDT minting and burning

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';
import { reserveCertificateService } from './reserve-certificate.service';
import { createHash } from 'crypto';


export interface CdtMintRequest {
  commodityType: string;
  weight: string;
  unit: string;
  reserveCertificateId: string;
  custodianId: string;
  sovereignIssuerId: string;
}

export interface CdtStructure {
  commodityType: string;
  weight: Decimal;
  reserveCertificate: string;
  custodian: string;
  sovereignIssuer: string;
  timestamp: Date;
  signature: string;
}

export class CdtService {
  /**
   * Mint CDT from reserves
   */
  async mintCdt(request: CdtMintRequest): Promise<string> {
    // Verify reserve certificate
    const certificate = await reserveCertificateService.verifyCertificate(
      request.reserveCertificateId
    );

    if (!certificate || certificate.verificationStatus !== 'verified') {
      throw new Error('Reserve certificate not verified');
    }

    // Verify custodian
    const custodian = await prisma.commodity_custodians.findUnique({
      where: { custodianId: request.custodianId },
    });

    if (!custodian || custodian.approvalStatus !== 'approved') {
      throw new Error('Custodian not approved');
    }

    // Verify certificate belongs to custodian
    if (certificate.custodianId !== request.custodianId) {
      throw new Error('Reserve certificate does not belong to custodian');
    }

    // Generate CDT ID
    const cdtId = `CDT-${request.commodityType}-${uuidv4()}`;

    // Create CDT structure
    const cdtStructure = await this.createCdtStructure(request, cdtId);

    // Create CDT
    const cdt = await prisma.commodity_digital_tokens.create({
      data: {
        id: uuidv4(),
        cdtId,
        commodityType: request.commodityType.toUpperCase(),
        weight: new Decimal(request.weight),
        unit: request.unit,
        reserveCertificateId: request.reserveCertificateId,
        custodianId: request.custodianId,
        sovereignIssuerId: request.sovereignIssuerId,
        timestamp: new Date(),
        signature: cdtStructure.        signature,
        status: 'active',
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    });

    return cdt.cdtId;
  }

  /**
   * Create CDT structure
   */
  private async createCdtStructure(
    request: CdtMintRequest,
    cdtId: string
  ): Promise<CdtStructure> {
    // Get certificate hash
    const certificate = await prisma.commodity_reserve_certificates.findUnique({
      where: { certificateId: request.reserveCertificateId },
    });

    if (!certificate) {
      throw new Error('Reserve certificate not found');
    }

    // Create CDT structure
    const cdtData = {
      commodity_type: request.commodityType.toUpperCase(),
      weight: request.weight,
      reserve_certificate: certificate.certificateHash,
      custodian: request.custodianId,
      sovereign_issuer: request.sovereignIssuerId,
      timestamp: new Date().toISOString(),
    };

    // Generate signature (in production, this would be HSM-signed)
    const signature = this.generateSignature(cdtData);

    return {
      commodityType: request.commodityType.toUpperCase(),
      weight: new Decimal(request.weight),
      reserveCertificate: certificate.certificateHash,
      custodian: request.custodianId,
      sovereignIssuer: request.sovereignIssuerId,
      timestamp: new Date(),
      signature,
    };
  }

  /**
   * Generate CDT signature
   */
  private generateSignature(cdtData: Record<string, unknown>): string {
    const dataString = JSON.stringify(cdtData);
    return createHash('sha256').update(dataString).digest('hex');
  }

  /**
   * Burn CDT
   */
  async burnCdt(cdtId: string, reason?: string): Promise<boolean> {
    const cdt = await prisma.commodity_digital_tokens.findUnique({
      where: { cdtId },
    });

    if (!cdt || cdt.status !== 'active') {
      throw new Error('CDT not found or not active');
    }

    // Create burn transaction
    await prisma.cdt_transactions.create({
      data: {
        id: uuidv4(),
        transactionId: `CDT-TX-BURN-${uuidv4()}`,
        cdtId,
        transactionType: 'burn',
        amount: cdt.weight,
        status: 'completed',
        completedAt: new Date(),
        createdAt: new Date(),
        updatedAt: new Date(),
      },
    });

    // Update CDT status
    await prisma.commodity_digital_tokens.update({
      where: { cdtId },
      data: {
        status: 'burned',
      },
    });

    return true;
  }

  /**
   * Get CDT by ID
   */
  async getCdt(cdtId: string) {
    return await prisma.commodity_digital_tokens.findUnique({
      where: { cdtId },
      include: {
        commodity_reserve_certificates: true,
        commodity_custodians: true,
        cdt_transactions: {
          orderBy: { createdAt: 'desc' },
          take: 10,
        },
      },
    });
  }

  /**
   * List CDTs by commodity type
   */
  async listCdts(
    commodityType?: string,
    status?: string,
    limit: number = 100
  ) {
    return await prisma.commodity_digital_tokens.findMany({
      where: {
        ...(commodityType && { commodityType }),
        ...(status && { status }),
      },
      orderBy: { createdAt: 'desc' },
      take: limit,
    });
  }

  /**
   * Verify CDT structure
   */
  async verifyCdtStructure(cdtId: string): Promise<boolean> {
    const cdt = await prisma.commodity_digital_tokens.findUnique({
      where: { cdtId },
      include: {
        commodity_reserve_certificates: true,
      },
    });

    if (!cdt) {
      return false;
    }

    // Reconstruct CDT structure
    const cdtData = {
      commodity_type: cdt.commodityType,
      weight: cdt.weight.toString(),
      reserve_certificate: cdt.commodity_reserve_certificates.certificateHash,
      custodian: cdt.custodianId,
      sovereign_issuer: cdt.sovereignIssuerId,
      timestamp: cdt.timestamp.toISOString(),
    };

    // Verify signature
    const dataString = JSON.stringify(cdtData);
    const expectedSignature = createHash('sha256').update(dataString).digest('hex');
    return cdt.signature === expectedSignature;
  }
}

export const cdtService = new CdtService();

