package com.correx.core.risk

import com.correx.core.events.risk.RiskLevel
import com.correx.core.events.risk.RiskSignal
import com.correx.core.events.risk.RiskSummary
import com.correx.core.inference.InferenceStatus
import com.correx.core.validation.model.ValidationSeverity

class DefaultRiskAssessor : RiskAssessor {
    override fun assess(context: RiskContext): RiskSummary {
        val (report, state, inferenceState) = context
        val signals = mutableListOf<RiskSignal>()

        val allIssues = report.sections.flatMap { it.issues }

        val errorCount = allIssues.count { it.severity == ValidationSeverity.ERROR }
        if (errorCount > 0) {
            signals += RiskSignal.ValidationErrors(errorCount)
        }

        allIssues.firstOrNull { it.code.contains("CYCLE", ignoreCase = true) }
            ?.let { signals += RiskSignal.CycleWithoutExit(it.code) }

        state.retryPolicy?.let { policy ->
            if (state.retryCount >= policy.maxAttempts - 1) {
                signals += RiskSignal.RepeatedFailure(
                    reason = state.failureReason ?: "unknown",
                    count = state.retryCount,
                )
            }
        }

        state.currentStageId?.let { stageId ->
            inferenceState.records
                .firstOrNull { it.stageId == stageId && it.status == InferenceStatus.TIMED_OUT }
                ?.let { signals += RiskSignal.InferenceTimeout(it.latencyMs ?: 0L) }
        }

        val validationDrivenLevel = when {
            allIssues.any { it.severity == ValidationSeverity.ERROR } -> RiskLevel.HIGH
            allIssues.any { it.severity == ValidationSeverity.WARNING } -> RiskLevel.MEDIUM
            allIssues.any { it.severity == ValidationSeverity.INFO } -> RiskLevel.LOW
            else -> RiskLevel.LOW
        }

        var level = signals.fold(RiskLevel.LOW) { acc, signal -> maxOf(acc, signal.toRiskLevel()) }
        level = maxOf(level, validationDrivenLevel)

        val rationale = allIssues.map { "[${it.code}] ${it.message}" }

        return RiskSummary(
            level = level,
            signals = signals,
            recommendedAction = level.toRiskAction(),
            rationale = rationale,
        )
    }
}
