package com.correx.core.sessions

import com.correx.core.events.events.EventMetadata
import com.correx.core.events.events.OperatorProfileBoundEvent
import com.correx.core.events.events.SessionWorkspaceBoundEvent
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.types.EventId
import com.correx.core.events.types.SessionId
import kotlinx.datetime.Instant
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNull
import org.junit.jupiter.api.Test

class DefaultSessionReducerTest {

    private val reducer = DefaultSessionReducer()
    private val sessionId = SessionId("s-test")
    private val initialState = SessionState(status = SessionStatus.ACTIVE)

    private fun stored(payload: com.correx.core.events.events.EventPayload) = StoredEvent(
        metadata = EventMetadata(
            eventId = EventId("e-1"),
            sessionId = sessionId,
            timestamp = Instant.parse("2026-01-01T00:00:00Z"),
            schemaVersion = 1,
            causationId = null,
            correlationId = null,
        ),
        sequence = 1L,
        sessionSequence = 1L,
        payload = payload,
    )

    @Test
    fun `OperatorProfileBoundEvent populates boundProfile`() {
        val event = stored(
            OperatorProfileBoundEvent(
                sessionId = sessionId,
                about = "Expert Kotlin engineer",
                approvalMode = "auto",
                preferredModels = listOf("model-x"),
                conventions = listOf("no var"),
            ),
        )

        val result = reducer.reduce(initialState, event)

        val profile = result.boundProfile
        assertEquals("Expert Kotlin engineer", profile?.about)
        assertEquals("auto", profile?.approvalMode)
        assertEquals(listOf("model-x"), profile?.preferredModels)
        assertEquals(listOf("no var"), profile?.conventions)
    }

    @Test
    fun `boundProfile is null by default`() {
        assertNull(initialState.boundProfile)
    }

    @Test
    fun `unrelated event leaves boundProfile unchanged`() {
        val state = initialState.copy(
            boundProfile = BoundProfile(
                about = "original",
                approvalMode = "",
                preferredModels = emptyList(),
                conventions = emptyList(),
            ),
        )
        val event = stored(
            SessionWorkspaceBoundEvent(
                sessionId = sessionId,
                workspaceRoot = "/ws",
                allowedPaths = listOf("/ws"),
            ),
        )

        val result = reducer.reduce(state, event)

        assertEquals("original", result.boundProfile?.about)
    }
}
