package com.correx.core.tasks

import com.correx.core.events.events.StoredEvent
import com.correx.core.events.events.TaskAcceptanceCriteriaSetEvent
import com.correx.core.events.events.TaskAffectedPathsSetEvent
import com.correx.core.events.events.TaskBlockedEvent
import com.correx.core.events.events.TaskCancelledEvent
import com.correx.core.events.events.TaskClaimedEvent
import com.correx.core.events.events.TaskCompletedEvent
import com.correx.core.events.events.TaskCreatedEvent
import com.correx.core.events.events.TaskDeletedEvent
import com.correx.core.events.events.TaskEditedEvent
import com.correx.core.events.events.TaskEvent
import com.correx.core.events.events.TaskLinkedEvent
import com.correx.core.events.events.TaskNoteAddedEvent
import com.correx.core.events.events.TaskReleasedEvent
import com.correx.core.events.events.TaskReopenedEvent
import com.correx.core.events.events.TaskSubmittedForReviewEvent
import com.correx.core.events.events.TaskUnblockedEvent
import com.correx.core.events.events.TaskUnlinkedEvent

/**
 * Renders a task's event log as a human-readable lifecycle timeline. The log is the source of
 * truth, so this is the audit trail straight from the facts — one line per event, in order,
 * `<timestamp>  <what happened>`. Useful for seeing what an agent actually did to a task
 * (claim/submit/complete, notes, links, git-driven status) rather than just its current state.
 */
object TaskHistory {

    fun render(events: List<StoredEvent>): String {
        val lines = events.mapNotNull { e ->
            val payload = e.payload as? TaskEvent ?: return@mapNotNull null
            "${e.metadata.timestamp}  ${describe(payload)}"
        }
        return if (lines.isEmpty()) "no history" else lines.joinToString("\n")
    }

    private fun describe(p: TaskEvent): String =
        describeContent(p) ?: describeLifecycle(p) ?: (p::class.simpleName ?: "event")

    private fun describeContent(p: TaskEvent): String? = when (p) {
        is TaskCreatedEvent -> "created ${p.key}: ${p.title}"
        is TaskEditedEvent -> "edited"
        is TaskAcceptanceCriteriaSetEvent -> "acceptance criteria set (${p.criteria.size})"
        is TaskAffectedPathsSetEvent -> "affected paths set (${p.paths.size})"
        is TaskLinkedEvent -> "linked ${p.type} -> ${p.targetId} (${p.targetKind})"
        is TaskUnlinkedEvent -> "unlinked ${p.type} -> ${p.targetId}"
        is TaskNoteAddedEvent -> "note [${p.author}] ${p.body}"
        is TaskDeletedEvent -> "deleted"
        else -> null
    }

    private fun describeLifecycle(p: TaskEvent): String? = when (p) {
        is TaskClaimedEvent -> "claimed by ${p.claimant}"
        is TaskReleasedEvent -> "released"
        is TaskBlockedEvent -> "blocked: ${p.reason}"
        is TaskUnblockedEvent -> "unblocked"
        is TaskSubmittedForReviewEvent -> "submitted for review"
        is TaskCompletedEvent -> "completed"
        is TaskReopenedEvent -> "reopened"
        is TaskCancelledEvent -> "cancelled" + (p.reason?.let { ": $it" } ?: "")
        else -> null
    }
}
