use std::sync::Arc;

use axum::{
    extract::{Path, Query, Request, State},
    response::Json,
};
use serde::Deserialize;
use uuid::Uuid;

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

/// Create role endpoint (admin only)
pub async fn create_role(
    State(app_state): State<Arc<AppState>>,
    Json(create_request): Json<CreateRoleRequest>,
    request: Request,
) -> Result<Json<ApiResponse<RoleResponse>>> {
    let user_context = request.require_user_context()?;

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

    let role = app_state.role_service.create_role(create_request).await?;

    Ok(Json(ApiResponse::success_with_message(
        role,
        "Role created successfully".to_string(),
    )))
}

/// Get role by ID
pub async fn get_role_by_id(
    State(app_state): State<Arc<AppState>>,
    Path(role_id): Path<Uuid>,
    request: Request,
) -> Result<Json<ApiResponse<RoleResponse>>> {
    let user_context = request.require_user_context()?;

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

    let role = app_state
        .role_service
        .get_role_response_by_id(role_id)
        .await?;

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

/// List roles
pub async fn list_roles(
    State(app_state): State<Arc<AppState>>,
    Query(params): Query<ListRolesParams>,
    request: Request,
) -> Result<Json<ApiResponse<Vec<RoleResponse>>>> {
    let user_context = request.require_user_context()?;

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

    let roles = app_state
        .role_service
        .list_roles(params.include_system, params.limit, params.offset)
        .await?;

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

/// Update role (admin only)
pub async fn update_role(
    State(app_state): State<Arc<AppState>>,
    Path(role_id): Path<Uuid>,
    Json(update_request): Json<UpdateRoleRequest>,
    request: Request,
) -> Result<Json<ApiResponse<RoleResponse>>> {
    let user_context = request.require_user_context()?;

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

    let role = app_state
        .role_service
        .update_role(role_id, update_request)
        .await?;

    Ok(Json(ApiResponse::success_with_message(
        role,
        "Role updated successfully".to_string(),
    )))
}

/// Delete role (admin only)
pub async fn delete_role(
    State(app_state): State<Arc<AppState>>,
    Path(role_id): Path<Uuid>,
    request: Request,
) -> Result<Json<ApiResponse<String>>> {
    let user_context = request.require_user_context()?;

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

    app_state.role_service.delete_role(role_id).await?;

    Ok(Json(ApiResponse::success(
        "Role deleted successfully".to_string(),
    )))
}

#[derive(Debug, Deserialize)]
pub struct ListRolesParams {
    pub include_system: Option<bool>,
    pub limit: Option<usize>,
    pub offset: Option<usize>,
}
