use axum::{
    extract::{Path, State},
    http::StatusCode,
    response::Json,
};
use ontoref_derive::onto_api;
use provisioning_orchestrator::{
    monitor::SystemHealthStatus,
    state::{ProgressInfo, StateManagerStatistics, StateSnapshot, SystemMetrics},
    SharedState,
};
use tracing::error;

use super::ApiResponse;

#[onto_api(
    method = "GET",
    path = "/state/workflows/{id}/progress",
    description = "Get workflow execution progress",
    auth = "bearer",
    actors = "developer, agent",
    tags = "state",
    feature = ""
)]
pub async fn get_workflow_progress(
    State(state): State<SharedState>,
    Path(workflow_id): Path<String>,
) -> Result<Json<ApiResponse<ProgressInfo>>, StatusCode> {
    match state
        .progress_tracker
        .get_real_time_progress(&workflow_id)
        .await
    {
        Some(progress) => Ok(Json(ApiResponse::success(progress))),
        None => Err(StatusCode::NOT_FOUND),
    }
}

#[onto_api(
    method = "GET",
    path = "/state/workflows/{id}/snapshots",
    description = "Get workflow state snapshots",
    auth = "bearer",
    actors = "developer, agent",
    tags = "state",
    feature = ""
)]
pub async fn get_workflow_snapshots(
    State(state): State<SharedState>,
    Path(workflow_id): Path<String>,
) -> Result<Json<ApiResponse<Vec<StateSnapshot>>>, StatusCode> {
    let snapshots = state
        .state_manager
        .get_workflow_snapshots(&workflow_id)
        .await;
    Ok(Json(ApiResponse::success(snapshots)))
}

#[onto_api(
    method = "GET",
    path = "/state/system/metrics",
    description = "Get system-level metrics",
    auth = "bearer",
    actors = "developer, agent, ci",
    tags = "state, metrics",
    feature = ""
)]
pub async fn get_system_metrics(
    State(state): State<SharedState>,
) -> Result<Json<ApiResponse<SystemMetrics>>, StatusCode> {
    let metrics = state.state_manager.get_system_metrics().await;
    Ok(Json(ApiResponse::success(metrics)))
}

#[onto_api(
    method = "GET",
    path = "/state/system/health",
    description = "Get system health status",
    auth = "none",
    actors = "developer, agent, ci",
    tags = "health, state",
    feature = ""
)]
pub async fn get_system_health(
    State(state): State<SharedState>,
) -> Result<Json<ApiResponse<SystemHealthStatus>>, StatusCode> {
    let health_status = state
        .monitoring_system
        .health_monitor()
        .get_system_health()
        .await;
    Ok(Json(ApiResponse::success(health_status)))
}

#[onto_api(
    method = "GET",
    path = "/state/statistics",
    description = "Get state manager statistics",
    auth = "bearer",
    actors = "developer, agent",
    tags = "state",
    feature = ""
)]
pub async fn get_state_statistics(
    State(state): State<SharedState>,
) -> Result<Json<ApiResponse<StateManagerStatistics>>, StatusCode> {
    match state.state_manager.get_statistics().await {
        Ok(stats) => Ok(Json(ApiResponse::success(stats))),
        Err(e) => {
            error!("Failed to get state statistics: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}
