use axum::{
    Json,
    extract::{Path, Query, State},
};
use serde_json::{Value, json};

use crate::{
    error::ApiError,
    routes::access::WorkspacePath,
    service::{LogsQuery, UsageRequestQuery},
    state::AppState,
};

#[derive(serde::Deserialize)]
pub struct WorkspaceLogPath {
    pub workspace_id: String,
    pub log_id: String,
}

#[derive(serde::Deserialize)]
pub struct WorkspaceOperationUsagePath {
    pub workspace_id: String,
    pub operation_id: String,
}

#[derive(serde::Deserialize)]
pub struct WorkspaceAgentUsagePath {
    pub workspace_id: String,
    pub agent_id: String,
}

pub async fn list_logs(
    Path(path): Path<WorkspacePath>,
    Query(query): Query<LogsQuery>,
    State(state): State<AppState>,
) -> Result<Json<Value>, ApiError> {
    let items = state
        .service
        .list_logs(&path.workspace_id.as_str().into(), query)
        .await?;
    Ok(Json(json!({ "items": items })))
}

pub async fn get_log(
    Path(path): Path<WorkspaceLogPath>,
    State(state): State<AppState>,
) -> Result<Json<Value>, ApiError> {
    let item = state
        .service
        .get_log(
            &path.workspace_id.as_str().into(),
            &path.log_id.as_str().into(),
        )
        .await?;
    Ok(Json(json!(item)))
}

pub async fn get_usage(
    Path(path): Path<WorkspacePath>,
    Query(query): Query<UsageRequestQuery>,
    State(state): State<AppState>,
) -> Result<Json<Value>, ApiError> {
    let usage = state
        .service
        .get_usage_overview(&path.workspace_id.as_str().into(), query)
        .await?;
    Ok(Json(json!(usage)))
}

pub async fn get_operation_usage(
    Path(path): Path<WorkspaceOperationUsagePath>,
    Query(query): Query<UsageRequestQuery>,
    State(state): State<AppState>,
) -> Result<Json<Value>, ApiError> {
    let usage = state
        .service
        .get_operation_usage(
            &path.workspace_id.as_str().into(),
            &path.operation_id.as_str().into(),
            query,
        )
        .await?;
    Ok(Json(json!(usage)))
}

pub async fn get_agent_usage(
    Path(path): Path<WorkspaceAgentUsagePath>,
    Query(query): Query<UsageRequestQuery>,
    State(state): State<AppState>,
) -> Result<Json<Value>, ApiError> {
    let usage = state
        .service
        .get_agent_usage(
            &path.workspace_id.as_str().into(),
            &path.agent_id.as_str().into(),
            query,
        )
        .await?;
    Ok(Json(json!(usage)))
}
