// UDFO Process Ontology Service - Domain 3: Processes

import prisma from '@/shared/database/prisma';
import { ProcessType, UDFOProcess } from './types';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';


export class ProcessOntologyService {
  /**
   * Get process definition by type
   */
  async getProcessByType(processType: ProcessType): Promise<UDFOProcess | null> {
    const process = await prisma.uDFOProcess.findFirst({
      where: { processType },
    });

    if (!process) {
      return null;
    }

    return this.mapToUDFOProcess(process);
  }

  /**
   * Get process definition by code
   */
  async getProcessByCode(code: string): Promise<UDFOProcess | null> {
    const process = await prisma.uDFOProcess.findFirst({
      where: { code },
    });

    if (!process) {
      return null;
    }

    return this.mapToUDFOProcess(process);
  }

  /**
   * Create or update process definition
   */
  async upsertProcess(process: Partial<UDFOProcess>): Promise<UDFOProcess> {
    const processId = process.id || `UDFO-PROCESS-${uuidv4()}`;

    const upserted = await prisma.uDFOProcess.upsert({
      where: { id: processId },
      create: {
        id: processId,
        processType: process.processType!,
        code: process.code!,
        name: process.name!,
        definition: process.definition!,
        inputs: process.inputs || [],
        outputs: process.outputs || [],
        triggers: process.triggers || [],
        properties: process.properties || {},
        metadata: process.metadata || {},
      },
      update: {
        processType: process.processType,
        code: process.code,
        name: process.name,
        definition: process.definition,
        inputs: process.inputs,
        outputs: process.outputs,
        triggers: process.triggers,
        properties: process.properties,
        metadata: process.metadata,
      },
    });

    logger.info(`Upserted UDFO process: ${processId}`, { processType: process.processType });

    return this.mapToUDFOProcess(upserted);
  }

  /**
   * Initialize default process definitions
   */
  async initializeDefaultProcesses(): Promise<void> {
    const defaultProcesses: Partial<UDFOProcess>[] = [
      {
        processType: ProcessType.SETTLEMENT,
        code: 'SETTLEMENT',
        name: 'Settlement',
        definition: 'Dual-ledger posting resulting in finality',
        inputs: ['ASSET', 'ENTITY'],
        outputs: ['ASSET', 'ENTITY'],
        triggers: ['PACS.008', 'FXMT.004', 'CBDC_TX'],
        properties: {
          finality: 'irreversible',
          timing: 'real_time',
        },
      },
      {
        processType: ProcessType.ISSUANCE,
        code: 'ISSUANCE',
        name: 'Issuance',
        definition: 'Creation of new asset units by authorized issuer',
        inputs: ['ENTITY'],
        outputs: ['ASSET'],
        triggers: ['ISSUANCE_REQUEST', 'CBDC_MINT'],
        properties: {
          authority: 'issuer',
          backing: 'required',
        },
      },
      {
        processType: ProcessType.CONVERSION,
        code: 'CONVERSION',
        name: 'Conversion',
        definition: 'Exchange of one asset type for another',
        inputs: ['ASSET'],
        outputs: ['ASSET'],
        triggers: ['FX_TRADE', 'CBDC_CONVERSION'],
        properties: {
          rate: 'market_or_fixed',
          finality: 'atomic',
        },
      },
      {
        processType: ProcessType.REDEMPTION,
        code: 'REDEMPTION',
        name: 'Redemption',
        definition: 'Return of asset to issuer for underlying value',
        inputs: ['ASSET'],
        outputs: ['ASSET', 'ENTITY'],
        triggers: ['REDEMPTION_REQUEST', 'CBDC_BURN'],
        properties: {
          authority: 'issuer',
          backing: 'verified',
        },
      },
      {
        processType: ProcessType.COLLATERALIZATION,
        code: 'COLLATERALIZATION',
        name: 'Collateralization',
        definition: 'Use of asset as collateral for obligation',
        inputs: ['ASSET', 'ENTITY'],
        outputs: ['ASSET', 'ENTITY'],
        triggers: ['COLLATERAL_PLEDGE', 'MARGIN_CALL'],
        properties: {
          haircut: 'applied',
          valuation: 'mark_to_market',
        },
      },
    ];

    for (const process of defaultProcesses) {
      await this.upsertProcess(process);
    }

    logger.info('Initialized default UDFO process definitions');
  }

  /**
   * Get all processes
   */
  async getAllProcesses(): Promise<UDFOProcess[]> {
    const processes = await prisma.uDFOProcess.findMany({
      orderBy: { processType: 'asc' },
    });

    return processes.map((p) => this.mapToUDFOProcess(p));
  }

  private mapToUDFOProcess(process: any): UDFOProcess {
    return {
      id: process.id,
      processType: process.processType as ProcessType,
      code: process.code,
      name: process.name,
      definition: process.definition,
      inputs: process.inputs as string[],
      outputs: process.outputs as string[],
      triggers: process.triggers as string[],
      properties: process.properties as Record<string, unknown>,
      metadata: process.metadata as Record<string, unknown> | undefined,
    };
  }
}

export const processOntologyService = new ProcessOntologyService();

