/**
 * TOM Rules Engine — Gap Analysis & Helper Functions
 *
 * Singleton instance, convenience functions, and gap analysis logic.
 */

import {
  DerivedTOM,
  EvidenceDocument,
  GapAnalysisResult,
  MissingControl,
  PartialControl,
  MissingEvidence,
  RulesEngineResult,
  RulesEngineEvaluationContext,
} from './types'
import { getControlById } from './controls/loader'
import { TOMRulesEngine } from './rules-evaluator'

// =============================================================================
// SINGLETON INSTANCE
// =============================================================================

let rulesEngineInstance: TOMRulesEngine | null = null

export function getTOMRulesEngine(): TOMRulesEngine {
  if (!rulesEngineInstance) {
    rulesEngineInstance = new TOMRulesEngine()
  }
  return rulesEngineInstance
}

// =============================================================================
// GAP ANALYSIS
// =============================================================================

export function performGapAnalysis(
  derivedTOMs: DerivedTOM[],
  documents: EvidenceDocument[]
): GapAnalysisResult {
  const missingControls: MissingControl[] = []
  const partialControls: PartialControl[] = []
  const missingEvidence: MissingEvidence[] = []
  const recommendations: string[] = []

  let totalScore = 0
  let totalWeight = 0

  const applicableTOMs = derivedTOMs.filter(
    (tom) => tom.applicability === 'REQUIRED' || tom.applicability === 'RECOMMENDED'
  )

  for (const tom of applicableTOMs) {
    const control = getControlById(tom.controlId)
    if (!control) continue

    const weight = tom.applicability === 'REQUIRED' ? 3 : 1
    totalWeight += weight

    if (tom.implementationStatus === 'NOT_IMPLEMENTED') {
      missingControls.push({
        controlId: tom.controlId,
        reason: `${control.name.de} ist nicht implementiert`,
        priority: control.priority,
      })
    } else if (tom.implementationStatus === 'PARTIAL') {
      partialControls.push({
        controlId: tom.controlId,
        missingAspects: tom.evidenceGaps,
      })
      totalScore += weight * 0.5
    } else {
      totalScore += weight
    }

    const linkedEvidenceIds = tom.linkedEvidence
    const requiredEvidence = control.evidenceRequirements
    const providedEvidence = documents.filter((doc) =>
      linkedEvidenceIds.includes(doc.id)
    )

    if (providedEvidence.length < requiredEvidence.length) {
      const missing = requiredEvidence.filter(
        (req) =>
          !providedEvidence.some(
            (doc) =>
              doc.documentType === 'POLICY' ||
              doc.documentType === 'CERTIFICATE' ||
              doc.originalName.toLowerCase().includes(req.toLowerCase())
          )
      )

      if (missing.length > 0) {
        missingEvidence.push({
          controlId: tom.controlId,
          requiredEvidence: missing,
        })
      }
    }
  }

  const overallScore =
    totalWeight > 0 ? Math.round((totalScore / totalWeight) * 100) : 0

  if (missingControls.length > 0) {
    const criticalMissing = missingControls.filter((mc) => mc.priority === 'CRITICAL')
    if (criticalMissing.length > 0) {
      recommendations.push(
        `${criticalMissing.length} kritische Kontrollen sind nicht implementiert. Diese sollten priorisiert werden.`
      )
    }
  }

  if (partialControls.length > 0) {
    recommendations.push(
      `${partialControls.length} Kontrollen sind nur teilweise implementiert. Vervollstaendigen Sie die Implementierung.`
    )
  }

  if (missingEvidence.length > 0) {
    recommendations.push(
      `Fuer ${missingEvidence.length} Kontrollen fehlen Nachweisdokumente. Laden Sie die entsprechenden Dokumente hoch.`
    )
  }

  if (overallScore >= 80) {
    recommendations.push(
      'Ihr TOM-Compliance-Score ist gut. Fuehren Sie regelmaessige Ueberpruefungen durch.'
    )
  } else if (overallScore >= 50) {
    recommendations.push(
      'Ihr TOM-Compliance-Score erfordert Verbesserungen. Fokussieren Sie sich auf die kritischen Luecken.'
    )
  } else {
    recommendations.push(
      'Ihr TOM-Compliance-Score ist niedrig. Eine systematische Ueberarbeitung der Massnahmen wird empfohlen.'
    )
  }

  return {
    overallScore,
    missingControls,
    partialControls,
    missingEvidence,
    recommendations,
    generatedAt: new Date(),
  }
}

// =============================================================================
// HELPER FUNCTIONS
// =============================================================================

export function evaluateControlsForContext(
  context: RulesEngineEvaluationContext
): RulesEngineResult[] {
  return getTOMRulesEngine().evaluateControls(context)
}

export function deriveTOMsForContext(
  context: RulesEngineEvaluationContext
): DerivedTOM[] {
  return getTOMRulesEngine().deriveAllTOMs(context)
}

export function performQuickGapAnalysis(
  derivedTOMs: DerivedTOM[],
  documents: EvidenceDocument[]
): GapAnalysisResult {
  return performGapAnalysis(derivedTOMs, documents)
}
