package com.correx.apps.cli.commands

import com.correx.apps.cli.CorrexCli
import com.correx.apps.cli.DEFAULT_PORT
import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.arguments.argument
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.required
import io.ktor.client.HttpClient
import io.ktor.client.engine.cio.CIO
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.http.ContentType
import io.ktor.http.contentType
import io.ktor.serialization.kotlinx.json.json
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json

@Serializable
private data class ApprovalRequest(
    val decision: String,
    val steeringNote: String?,
)

class ApproveCommand : CliktCommand(name = "approve") {
    private val sessionId by argument("SESSION_ID")
    private val decision by option("--decision", help = "approve | reject | steer").required()
    private val note by option("--note", help = "Steering note")
    private val host by option("--host").default("localhost")
    private val port by option("--port").default("$DEFAULT_PORT")

    private val approveJson = Json { ignoreUnknownKeys = true }

    override fun run(): Unit = runBlocking {
        val portInt = port.toIntOrNull() ?: DEFAULT_PORT
        val outputJson = (currentContext.findRoot().command as? CorrexCli)?.json ?: false

        val decisionUpper = decision.uppercase()
        if (decisionUpper !in setOf("APPROVE", "REJECT", "STEER")) {
            System.err.println("Invalid decision: $decision. Must be approve, reject, or steer.")
            return@runBlocking
        }

        val client = HttpClient(CIO) {
            install(ContentNegotiation) { json(approveJson) }
        }

        runCatching {
            client.post("http://$host:$portInt/sessions/$sessionId/approve") {
                contentType(ContentType.Application.Json)
                setBody(ApprovalRequest(decision = decisionUpper, steeringNote = note))
            }
            if (outputJson) {
                println("{\"sessionId\": \"$sessionId\", \"decision\": \"$decisionUpper\"}")
            } else {
                println("Approval decision '$decisionUpper' sent for session $sessionId.")
            }
        }.getOrElse { e ->
            System.err.println("Error sending approval: ${e.message}")
        }

        client.close()
    }
}
