package com.correx.core.sessions

import com.correx.core.events.events.OperatorProfileBoundEvent
import com.correx.core.events.events.ProjectProfileBoundEvent
import com.correx.core.events.events.SessionWorkspaceBoundEvent
import com.correx.core.events.events.StageCompletedEvent
import com.correx.core.events.events.StageFailedEvent
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.events.TransitionExecutedEvent

class DefaultSessionReducer : SessionReducer {

    override fun reduce(
        state: SessionState,
        event: StoredEvent
    ): SessionState {

        val payload = event.payload

        val newStatus = when (payload) {
            is StageFailedEvent ->
                SessionStatus.FAILED

            is StageCompletedEvent,
            is TransitionExecutedEvent ->
                SessionStatus.ACTIVE

            else ->
                state.status
        }

        val createdAt = state.createdAt
            ?: event.metadata.timestamp

        val boundWorkspace = when (payload) {
            is SessionWorkspaceBoundEvent ->
                BoundWorkspace(
                    workspaceRoot = payload.workspaceRoot,
                    allowedPaths = payload.allowedPaths,
                )
            else -> state.boundWorkspace
        }

        val boundProfile = when (payload) {
            is OperatorProfileBoundEvent ->
                BoundProfile(
                    about = payload.about,
                    approvalMode = payload.approvalMode,
                    preferredModels = payload.preferredModels,
                    conventions = payload.conventions,
                )
            else -> state.boundProfile
        }

        val boundProjectProfile = when (payload) {
            is ProjectProfileBoundEvent -> BoundProjectProfile(
                about = payload.about,
                conventions = payload.conventions,
                commands = payload.commands,
            )
            else -> state.boundProjectProfile
        }

        return state.copy(
            status = newStatus,
            createdAt = createdAt,
            updatedAt = event.metadata.timestamp,
            boundWorkspace = boundWorkspace,
            boundProfile = boundProfile,
            boundProjectProfile = boundProjectProfile,
        )
    }
}
