// WAPL Pattern Library Service

import prisma from '@/shared/database/prisma';
import { WAPLPattern } from './types';
import { circularFXPattern } from './patterns/circular-fx.pattern';
import { cbdcLayeringPattern } from './patterns/cbdc-layering.pattern';
import { logger } from '@/infrastructure/monitoring/logger';


export class PatternLibraryService {
  /**
   * Initialize default patterns
   */
  async initializeDefaultPatterns(): Promise<void> {
    const defaultPatterns = [
      circularFXPattern,
      cbdcLayeringPattern,
    ];

    for (const pattern of defaultPatterns) {
      await prisma.wAPLPattern.upsert({
        where: { patternCode: pattern.patternCode },
        create: {
          id: pattern.id,
          patternCode: pattern.patternCode,
          name: pattern.name,
          description: pattern.description,
          patternDefinition: pattern.patternDefinition,
          severity: pattern.severity,
          status: pattern.status,
        },
        update: {
          name: pattern.name,
          description: pattern.description,
          patternDefinition: pattern.patternDefinition,
          severity: pattern.severity,
          status: pattern.status,
        },
      });
    }

    logger.info(`Initialized ${defaultPatterns.length} default WAPL patterns`);
  }

  /**
   * Get all active patterns
   */
  async getActivePatterns(): Promise<WAPLPattern[]> {
    const patterns = await prisma.wAPLPattern.findMany({
      where: { status: 'ACTIVE' },
      orderBy: { patternCode: 'asc' },
    });

    return patterns.map((p) => this.mapToWAPLPattern(p));
  }

  /**
   * Get pattern by code
   */
  async getPattern(patternCode: string): Promise<WAPLPattern | null> {
    const pattern = await prisma.wAPLPattern.findUnique({
      where: { patternCode },
    });

    if (!pattern) {
      return null;
    }

    return this.mapToWAPLPattern(pattern);
  }

  /**
   * Create or update pattern
   */
  async upsertPattern(pattern: Partial<WAPLPattern>): Promise<WAPLPattern> {
    const upserted = await prisma.wAPLPattern.upsert({
      where: { patternCode: pattern.patternCode! },
      create: {
        id: pattern.id || `WAPL-${pattern.patternCode}`,
        patternCode: pattern.patternCode!,
        name: pattern.name!,
        description: pattern.description!,
        patternDefinition: pattern.patternDefinition!,
        severity: pattern.severity || 'MEDIUM',
        status: pattern.status || 'DRAFT',
      },
      update: {
        name: pattern.name,
        description: pattern.description,
        patternDefinition: pattern.patternDefinition,
        severity: pattern.severity,
        status: pattern.status,
      },
    });

    logger.info(`Upserted WAPL pattern: ${upserted.patternCode}`);

    return this.mapToWAPLPattern(upserted);
  }

  private mapToWAPLPattern(pattern: any): WAPLPattern {
    return {
      id: pattern.id,
      patternCode: pattern.patternCode,
      name: pattern.name,
      description: pattern.description,
      patternDefinition: pattern.patternDefinition,
      severity: pattern.severity,
      status: pattern.status,
    };
  }
}

export const patternLibraryService = new PatternLibraryService();

