
/**
 * Machine Learning Prediction Service
 * Provides ML-based predictions for quotes, SLA breaches, badge renewals, etc.
 */

// import { Region } from '@prisma/client';
type Region = "SOUTH_AFRICA" | "AUSTRALIA" | "UNITED_KINGDOM" | "USA";

// Simple ML model simulation (in production, this would call actual ML APIs)
export class MLPredictionService {
  /**
   * Predict quote success probability
   */
  static async predictQuoteSuccess(params: {
    region: Region;
    roofType?: string;
    propertyCondition?: string;
    badgeLevel?: string;
    pricingAmount?: number;
  }): Promise<{
    successProbability: number;
    conversionImpact: number;
    confidenceScore: number;
  }> {
    // Base probability
    let probability = 0.5;

    // Region factor
    const regionFactors: Record<Region, number> = {
      SOUTH_AFRICA: 0.72,
      AUSTRALIA: 0.78,
      UNITED_KINGDOM: 0.75,
      USA: 0.80,
    };
    probability = regionFactors[params.region] || 0.7;

    // Badge level factor
    if (params.badgeLevel) {
      const badgeBonus: Record<string, number> = {
        BRONZE: 0.0,
        SILVER: 0.05,
        GOLD: 0.10,
        PLATINUM: 0.15,
      };
      probability += badgeBonus[params.badgeLevel] || 0;
    }

    // Property condition factor
    if (params.propertyCondition) {
      const conditionFactor: Record<string, number> = {
        EXCELLENT: 0.08,
        GOOD: 0.05,
        FAIR: 0.0,
        POOR: -0.05,
      };
      probability += conditionFactor[params.propertyCondition.toUpperCase()] || 0;
    }

    // Pricing factor (simplified)
    if (params.pricingAmount) {
      if (params.pricingAmount < 100000) {
        probability += 0.05; // Smaller projects convert better
      } else if (params.pricingAmount > 500000) {
        probability -= 0.05; // Larger projects need more consideration
      }
    }

    // Ensure bounds
    probability = Math.max(0.1, Math.min(0.99, probability));

    return {
      successProbability: probability,
      conversionImpact: probability > 0.7 ? 0.25 : 0.15,
      confidenceScore: 0.85,
    };
  }

  /**
   * Predict SLA breach likelihood
   */
  static async predictSLABreach(params: {
    contractId: string;
    currentDelay?: number;
    historicalPerformance?: number;
    contractorReliability?: number;
  }): Promise<{
    breachProbability: number;
    severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
    estimatedDaysToRisk: number;
    mitigationSteps: string[];
  }> {
    let probability = 0.3;

    // Current delay factor
    if (params.currentDelay) {
      probability += Math.min(0.4, params.currentDelay / 1000); // Delay in hours
    }

    // Historical performance
    if (params.historicalPerformance !== undefined) {
      probability += (1 - params.historicalPerformance) * 0.3;
    }

    // Contractor reliability
    if (params.contractorReliability !== undefined) {
      probability += (1 - params.contractorReliability) * 0.2;
    }

    probability = Math.max(0.05, Math.min(0.99, probability));

    // Determine severity
    let severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
    if (probability < 0.3) severity = 'LOW';
    else if (probability < 0.5) severity = 'MEDIUM';
    else if (probability < 0.75) severity = 'HIGH';
    else severity = 'CRITICAL';

    // Calculate estimated days to risk
    const daysToRisk = Math.round((1 - probability) * 14);

    // Generate mitigation steps
    const mitigationSteps: string[] = [];
    if (probability > 0.5) {
      mitigationSteps.push('Contact contractor immediately');
      mitigationSteps.push('Review resource allocation');
    }
    if (probability > 0.7) {
      mitigationSteps.push('Escalate to senior management');
      mitigationSteps.push('Prepare customer communication');
    }
    if (params.currentDelay && params.currentDelay > 24) {
      mitigationSteps.push('Assign backup contractor');
    }

    return {
      breachProbability: probability,
      severity,
      estimatedDaysToRisk: daysToRisk,
      mitigationSteps,
    };
  }

