use std::sync::Arc;

use axum::{
    extract::{Query, Request, State},
    response::Json,
};
use ontoref_derive::onto_api;
use serde::Deserialize;

use crate::error::{auth, http, ControlCenterError, Result};
use crate::handlers::auth::ApiResponse;
use crate::middleware::RequestExt;
use crate::models::PermissionResponse;
use crate::AppState;

/// List permissions
#[onto_api(
    method = "GET",
    path = "/permissions",
    description = "List all permissions",
    auth = "bearer",
    actors = "developer",
    tags = "permissions",
    feature = ""
)]
pub async fn list_permissions(
    State(app_state): State<Arc<AppState>>,
    Query(params): Query<ListPermissionsParams>,
) -> Result<Json<ApiResponse<Vec<PermissionResponse>>>> {
    // TODO: Add proper authentication middleware and permission checking
    // For now, we'll skip the permission check to get the service running

    let permissions = app_state
        .permission_service
        .list_permissions(params.resource, params.action, params.limit, params.offset)
        .await?;

    Ok(Json(ApiResponse::success(permissions)))
}

/// Get all resources
pub async fn get_resources(
    State(app_state): State<Arc<AppState>>,
    request: Request,
) -> Result<Json<ApiResponse<Vec<String>>>> {
    let user_context = request.require_user_context()?;

    if !user_context.has_permission("permissions:read") {
        return Err(ControlCenterError::Http(http::HttpError::BadRequest(
            "Permission required to read permissions".to_string(),
        )));
    }

    let resources = app_state.permission_service.get_resources().await?;

    Ok(Json(ApiResponse::success(resources)))
}

/// Get all actions
pub async fn get_actions(
    State(app_state): State<Arc<AppState>>,
    request: Request,
) -> Result<Json<ApiResponse<Vec<String>>>> {
    let user_context = request.require_user_context()?;

    if !user_context.has_permission("permissions:read") {
        return Err(ControlCenterError::Http(http::HttpError::BadRequest(
            "Permission required to read permissions".to_string(),
        )));
    }

    let actions = app_state.permission_service.get_actions().await?;

    Ok(Json(ApiResponse::success(actions)))
}

#[derive(Debug, Deserialize)]
pub struct ListPermissionsParams {
    pub resource: Option<String>,
    pub action: Option<String>,
    pub limit: Option<usize>,
    pub offset: Option<usize>,
}
