@file:Suppress("MatchingDeclarationName") // SessionOrchestrator* extension group, not a single-class file.

package com.correx.core.kernel.orchestration

import com.correx.core.context.model.ContextEntry
import com.correx.core.context.model.ContextLayer
import com.correx.core.context.model.EntryRole
import com.correx.core.events.events.ExecutionPlanLockedEvent
import com.correx.core.events.events.InitialIntentEvent
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.events.WorkflowCompletedEvent
import com.correx.core.events.types.ContextEntryId
import com.correx.core.events.types.SessionId
import com.correx.core.transitions.graph.StageConfig
import java.util.UUID

/**
 * Positive-pattern accretion (design 2026-07-12-acr-concept-compiler.md §"Broaden beyond failure→fix"):
 * the failure→fix rail learns from what BROKE; this learns from what WORKED. When the architect is about
 * to plan, it is shown the plan SHAPE (stage-id sequence) of a prior run whose intent resembled this
 * one and that actually completed — so run N+1 starts from a decomposition already validated by run N,
 * instead of re-deriving structure from zero every time.
 *
 * Fully deterministic (invariants #8/#9): a pure fold over recorded events (initial intent, locked plan,
 * workflow completion) across all sessions. Intent resemblance is a keyword Jaccard overlap — no LLM, no
 * embedder — so it replays identically. Advisory only: it injects a reference shape as SYSTEM context;
 * the architect still authors the plan (invariant #3 LLM-proposes/core-decides).
 */

/** A completed run reduced to what a future planner can reuse: its intent keywords and plan shape. */
internal data class SuccessfulPlanShape(
    val sessionId: String,
    val intentKeywords: Set<String>,
    val stageSequence: List<String>,
)

/** Stopword-trimmed lowercase word set of an intent — the deterministic resemblance key. */
internal fun intentKeywords(intent: String): Set<String> =
    intent.lowercase()
        .split(Regex("""[^a-z0-9]+"""))
        .filter { it.length > 2 && it !in INTENT_STOPWORDS }
        .toSet()

/** Jaccard overlap of two keyword sets — 0.0 when either is empty. */
internal fun keywordOverlap(a: Set<String>, b: Set<String>): Double {
    if (a.isEmpty() || b.isEmpty()) return 0.0
    val inter = a.intersect(b).size.toDouble()
    return inter / a.union(b).size
}

/**
 * Mine successful plan shapes from [events] (cross-session log). A session qualifies when its locked
 * plan's workflow later emits a [WorkflowCompletedEvent] for that SAME workflow id — i.e. the executed
 * plan (not just the planning phase) reached completion. [exclude] drops the current session so a run
 * never learns from itself.
 */
internal fun mineSuccessfulPlanShapes(events: List<StoredEvent>, exclude: String): List<SuccessfulPlanShape> {
    val intents = events.mapNotNull { it.payload as? InitialIntentEvent }.associate { it.sessionId.value to it.intent }
    val locked = events.mapNotNull { it.payload as? ExecutionPlanLockedEvent }
    val completedWorkflows = events.mapNotNull { it.payload as? WorkflowCompletedEvent }
        .map { it.sessionId.value to it.workflowId }.toSet()
    return locked.mapNotNull { plan ->
        val sid = plan.sessionId.value
        val intent = intents[sid] ?: return@mapNotNull null
        // The executed plan completed only if a completion for its OWN workflow id was recorded.
        if (sid == exclude || (sid to plan.workflowId) !in completedWorkflows) return@mapNotNull null
        SuccessfulPlanShape(sid, intentKeywords(intent), plan.stageIds)
    }
}

/**
 * L0/SYSTEM entry naming the closest matching prior successful plan shape — but only for the PLANNING
 * stage (the one producing an `execution_plan`), and only when resemblance clears [MIN_INTENT_OVERLAP]
 * so an unrelated run's shape is not mistaken for guidance.
 */
internal suspend fun SessionOrchestrator.successfulPlanShapeEntries(
    sessionId: SessionId,
    stageConfig: StageConfig,
): List<ContextEntry> {
    val isPlanningStage = stageConfig.produces.any { it.kind.id == "execution_plan" }
    if (!isPlanningStage) return emptyList()
    val here = initialIntent(sessionId)?.let(::intentKeywords).orEmpty()
    if (here.isEmpty()) return emptyList()
    val best = mineSuccessfulPlanShapes(eventStore.allEvents().toList(), exclude = sessionId.value)
        .map { it to keywordOverlap(here, it.intentKeywords) }
        .filter { it.second >= MIN_INTENT_OVERLAP }
        .maxByOrNull { it.second } ?: return emptyList()
    val content = "## A plan shape that worked before\nA prior run with a similar goal completed " +
        "successfully using this stage sequence — reuse its structure where it fits, adapt where the " +
        "goal differs:\n${best.first.stageSequence.joinToString(" → ")}"
    return listOf(
        ContextEntry(
            id = ContextEntryId(UUID.randomUUID().toString()),
            layer = ContextLayer.L0,
            content = content,
            sourceType = "successfulPlanShape",
            sourceId = best.first.sessionId,
            tokenEstimate = estimateTokens(content),
            role = EntryRole.SYSTEM,
        ),
    )
}

private const val MIN_INTENT_OVERLAP = 0.34
private val INTENT_STOPWORDS = setOf(
    "the", "and", "for", "with", "that", "this", "add", "make", "use", "using", "into", "from", "all",
    "new", "app", "should", "must", "will", "can", "its", "was", "are", "you", "your", "then",
)
