package com.correx.core.journal

import com.correx.core.events.events.ApprovalDecisionResolvedEvent
import com.correx.core.events.events.ArtifactValidatedEvent
import com.correx.core.events.events.ExecutionPlanLockedEvent
import com.correx.core.events.events.JournalCompactedEvent
import com.correx.core.events.events.InitialIntentEvent
import com.correx.core.events.events.RetryAttemptedEvent
import com.correx.core.events.events.StageFailedEvent
import com.correx.core.events.events.SteeringNoteAddedEvent
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.events.TransitionExecutedEvent
import com.correx.core.journal.model.DecisionJournalState
import com.correx.core.journal.model.DecisionKind
import com.correx.core.journal.model.DecisionRecord

class DefaultDecisionJournalReducer : DecisionJournalReducer {
    override fun reduce(state: DecisionJournalState, event: StoredEvent): DecisionJournalState {
        if (event.payload is ExecutionPlanLockedEvent) return state.copy(planLocked = true)
        if (event.payload is JournalCompactedEvent) {
            val p = event.payload as JournalCompactedEvent
            return state.copy(
                compactedThroughSequence = p.coversThroughSequence,
                summaryArtifactId = p.summaryArtifactId,
                lowSalienceOmittedCount = state.lowSalienceOmittedCount + p.lowSalienceOmittedCount,
                records = state.records.filter { it.sequence > p.coversThroughSequence },
            )
        }
        val record = when (val p = event.payload) {
            is InitialIntentEvent -> DecisionRecord(
                sequence = event.sessionSequence,
                kind = DecisionKind.INTENT,
                summary = "Goal: ${p.intent}",
            )
            is SteeringNoteAddedEvent -> DecisionRecord(
                sequence = event.sessionSequence,
                kind = if (state.planLocked) DecisionKind.PREEMPT else DecisionKind.STEERING,
                summary = if (state.planLocked) "PRIORITY DIRECTIVE (overrides plan): ${p.content}"
                          else "User steering: ${p.content}",
                stageId = p.stageId?.value,
            )
            is ApprovalDecisionResolvedEvent -> DecisionRecord(
                sequence = event.sessionSequence,
                kind = DecisionKind.APPROVAL,
                summary = buildString {
                    append("Approval ${p.outcome} (tier ${p.tier})")
                    p.reason?.let { append(": $it") }
                    p.userSteering?.let { append(" — steered: ${it.text}") }
                },
            )
            is TransitionExecutedEvent -> DecisionRecord(
                sequence = event.sessionSequence,
                kind = DecisionKind.TRANSITION,
                summary = "Advanced ${p.from.value} → ${p.to.value} (${p.transitionId.value})",
                stageId = p.to.value,
                fromStageId = p.from.value,
            )
            is RetryAttemptedEvent -> DecisionRecord(
                sequence = event.sessionSequence,
                kind = DecisionKind.RETRY,
                summary = "Retry ${p.attemptNumber}/${p.maxAttempts} of ${p.stageId.value}: ${p.failureReason}",
                stageId = p.stageId.value,
            )
            is StageFailedEvent -> DecisionRecord(
                sequence = event.sessionSequence,
                kind = DecisionKind.FAILURE,
                summary = "Stage ${p.stageId.value} failed: ${p.reason}",
                stageId = p.stageId.value,
            )
            is ArtifactValidatedEvent -> DecisionRecord(
                sequence = event.sessionSequence,
                kind = DecisionKind.ARTIFACT,
                summary = "Validated artifact ${p.artifactId.value} at ${p.stageId.value}",
                stageId = p.stageId.value,
            )
            else -> null
        }
        return record?.let { state.copy(records = state.records + it) } ?: state
    }
}
