// Qualification Engine Service
import { v4 as uuidv4 } from 'uuid';
// Main orchestrator for IRU qualification process

import { institutionalVerifier } from './institutional-verifier.service';
import { capacityTierAssessor } from './capacity-tier-assessor.service';
import { regulatoryComplianceChecker } from './regulatory-compliance-checker.service';
import { jurisdictionalLawReviewer } from './jurisdictional-law-reviewer.service';
import { technicalCapabilityAssessor } from './technical-capability-assessor.service';
import prisma from '@/shared/database/prisma';
import { DbisError, ErrorCode } from '@/shared/types';

export interface QualificationRequest {
  inquiryId: string;
  preliminaryInfo: any;
}

export interface QualificationResult {
  inquiryId: string;
  qualified: boolean;
  institutionalType: string;
  capacityTier: number;
  riskScore: number;
  qualificationDetails: {
    institutionalVerification: any;
    capacityAssessment: any;
    regulatoryCompliance: any;
    jurisdictionalLaw: any;
    technicalCapability: any;
  };
  recommendations: string[];
  nextSteps: string[];
}

export class QualificationEngine {
  /**
   * Process qualification assessment
   */
  async processQualification(request: QualificationRequest): Promise<QualificationResult> {
    const inquiry = await prisma.iruInquiry.findUnique({
      where: { inquiryId: request.inquiryId },
      include: { offering: true },
    });

    if (!inquiry) {
      throw new DbisError(ErrorCode.NOT_FOUND, `Inquiry ${request.inquiryId} not found`);
    }

    // Step 1: Institutional Verification
    const institutionalVerification = await institutionalVerifier.verify(
      inquiry.organizationName,
      inquiry.institutionalType,
      request.preliminaryInfo
    );

    // Step 2: Capacity Tier Assessment
    const capacityAssessment = await capacityTierAssessor.assess(
      inquiry.institutionalType,
      inquiry.estimatedVolume,
      request.preliminaryInfo
    );

    // Step 3: Regulatory Compliance Check
    const regulatoryCompliance = await regulatoryComplianceChecker.check(
      inquiry.jurisdiction,
      inquiry.organizationName,
      request.preliminaryInfo
    );

    // Step 4: Jurisdictional Law Review
    const jurisdictionalLaw = await jurisdictionalLawReviewer.review(
      inquiry.jurisdiction,
      inquiry.offering.capacityTier
    );

    // Step 5: Technical Capability Assessment
    const technicalCapability = await technicalCapabilityAssessor.assess(
      request.preliminaryInfo
    );

    // Calculate overall qualification
    const qualified =
      institutionalVerification.verified &&
      regulatoryCompliance.compliant &&
      jurisdictionalLaw.approved &&
      technicalCapability.capable;

    // Calculate risk score (0-100, lower is better)
    const riskScore = this.calculateRiskScore({
      institutionalVerification,
      capacityAssessment,
      regulatoryCompliance,
      jurisdictionalLaw,
      technicalCapability,
    });

    // Generate recommendations
    const recommendations = this.generateRecommendations({
      institutionalVerification,
      capacityAssessment,
      regulatoryCompliance,
      jurisdictionalLaw,
      technicalCapability,
    });

    // Generate next steps
    const nextSteps = this.generateNextSteps(qualified, {
      institutionalVerification,
      capacityAssessment,
      regulatoryCompliance,
      jurisdictionalLaw,
      technicalCapability,
    });

    const result: QualificationResult = {
      inquiryId: inquiry.inquiryId,
      qualified,
      institutionalType: institutionalVerification.verifiedType || inquiry.institutionalType,
      capacityTier: capacityAssessment.recommendedTier || inquiry.offering.capacityTier,
      riskScore,
      qualificationDetails: {
        institutionalVerification,
        capacityAssessment,
        regulatoryCompliance,
        jurisdictionalLaw,
        technicalCapability,
      },
      recommendations,
      nextSteps,
    };

    // Update inquiry with qualification result (within transaction)
    await prisma.$transaction(async (tx) => {
      await tx.iruInquiry.update({
        where: { inquiryId: inquiry.inquiryId },
        data: {
          status: qualified ? 'qualified' : 'rejected',
          qualificationResult: result,
          capacityTier: result.capacityTier,
          riskScore: result.riskScore,
          completedAt: new Date(),
          updatedAt: new Date(),
        },
      });

      // If qualified, create subscription record
      if (qualified) {
        const subscriptionId = `SUB-${uuidv4().substring(0, 8).toUpperCase()}`;
        await tx.iruSubscription.create({
          data: {
            id: uuidv4(),
            subscriptionId,
            inquiryId: inquiry.inquiryId,
            offeringId: inquiry.offering.id,
            organizationName: inquiry.organizationName,
            capacityTier: result.capacityTier,
            subscriptionStatus: 'pending',
            subscriptionDate: new Date(),
            createdAt: new Date(),
            updatedAt: new Date(),
          },
        });
      }
    });

    return result;
  }

