package com.correx.core.talkie

import com.correx.core.events.events.IdeaCapturedEvent
import com.correx.core.events.events.IdeaDiscardedEvent
import com.correx.core.events.events.IdeaPromotedEvent
import com.correx.core.events.stores.EventStore
import com.correx.core.events.types.SessionId
import com.correx.core.talkie.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] (or [IdeaPromotedEvent]) tombstones it (invariant #1 — the capture
 * stays in the log).
 */
class IdeaReader(private val eventStore: EventStore) {

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

    /** The session that captured [ideaId], so a tombstone lands alongside its capture. */
    fun sessionOf(ideaId: String): SessionId? =
        capturedOf(ideaId)?.sessionId

    /** The captured text of [ideaId] (so a promotion can write it into the project profile), or null. */
    fun textOf(ideaId: String): String? =
        capturedOf(ideaId)?.text

    private fun capturedOf(ideaId: String): IdeaCapturedEvent? =
        eventStore.allEvents()
            .mapNotNull { it.payload as? IdeaCapturedEvent }
            .firstOrNull { it.ideaId == ideaId }
}
