// GRU Regulatory Classification Service
// Implements SR-1, SR-2, SR-3, M0, M1 regulatory classifications from GRU Institutional Whitepaper

import prisma from '@/shared/database/prisma';
import { v4 as uuidv4 } from 'uuid';
import { logger } from '@/infrastructure/monitoring/logger';


export type RegulatoryClass = 'SR-1' | 'SR-2' | 'SR-3' | 'M0' | 'M1';
export type EntityType = 'sovereign_bank' | 'supranational_council' | 'regional_union' | 'institution' | 'commercial';
export type EligibilityStatus = 'pending' | 'eligible' | 'ineligible' | 'suspended';

export interface RegulatoryClassificationRequest {
  entityId: string;
  entityType: EntityType;
  regulatoryClass: RegulatoryClass;
  reserveAdequacy?: boolean;
  legalRecognition?: boolean;
  ilieVerified?: boolean;
}

export interface RegulatoryClassificationResult {
  classificationId: string;
  entityId: string;
  entityType: string;
  regulatoryClass: string;
  accessLevel: string;
  eligibilityStatus: string;
  status: string;
}

export class GruRegulatoryClassificationService {
  /**
   * Regulatory class definitions from GRU Institutional Whitepaper
   */
  private readonly REGULATORY_CLASSES: Record<RegulatoryClass, {
    accessLevel: string;
    description: string;
    allowedEntityTypes: EntityType[];
  }> = {
    'SR-1': {
      accessLevel: 'global_reserve',
      description: 'Supranational councils, DBIS - Global reserve tier',
      allowedEntityTypes: ['supranational_council'],
    },
    'SR-2': {
      accessLevel: 'stabilization',
      description: 'Regional unions - Stabilization tier',
      allowedEntityTypes: ['regional_union'],
    },
    'SR-3': {
      accessLevel: 'commodity_reserves',
      description: 'Nations/SCBs - Commodity & crisis reserves',
      allowedEntityTypes: ['sovereign_bank'],
    },
    'M0': {
      accessLevel: 'operational_liquidity',
      description: 'Institutions - Operational liquidity',
      allowedEntityTypes: ['institution'],
    },
    'M1': {
      accessLevel: 'market_instruments',
      description: 'Commercial - Market instruments',
      allowedEntityTypes: ['commercial'],
    },
  };

  /**
   * Classify entity for GRU access
   */
  async classifyEntity(
    request: RegulatoryClassificationRequest
  ): Promise<RegulatoryClassificationResult> {
    logger.info('GRU Regulatory Classification: Classifying entity', { request });

    // Validate entity type matches regulatory class
    const classDef = this.REGULATORY_CLASSES[request.regulatoryClass];
    if (!classDef.allowedEntityTypes.includes(request.entityType)) {
      throw new Error(
        `Entity type ${request.entityType} is not allowed for regulatory class ${request.regulatoryClass}`
      );
    }

    // Check if classification already exists
    const existing = await prisma.gru_regulatory_classifications.findFirst({
      where: {
        entityId: request.entityId,
        regulatoryClass: request.regulatoryClass,
        status: 'active',
      },
    });

    if (existing) {
      logger.warn('GRU Regulatory Classification: Classification already exists', {
        classificationId: existing.classificationId,
      });
      return this.mapToResult(existing);
    }

    // Determine eligibility status
    const eligibilityStatus = this.determineEligibilityStatus(request);

    // Create or update supranational entity if needed
    if (request.entityType === 'supranational_council' || request.entityType === 'regional_union') {
      await this.ensureSupranationalEntity(request.entityId, request.entityType);
    }

    // Create classification
    const classification = await prisma.gru_regulatory_classifications.create({
      data: {
        classificationId: `GRU-REG-${uuidv4()}`,
        entityId: request.entityId,
        entityType: request.entityType,
        regulatoryClass: request.regulatoryClass,
        accessLevel: classDef.accessLevel,
        eligibilityStatus,
        reserveAdequacy: request.reserveAdequacy ?? false,
        legalRecognition: request.legalRecognition ?? false,
        ilieVerified: request.ilieVerified ?? false,
        status: 'active',
      },
    });

    logger.info('GRU Regulatory Classification: Entity classified', {
      classificationId: classification.classificationId,
      regulatoryClass: request.regulatoryClass,
    });

    return this.mapToResult(classification);
  }