  /**
   * Calculate risk score
   */
  private calculateRiskScore(assessments: any): number {
    let riskScore = 0;
    let weight = 0;

    // Institutional verification (weight: 20%)
    if (assessments.institutionalVerification.riskScore !== undefined) {
      riskScore += assessments.institutionalVerification.riskScore * 0.2;
      weight += 0.2;
    }

    // Regulatory compliance (weight: 30%)
    if (assessments.regulatoryCompliance.riskScore !== undefined) {
      riskScore += assessments.regulatoryCompliance.riskScore * 0.3;
      weight += 0.3;
    }

    // Jurisdictional law (weight: 20%)
    if (assessments.jurisdictionalLaw.riskScore !== undefined) {
      riskScore += assessments.jurisdictionalLaw.riskScore * 0.2;
      weight += 0.2;
    }

    // Technical capability (weight: 20%)
    if (assessments.technicalCapability.riskScore !== undefined) {
      riskScore += assessments.technicalCapability.riskScore * 0.2;
      weight += 0.2;
    }

    // Capacity assessment (weight: 10%)
    if (assessments.capacityAssessment.riskScore !== undefined) {
      riskScore += assessments.capacityAssessment.riskScore * 0.1;
      weight += 0.1;
    }

    return weight > 0 ? riskScore / weight : 50; // Default to medium risk if no assessments
  }

  /**
   * Generate recommendations
   */
  private generateRecommendations(assessments: any): string[] {
    const recommendations: string[] = [];

    if (!assessments.institutionalVerification.verified) {
      recommendations.push('Provide additional documentation to verify institutional type');
    }

    if (!assessments.regulatoryCompliance.compliant) {
      recommendations.push('Address regulatory compliance issues before proceeding');
    }

    if (!assessments.jurisdictionalLaw.approved) {
      recommendations.push('Review jurisdictional law requirements and obtain necessary approvals');
    }

    if (!assessments.technicalCapability.capable) {
      recommendations.push('Enhance technical capabilities or provide technical support plan');
    }

    if (assessments.capacityAssessment.recommendedTier !== assessments.capacityAssessment.requestedTier) {
      recommendations.push(
        `Consider adjusting to Tier ${assessments.capacityAssessment.recommendedTier} based on usage profile`
      );
    }

    return recommendations;
  }

  /**
   * Generate next steps
   */
  private generateNextSteps(qualified: boolean, assessments: any): string[] {
    const nextSteps: string[] = [];

    if (qualified) {
      nextSteps.push('Proceed to agreement generation and execution');
      nextSteps.push('Complete technical onboarding');
      nextSteps.push('Schedule infrastructure deployment');
    } else {
      nextSteps.push('Address qualification issues identified in assessment');
      nextSteps.push('Resubmit inquiry after addressing concerns');
      nextSteps.push('Contact DBIS support for assistance');
    }

    return nextSteps;
  }
}

export const qualificationEngine = new QualificationEngine();