  /**
   * Predict badge renewal likelihood
   */
  static async predictBadgeRenewal(params: {
    contractorId: string;
    badgeId: string;
    performanceScore?: number;
    complianceScore?: number;
    recentViolations?: number;
    daysToExpiry: number;
  }): Promise<{
    renewalProbability: number;
    renewalLikelihood: 'VERY_LOW' | 'LOW' | 'MODERATE' | 'HIGH' | 'VERY_HIGH';
    improvementAreas: string[];
    urgencyLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT';
  }> {
    let probability = 0.7; // Base renewal rate

    // Performance factor
    if (params.performanceScore !== undefined) {
      probability += (params.performanceScore - 0.5) * 0.3;
    }

    // Compliance factor
    if (params.complianceScore !== undefined) {
      probability += (params.complianceScore - 0.5) * 0.3;
    }

    // Violations penalty
    if (params.recentViolations) {
      probability -= Math.min(0.4, params.recentViolations * 0.1);
    }

    probability = Math.max(0.05, Math.min(0.99, probability));

    // Determine likelihood category
    let renewalLikelihood: 'VERY_LOW' | 'LOW' | 'MODERATE' | 'HIGH' | 'VERY_HIGH';
    if (probability < 0.2) renewalLikelihood = 'VERY_LOW';
    else if (probability < 0.4) renewalLikelihood = 'LOW';
    else if (probability < 0.6) renewalLikelihood = 'MODERATE';
    else if (probability < 0.8) renewalLikelihood = 'HIGH';
    else renewalLikelihood = 'VERY_HIGH';

    // Generate improvement areas
    const improvementAreas: string[] = [];
    if (params.performanceScore && params.performanceScore < 0.7) {
      improvementAreas.push('Improve job completion rate');
    }
    if (params.complianceScore && params.complianceScore < 0.7) {
      improvementAreas.push('Address compliance issues');
    }
    if (params.recentViolations && params.recentViolations > 0) {
      improvementAreas.push('Resolve pending violations');
    }

    // Determine urgency
    let urgencyLevel: 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT';
    if (params.daysToExpiry < 7) urgencyLevel = 'URGENT';
    else if (params.daysToExpiry < 14) urgencyLevel = 'HIGH';
    else if (params.daysToExpiry < 30) urgencyLevel = 'MEDIUM';
    else urgencyLevel = 'LOW';

    return {
      renewalProbability: probability,
      renewalLikelihood,
      improvementAreas,
      urgencyLevel,
    };
  }

  /**
   * Generate quote optimization suggestions
   */
  static async generateQuoteOptimizations(params: {
    quoteId: string;
    currentPricing: number;
    region: Region;
    successProbability: number;
  }): Promise<
    Array<{
      type: string;
      currentValue: number;
      suggestedValue: number;
      expectedImprovement: number;
      reason: string;
      priority: 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT';
    }>
  > {
    const optimizations: Array<{
      type: string;
      currentValue: number;
      suggestedValue: number;
      expectedImprovement: number;
      reason: string;
      priority: 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT';
    }> = [];

    // Pricing optimization
    if (params.successProbability < 0.6) {
      const suggestedPrice = params.currentPricing * 0.95; // 5% discount
      optimizations.push({
        type: 'PRICING_ADJUSTMENT',
        currentValue: params.currentPricing,
        suggestedValue: suggestedPrice,
        expectedImprovement: 15, // 15% increase in conversion
        reason: 'Current probability is low. A 5% price reduction could improve conversion by 15%.',
        priority: 'HIGH',
      });
    }

    // Badge upgrade suggestion
    if (params.successProbability < 0.75) {
      optimizations.push({
        type: 'BADGE_UPGRADE',
        currentValue: 0,
        suggestedValue: 1,
        expectedImprovement: 10,
        reason: 'Upgrading contractor badge level could increase customer confidence.',
        priority: 'MEDIUM',
      });
    }

    return optimizations;
  }

  /**
   * Simulate quote in real-time
   */
  static async simulateQuote(params: {
    region: Region;
    roofType?: string;
    propertyCondition?: string;
    badgeLevel?: string;
    estimatedPrice?: number;
  }): Promise<{
    successProbability: number;
    approvalLikelihood: number;
    conversionImpact: number;
    pricingRecommendation?: number;
    improvementSuggestions: string[];
  }> {
    const prediction = await this.predictQuoteSuccess({
      region: params.region,
      roofType: params.roofType,
      propertyCondition: params.propertyCondition,
      badgeLevel: params.badgeLevel,
      pricingAmount: params.estimatedPrice,
    });

    const improvementSuggestions: string[] = [];

    if (prediction.successProbability < 0.7) {
      improvementSuggestions.push('Consider improving property condition assessment');
      if (params.estimatedPrice && params.estimatedPrice > 300000) {
        improvementSuggestions.push('Break down pricing into milestones');
      }
    }

    let pricingRecommendation: number | undefined;
    if (params.estimatedPrice && prediction.successProbability < 0.6) {
      pricingRecommendation = params.estimatedPrice * 0.95;
      improvementSuggestions.push(
        `Consider reducing price to ${pricingRecommendation.toLocaleString()} ZAR`
      );
    }

    return {
      successProbability: prediction.successProbability,
      approvalLikelihood: prediction.successProbability * 0.95,
      conversionImpact: prediction.conversionImpact,
      pricingRecommendation,
      improvementSuggestions,
    };
  }
}
