import com.correx.core.events.events.InitialIntentEvent
import com.correx.core.events.events.SteeringNoteAddedEvent
import com.correx.core.events.events.TransitionExecutedEvent
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import com.correx.core.events.types.TransitionId
import com.correx.core.journal.DecisionJournalProjector
import com.correx.core.journal.DefaultDecisionJournalReducer
import com.correx.core.journal.model.DecisionKind
import com.correx.testing.fixtures.EventFixtures.stored
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class DecisionJournalProjectorTest {
    private val projector = DecisionJournalProjector(DefaultDecisionJournalReducer())

    @Test
    fun `steering and transition each produce one ordered record`() {
        var s = projector.initial()
        s = projector.apply(
            s,
            stored(
                payload = SteeringNoteAddedEvent(SessionId("x"), "use jwt", StageId("plan")),
                sequence = 1L,
            ),
        )
        s = projector.apply(
            s,
            stored(
                payload = TransitionExecutedEvent(SessionId("x"), StageId("plan"), StageId("impl"), TransitionId("t1")),
                sequence = 2L,
            ),
        )
        assertEquals(2, s.records.size)
        assertEquals(DecisionKind.STEERING, s.records[0].kind)
        assertEquals(DecisionKind.TRANSITION, s.records[1].kind)
    }

    @Test
    fun `initial intent becomes a journal record`() {
        val s = projector.apply(
            projector.initial(),
            stored(payload = InitialIntentEvent(SessionId("x"), "add auth layer"), sequence = 1L),
        )
        assertEquals(1, s.records.size)
        assertEquals(DecisionKind.INTENT, s.records[0].kind)
        assertEquals("Goal: add auth layer", s.records[0].summary)
    }

    @Test
    fun `unrelated events are ignored`() {
        val s0 = projector.initial()
        val s1 = projector.apply(
            s0,
            stored(payload = SteeringNoteAddedEvent(SessionId("x"), "note")),
        )
        assertEquals(1, s1.records.size)
    }
}
