import { NextRequest, NextResponse } from 'next/server'
import { TOMRulesEngine } from '@/lib/sdk/tom-generator/rules-engine'
import { TOMGeneratorState, GapAnalysisResult } from '@/lib/sdk/tom-generator/types'

/**
 * TOM Generator Gap Analysis API
 *
 * POST /api/sdk/v1/tom-generator/gap-analysis - Perform gap analysis
 *
 * Request body:
 * {
 *   tenantId: string
 *   state: TOMGeneratorState
 * }
 *
 * Response:
 * {
 *   gapAnalysis: GapAnalysisResult
 * }
 */

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    const { tenantId, state } = body

    if (!tenantId) {
      return NextResponse.json(
        { success: false, error: 'tenantId is required' },
        { status: 400 }
      )
    }

    if (!state) {
      return NextResponse.json(
        { success: false, error: 'state is required in request body' },
        { status: 400 }
      )
    }

    // Parse dates in state
    const parsedState: TOMGeneratorState = {
      ...state,
      createdAt: new Date(state.createdAt),
      updatedAt: new Date(state.updatedAt),
      steps: state.steps?.map((step: { id: string; completed: boolean; data: unknown; validatedAt: string | null }) => ({
        ...step,
        validatedAt: step.validatedAt ? new Date(step.validatedAt) : null,
      })) || [],
      documents: state.documents?.map((doc: { uploadedAt: string; validFrom?: string; validUntil?: string; aiAnalysis?: { analyzedAt: string } }) => ({
        ...doc,
        uploadedAt: new Date(doc.uploadedAt),
        validFrom: doc.validFrom ? new Date(doc.validFrom) : null,
        validUntil: doc.validUntil ? new Date(doc.validUntil) : null,
        aiAnalysis: doc.aiAnalysis ? {
          ...doc.aiAnalysis,
          analyzedAt: new Date(doc.aiAnalysis.analyzedAt),
        } : null,
      })) || [],
      derivedTOMs: state.derivedTOMs?.map((tom: { implementationDate?: string; reviewDate?: string }) => ({
        ...tom,
        implementationDate: tom.implementationDate ? new Date(tom.implementationDate) : null,
        reviewDate: tom.reviewDate ? new Date(tom.reviewDate) : null,
      })) || [],
      gapAnalysis: state.gapAnalysis ? {
        ...state.gapAnalysis,
        generatedAt: new Date(state.gapAnalysis.generatedAt),
      } : null,
      exports: state.exports?.map((exp: { generatedAt: string }) => ({
        ...exp,
        generatedAt: new Date(exp.generatedAt),
      })) || [],
    }

    // Initialize rules engine
    const engine = new TOMRulesEngine()

    // Perform gap analysis using derived TOMs and documents from state
    const gapAnalysis = engine.performGapAnalysis(
      parsedState.derivedTOMs,
      parsedState.documents
    )

    // Calculate detailed metrics
    const metrics = calculateGapMetrics(gapAnalysis)

    return NextResponse.json({
      success: true,
      data: {
        gapAnalysis,
        metrics,
        generatedAt: gapAnalysis.generatedAt.toISOString(),
      },
    })
  } catch (error) {
    console.error('Failed to perform gap analysis:', error)
    return NextResponse.json(
      { success: false, error: 'Failed to perform gap analysis' },
      { status: 500 }
    )
  }
}

function calculateGapMetrics(gapAnalysis: GapAnalysisResult) {
  const totalGaps = gapAnalysis.missingControls.length +
    gapAnalysis.partialControls.length +
    gapAnalysis.missingEvidence.length

  const criticalGaps = gapAnalysis.missingControls.filter(
    (c) => c.priority === 'CRITICAL' || c.priority === 'HIGH'
  ).length

  const mediumGaps = gapAnalysis.missingControls.filter(
    (c) => c.priority === 'MEDIUM'
  ).length

  const lowGaps = gapAnalysis.missingControls.filter(
    (c) => c.priority === 'LOW'
  ).length

  // Group missing controls by category
  const gapsByCategory: Record<string, number> = {}
  gapAnalysis.missingControls.forEach((control) => {
    const category = control.controlId.split('-')[1] || 'OTHER'
    gapsByCategory[category] = (gapsByCategory[category] || 0) + 1
  })

  // Calculate compliance readiness
  const maxScore = 100
  const deductionPerCritical = 10
  const deductionPerMedium = 5
  const deductionPerLow = 2
  const deductionPerPartial = 3
  const deductionPerMissingEvidence = 1

  const deductions =
    criticalGaps * deductionPerCritical +
    mediumGaps * deductionPerMedium +
    lowGaps * deductionPerLow +
    gapAnalysis.partialControls.length * deductionPerPartial +
    gapAnalysis.missingEvidence.length * deductionPerMissingEvidence

  const complianceReadiness = Math.max(0, Math.min(100, maxScore - deductions))

  // Prioritized action items
  const prioritizedActions = [
    ...gapAnalysis.missingControls
      .filter((c) => c.priority === 'CRITICAL')
      .map((c) => ({
        type: 'MISSING_CONTROL',
        priority: 'CRITICAL',
        controlId: c.controlId,
        reason: c.reason,
        action: `Implement control ${c.controlId}`,
      })),
    ...gapAnalysis.missingControls
      .filter((c) => c.priority === 'HIGH')
      .map((c) => ({
        type: 'MISSING_CONTROL',
        priority: 'HIGH',
        controlId: c.controlId,
        reason: c.reason,
        action: `Implement control ${c.controlId}`,
      })),
    ...gapAnalysis.partialControls.map((c) => ({
      type: 'PARTIAL_CONTROL',
      priority: 'MEDIUM',
      controlId: c.controlId,
      missingAspects: c.missingAspects,
      action: `Complete implementation of ${c.controlId}`,
    })),
    ...gapAnalysis.missingEvidence.map((e) => ({
      type: 'MISSING_EVIDENCE',
      priority: 'LOW',
      controlId: e.controlId,
      requiredEvidence: e.requiredEvidence,
      action: `Upload evidence for ${e.controlId}`,
    })),
  ]

  return {
    totalGaps,
    criticalGaps,
    mediumGaps,
    lowGaps,
    partialControls: gapAnalysis.partialControls.length,
    missingEvidence: gapAnalysis.missingEvidence.length,
    gapsByCategory,
    complianceReadiness,
    overallScore: gapAnalysis.overallScore,
    prioritizedActionsCount: prioritizedActions.length,
    prioritizedActions: prioritizedActions.slice(0, 10), // Top 10 actions
  }
}

export async function OPTIONS() {
  return NextResponse.json(
    { status: 'ok' },
    {
      headers: {
        Allow: 'POST, OPTIONS',
      },
    }
  )
}
