package com.correx.apps.server.routes

import com.correx.apps.server.ServerModule
import com.correx.apps.server.protocol.ApprovalDecision
import com.correx.apps.server.protocol.ClientMessage
import com.correx.apps.server.protocol.ServerMessage
import com.correx.core.events.types.SessionId
import com.correx.core.utils.TypeId
import io.ktor.http.HttpStatusCode
import io.ktor.server.request.receive
import io.ktor.server.response.respond
import io.ktor.server.routing.Route
import io.ktor.server.routing.post

// REST parity for stage approvals (WS already has ClientMessage.ApprovalResponse). Keyed by
// session — a session suspends on at most one approval at a time, so the pending requestId is
// resolved server-side and the caller need not know it. Lets a headless run (a script, `correx
// run`) clear an approval gate without a WebSocket. STEER attaches the note alongside an APPROVE.
internal fun Route.approveStageRoute(module: ServerModule) {
    post("/approve") {
        val id = call.parameters["id"]
        if (id == null) {
            call.respond(HttpStatusCode.BadRequest, "Missing session id")
            return@post
        }
        val body = call.receive<ApproveStageRequest>()
        val decision = when (body.decision.uppercase()) {
            "APPROVE", "STEER" -> ApprovalDecision.APPROVE
            "REJECT" -> ApprovalDecision.REJECT
            else -> null
        }
        if (decision == null) {
            call.respond(HttpStatusCode.BadRequest, "Invalid decision '${body.decision}'.")
            return@post
        }
        val sessionId: SessionId = TypeId(id)
        val requestId = module.approvalCoordinator.pendingRequestFor(sessionId)
        if (requestId == null) {
            call.respond(HttpStatusCode.NotFound, "No pending approval for session $id")
            return@post
        }
        val response = ClientMessage.ApprovalResponse(requestId, decision, body.steeringNote)
        val error = module.approvalCoordinator.handleResponse(response, sessionId)
        if (error is ServerMessage.ProtocolError) {
            call.respond(HttpStatusCode.Conflict, error.message)
        } else {
            call.respond(HttpStatusCode.OK)
        }
    }
}
