// ISP Issuance Service
// iSSU and iCBDC issuance

import prisma from '@/shared/database/prisma';
import { Decimal } from '@prisma/client/runtime/library';
import { v4 as uuidv4 } from 'uuid';


export interface IssueISSURequest {
  nodeId: string;
  amount: string;
  gravityAdjustment?: string;
  radiationEnvelope?: string;
}

export interface IssueICBDCRequest {
  nodeId: string;
  currencyCode: string;
  amount: string;
  issuanceType: string; // mars_issuance, lunar_issuance
  sovereignAutonomy?: boolean;
  dualLedgerFinality?: boolean;
}

export interface IssuanceResult {
  issuId?: string;
  icbdcId?: string;
  status: string;
}

export class IspIssuanceService {
  /**
   * Issue Interplanetary SSU (iSSU)
   */
  async issueISSU(request: IssueISSURequest): Promise<IssuanceResult> {
    const node = await prisma.interplanetaryNode.findUnique({
      where: { nodeId: request.nodeId },
    });

    if (!node) {
      throw new Error(`Node not found: ${request.nodeId}`);
    }

    const issuId = `ISP-iSSU-${uuidv4()}`;

    // Calculate gravity adjustment if not provided
    let gravityAdjustment = new Decimal(0);
    if (request.gravityAdjustment) {
      gravityAdjustment = new Decimal(request.gravityAdjustment);
    } else {
      gravityAdjustment = this.calculateGravityAdjustment(node.planetaryLocation);
    }

    // Generate radiation-hardened cryptographic envelope if not provided
    const radiationEnvelope = request.radiationEnvelope || this.generateRadiationEnvelope();

    const issu = await prisma.interplanetarySSU.create({
      data: {
        issuId,
        nodeId: request.nodeId,
        amount: new Decimal(request.amount),
        gravityAdjustment,
        radiationEnvelope,
        status: 'active',
      },
    });

    return {
      issuId: issu.issuId,
      status: issu.status,
    };
  }

  /**
   * Issue Interplanetary CBDC (iCBDC)
   */
  async issueICBDC(request: IssueICBDCRequest): Promise<IssuanceResult> {
    const node = await prisma.interplanetaryNode.findUnique({
      where: { nodeId: request.nodeId },
    });

    if (!node) {
      throw new Error(`Node not found: ${request.nodeId}`);
    }

    const icbdcId = `ISP-iCBDC-${uuidv4()}`;

    const icbdc = await prisma.interplanetaryCBDC.create({
      data: {
        icbdcId,
        nodeId: request.nodeId,
        currencyCode: request.currencyCode,
        amount: new Decimal(request.amount),
        issuanceType: request.issuanceType,
        sovereignAutonomy: request.sovereignAutonomy ?? true,
        dualLedgerFinality: request.dualLedgerFinality ?? false,
        status: 'active',
      },
    });

    return {
      icbdcId: icbdc.icbdcId,
      status: icbdc.status,
    };
  }

  /**
   * Calculate gravity adjustment based on planetary location
   */
  private calculateGravityAdjustment(planetaryLocation: string): Decimal {
    // Gravity adjustments (simplified)
    const adjustments: Record<string, number> = {
      earth: 1.0,
      lunar: 0.165, // Moon gravity
      martian: 0.376, // Mars gravity
    };

    return new Decimal(adjustments[planetaryLocation.toLowerCase()] || 1.0);
  }

  /**
   * Generate radiation-hardened cryptographic envelope
   */
  private generateRadiationEnvelope(): string {
    // In production, this would use actual radiation-hardened cryptography
    // For now, return a placeholder
    return `RAD-ENV-${uuidv4()}`;
  }

  /**
   * Get iSSU
   */
  async getISSU(issuId: string) {
    return await prisma.interplanetarySSU.findUnique({
      where: { issuId },
      include: {
        node: true,
      },
    });
  }

  /**
   * Get iCBDC
   */
  async getICBDC(icbdcId: string) {
    return await prisma.interplanetaryCBDC.findUnique({
      where: { icbdcId },
      include: {
        node: true,
      },
    });
  }

  /**
   * List iSSU for node
   */
  async listISSU(nodeId: string) {
    return await prisma.interplanetarySSU.findMany({
      where: { nodeId },
      orderBy: { issuedAt: 'desc' },
    });
  }

  /**
   * List iCBDC for node
   */
  async listICBDC(nodeId: string) {
    return await prisma.interplanetaryCBDC.findMany({
      where: { nodeId },
      orderBy: { issuedAt: 'desc' },
    });
  }
}

export const ispIssuanceService = new IspIssuanceService();

