package com.correx.core.tasks

import com.correx.core.events.events.EventMetadata
import com.correx.core.events.events.EventPayload
import com.correx.core.events.events.StoredEvent
import com.correx.core.events.events.TaskCancelledEvent
import com.correx.core.events.events.TaskCreatedEvent
import com.correx.core.events.types.EventId
import com.correx.core.events.types.ProjectId
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.TaskId
import kotlinx.datetime.Instant
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class TaskCounterProjectionTest {

    private val projection = TaskCounterProjection("auth")
    private val projectId = ProjectId("auth")

    private fun stored(payload: EventPayload, seq: Long) = StoredEvent(
        metadata = EventMetadata(
            eventId = EventId("e-$seq"),
            sessionId = SessionId("tasks:auth"),
            timestamp = Instant.parse("2026-01-01T00:00:0${seq}Z"),
            schemaVersion = 1,
            causationId = null,
            correlationId = null,
        ),
        sequence = seq,
        sessionSequence = seq,
        payload = payload,
    )

    private fun created(id: TaskId) =
        TaskCreatedEvent(id, projectId, id.value, "title", "goal")

    @Test
    fun `counts only created events and survives cancellation`() {
        val events = listOf(
            stored(created(TaskId("auth-1")), 1),
            stored(created(TaskId("auth-2")), 2),
            stored(TaskCancelledEvent(TaskId("auth-1")), 3),
        )

        val state = events.fold(projection.initial()) { s, e -> projection.apply(s, e) }

        assertEquals("auth", state.projectId)
        assertEquals(2, state.count)
    }
}
