package com.correx.core.tasks

import com.correx.core.events.types.TaskId
import com.correx.core.events.types.TaskNoteAuthor
import kotlinx.datetime.Instant
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

class TaskSearchTest {

    private fun task(
        id: String,
        title: String?,
        goal: String? = null,
        criteria: List<String> = emptyList(),
        notes: List<String> = emptyList(),
    ) = Task(
        TaskId(id),
        TaskState(
            key = id,
            title = title,
            goal = goal,
            acceptanceCriteria = criteria,
            notes = notes.map { TaskNote(TaskNoteAuthor.AGENT, it, Instant.parse("2026-01-01T00:00:00Z")) },
        ),
    )

    @Test
    fun `requires all terms and ranks title hits above body hits`() {
        val titleHit = task("auth-1", title = "JWT refresh flow", goal = "stay authed")
        val goalHit = task("auth-2", title = "Token rotation", goal = "rotate the jwt refresh token")
        val noMatch = task("auth-3", title = "Logging", goal = "structured logs")

        val results = TaskSearch.search(listOf(goalHit, noMatch, titleHit), "jwt refresh")

        assertEquals(listOf("auth-1", "auth-2"), results.map { it.taskId.value })
    }

    @Test
    fun `matches across acceptance criteria and notes`() {
        val viaNotes = task("auth-1", title = "x", notes = listOf("the migration failed on rollback"))
        val viaCriteria = task("auth-2", title = "y", criteria = listOf("rollback is idempotent"))

        val results = TaskSearch.search(listOf(viaNotes, viaCriteria), "rollback")

        assertEquals(setOf("auth-1", "auth-2"), results.map { it.taskId.value }.toSet())
    }

    @Test
    fun `blank query returns the input unchanged`() {
        val tasks = listOf(task("auth-1", "a"), task("auth-2", "b"))
        assertEquals(tasks, TaskSearch.search(tasks, "   "))
    }

    @Test
    fun `no match yields empty`() {
        assertEquals(emptyList<Task>(), TaskSearch.search(listOf(task("auth-1", "nothing here")), "zebra"))
    }
}