  /**
   * Get classification by ID
   */
  async getClassification(classificationId: string) {
    return await prisma.gru_regulatory_classifications.findUnique({
      where: { classificationId },
      include: {
        entity: true,
        reviews: true,
      },
    });
  }

  /**
   * Get entities by regulatory class
   */
  async getEntitiesByClass(regulatoryClass: RegulatoryClass) {
    return await prisma.gru_regulatory_classifications.findMany({
      where: {
        regulatoryClass,
        status: 'active',
      },
      include: {
        entity: true,
      },
      orderBy: {
        createdAt: 'desc',
      },
    });
  }

  /**
   * Check eligibility for entity
   */
  async checkEligibility(entityId: string): Promise<{
    eligible: boolean;
    classifications: RegulatoryClassificationResult[];
    eligibilityStatus: EligibilityStatus;
  }> {
    const classifications = await prisma.gru_regulatory_classifications.findMany({
      where: {
        entityId,
        status: 'active',
      },
    });

    const eligibleClassifications = classifications.filter(
      (c) => c.eligibilityStatus === 'eligible'
    );

    return {
      eligible: eligibleClassifications.length > 0,
      classifications: classifications.map((c) => this.mapToResult(c)),
      eligibilityStatus: eligibleClassifications.length > 0 ? 'eligible' : 'pending',
    };
  }

  /**
   * Update eligibility status
   */
  async updateEligibilityStatus(
    classificationId: string,
    eligibilityStatus: EligibilityStatus,
    reviewNotes?: string
  ): Promise<void> {
    const classification = await prisma.gru_regulatory_classifications.findUnique({
      where: { classificationId },
    });

    if (!classification) {
      throw new Error(`Classification not found: ${classificationId}`);
    }

    await prisma.gru_regulatory_classifications.update({
      where: { classificationId },
      data: {
        eligibilityStatus,
        eligibilityReviewDate: new Date(),
      },
    });

    // Create eligibility review record
    await prisma.gru_eligibility_reviews.create({
      data: {
        reviewId: `GRU-REV-${uuidv4()}`,
        classificationId,
        reviewType: 'periodic',
        reviewResult: eligibilityStatus === 'eligible' ? 'approved' : 'rejected',
        reviewNotes,
        reviewedAt: new Date(),
      },
    });

    logger.info('GRU Regulatory Classification: Eligibility status updated', {
      classificationId,
      eligibilityStatus,
    });
  }

  /**
   * Determine eligibility status based on requirements
   */
  private determineEligibilityStatus(
    request: RegulatoryClassificationRequest
  ): EligibilityStatus {
    // For SR-1, SR-2, SR-3: require all checks
    if (['SR-1', 'SR-2', 'SR-3'].includes(request.regulatoryClass)) {
      if (
        request.reserveAdequacy &&
        request.legalRecognition &&
        request.ilieVerified
      ) {
        return 'eligible';
      }
      return 'pending';
    }

    // For M0, M1: require legal recognition and ILIE verification
    if (['M0', 'M1'].includes(request.regulatoryClass)) {
      if (request.legalRecognition && request.ilieVerified) {
        return 'eligible';
      }
      return 'pending';
    }

    return 'pending';
  }

  /**
   * Ensure supranational entity exists
   */
  private async ensureSupranationalEntity(
    entityId: string,
    entityType: EntityType
  ): Promise<void> {
    const existing = await prisma.gru_supranational_entities.findUnique({
      where: { entityId },
    });

    if (!existing) {
      await prisma.gru_supranational_entities.create({
        data: {
          entityId,
          entityName: `Entity ${entityId}`, // Should be provided in request
          entityType: entityType === 'supranational_council' ? 'supranational_council' : 'regional_union',
          status: 'active',
        },
      });
    }
  }

  /**
   * Map database model to result
   */
  private mapToResult(
    classification: any
  ): RegulatoryClassificationResult {
    return {
      classificationId: classification.classificationId,
      entityId: classification.entityId,
      entityType: classification.entityType,
      regulatoryClass: classification.regulatoryClass,
      accessLevel: classification.accessLevel,
      eligibilityStatus: classification.eligibilityStatus,
      status: classification.status,
    };
  }
}

export const gruRegulatoryClassificationService = new GruRegulatoryClassificationService();

