package com.correx.core.tasks

import com.correx.core.events.events.NewEvent
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.stores.EventStore
import com.correx.core.events.types.SessionId
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.emptyFlow

/** Minimal append-capable in-memory event store for core:tasks tests, keyed per session. */
internal class InMemoryEventStore : EventStore {
    private val events = mutableListOf<StoredEvent>()
    private var global = 0L
    private val perSession = mutableMapOf<SessionId, Long>()

    override suspend fun append(event: NewEvent): StoredEvent {
        global += 1
        val seq = (perSession[event.metadata.sessionId] ?: 0L) + 1
        perSession[event.metadata.sessionId] = seq
        val stored = StoredEvent(
            metadata = event.metadata,
            sequence = global,
            sessionSequence = seq,
            payload = event.payload,
        )
        events += stored
        return stored
    }

    override suspend fun appendAll(events: List<NewEvent>): List<StoredEvent> = events.map { append(it) }

    override fun read(sessionId: SessionId): List<StoredEvent> =
        events.filter { it.metadata.sessionId == sessionId }.sortedBy { it.sessionSequence }

    override fun readFrom(sessionId: SessionId, fromSequence: Long): List<StoredEvent> =
        read(sessionId).filter { it.sessionSequence >= fromSequence }

    override fun lastSequence(sessionId: SessionId): Long? =
        read(sessionId).maxOfOrNull { it.sessionSequence }

    override fun subscribe(sessionId: SessionId): Flow<StoredEvent> = emptyFlow()

    override fun subscribeAll(): Flow<StoredEvent> = emptyFlow()

    override suspend fun lastGlobalSequence(): Long = global

    override fun allEvents(): Sequence<StoredEvent> = events.asSequence()

    override fun allSessionIds(): Set<SessionId> = events.map { it.metadata.sessionId }.toSet()
}
