use crate::app::AppState;
use crate::context::RequestContext;
use crate::error::WebError;
use axum::extract::{Extension, State};
use axum::http::StatusCode;
use axum::Json;
use bridge_runtime::{
    build_failure_response, build_success_response, execute_runtime_input, execute_runtime_query,
    runtime_input_requests_result, RuntimeInput,
};
use serde::Serialize;
use serde_json::{json, Value};

#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct HermesHealthResponse {
    pub ok: bool,
    pub service: String,
    pub bridge: &'static str,
    pub request_id: String,
    pub trace_id: String,
}

pub async fn health(
    State(state): State<AppState>,
    Extension(context): Extension<RequestContext>,
) -> Json<HermesHealthResponse> {
    Json(HermesHealthResponse {
        ok: true,
        service: state.config().service_name.clone(),
        bridge: "hermes",
        request_id: context.trace.request_id,
        trace_id: context.trace.trace_id,
    })
}

pub async fn bridge_runtime(
    Extension(context): Extension<RequestContext>,
    Json(runtime_input): Json<RuntimeInput>,
) -> Result<(StatusCode, Json<Value>), WebError> {
    let payload = if runtime_input_requests_result(&runtime_input) {
        match execute_runtime_query(runtime_input) {
            Ok(result) => json!({
                "ok": true,
                "bridge": "hermes_runtime_result",
                "requestId": context.trace.request_id,
                "traceId": context.trace.trace_id,
                "result": result,
            }),
            Err(error) => {
                let failure = build_failure_response(error);
                return Ok((
                    StatusCode::BAD_REQUEST,
                    Json(serde_json::to_value(failure).expect("runtime failure 应可序列化")),
                ));
            }
        }
    } else {
        match execute_runtime_input(runtime_input) {
            Ok(plan) => {
                let success = build_success_response(plan);
                json!({
                    "ok": success.ok,
                    "bridge": "hermes_runtime_plan",
                    "requestId": context.trace.request_id,
                    "traceId": context.trace.trace_id,
                    "plan": success.plan,
                })
            }
            Err(error) => {
                let failure = build_failure_response(error);
                return Ok((
                    StatusCode::BAD_REQUEST,
                    Json(serde_json::to_value(failure).expect("runtime failure 应可序列化")),
                ));
            }
        }
    };

    Ok((StatusCode::OK, Json(payload)))
}
