use axum::{
    extract::{Path, State},
    http::StatusCode,
    response::Json,
};
use ontoref_derive::onto_api;
use provisioning_orchestrator::{
    batch::{BatchOperationRequest, BatchOperationResult},
    workflow::WorkflowExecutionState,
    SharedState,
};
use tracing::error;

use super::ApiResponse;

#[onto_api(
    method = "POST",
    path = "/batch/execute",
    description = "Execute a batch operation",
    auth = "bearer",
    actors = "developer, agent",
    tags = "batch",
    feature = ""
)]
pub async fn execute_batch_operation(
    State(state): State<SharedState>,
    Json(request): Json<BatchOperationRequest>,
) -> Result<Json<ApiResponse<BatchOperationResult>>, StatusCode> {
    match state
        .batch_coordinator
        .execute_batch_operation(request)
        .await
    {
        Ok(result) => Ok(Json(ApiResponse::success(result))),
        Err(e) => {
            error!("Failed to execute batch operation: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

#[onto_api(
    method = "GET",
    path = "/batch/operations/{id}",
    description = "Get batch operation status",
    auth = "bearer",
    actors = "developer, agent",
    tags = "batch",
    feature = ""
)]
pub async fn get_batch_operation_status(
    State(state): State<SharedState>,
    Path(operation_id): Path<String>,
) -> Result<Json<ApiResponse<WorkflowExecutionState>>, StatusCode> {
    match state
        .batch_coordinator
        .get_operation_status(&operation_id)
        .await
    {
        Some(state) => Ok(Json(ApiResponse::success(state))),
        None => Err(StatusCode::NOT_FOUND),
    }
}

#[onto_api(
    method = "GET",
    path = "/batch/operations",
    description = "List all batch operations",
    auth = "bearer",
    actors = "developer, agent",
    tags = "batch",
    feature = ""
)]
pub async fn list_batch_operations(
    State(state): State<SharedState>,
) -> Result<Json<ApiResponse<Vec<WorkflowExecutionState>>>, StatusCode> {
    let operations = state.batch_coordinator.list_operations().await;
    Ok(Json(ApiResponse::success(operations)))
}

#[onto_api(
    method = "POST",
    path = "/batch/operations/{id}/cancel",
    description = "Cancel a batch operation",
    auth = "bearer",
    actors = "developer, agent",
    tags = "batch",
    feature = ""
)]
pub async fn cancel_batch_operation(
    State(state): State<SharedState>,
    Path(operation_id): Path<String>,
) -> Result<Json<ApiResponse<String>>, StatusCode> {
    match state
        .batch_coordinator
        .cancel_operation(&operation_id)
        .await
    {
        Ok(_) => Ok(Json(ApiResponse::success(format!(
            "Operation {} cancelled",
            operation_id
        )))),
        Err(e) => {
            error!("Failed to cancel operation {}: {}", operation_id, e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}
