package com.correx.core.router

import com.correx.core.events.events.IdeaCapturedEvent
import com.correx.core.events.events.IdeaDiscardedEvent
import com.correx.core.events.stores.EventStore
import com.correx.core.events.types.SessionId
import com.correx.core.router.model.Idea

/**
 * Rebuilds the operator's idea board from the event log. Cross-session by design: it folds over
 * [EventStore.allEvents] rather than a single session's replay, so an idea captured in one session
 * shows on the board (and feeds the router) in every session. A captured idea is dropped once a
 * matching [IdeaDiscardedEvent] tombstones it (invariant #1 — the capture stays in the log).
 */
class IdeaReader(private val eventStore: EventStore) {

    /** Active ideas (captured, not later discarded) across all sessions, newest first. */
    fun activeIdeas(): List<Idea> {
        val discarded = mutableSetOf<String>()
        val captured = mutableListOf<Idea>()
        eventStore.allEvents().forEach { stored ->
            when (val payload = stored.payload) {
                is IdeaDiscardedEvent -> discarded += payload.ideaId
                is IdeaCapturedEvent -> captured += Idea(payload.ideaId, payload.text, payload.timestampMs)
                else -> Unit
            }
        }
        return captured.filterNot { it.id in discarded }.sortedByDescending { it.capturedAtMs }
    }

    /** The session that captured [ideaId], so a discard tombstone lands alongside its capture. */
    fun sessionOf(ideaId: String): SessionId? =
        eventStore.allEvents()
            .mapNotNull { it.payload as? IdeaCapturedEvent }
            .firstOrNull { it.ideaId == ideaId }
            ?.sessionId
}
