use std::sync::Arc;

use axum::{
    extract::State,
    routing::{get, post, put},
    Json, Router,
};

use crate::db;
use crate::middleware::auth::AuthUser;
use crate::models::error::{ApiError, ApiResult};
use crate::AppState;

pub fn router() -> Router<Arc<AppState>> {
    Router::new()
        .route("/", get(get_server_overview))
        .route("/connection", get(get_connection))
        .route("/config", get(get_config))
        .route("/config", put(update_config))
        .route("/command", post(send_command))
        .route("/admins", get(get_admins))
        .route("/start", post(start_server))
        .route("/stop", post(stop_server))
        .route("/restart", post(restart_server))
}

/// GET /api/servers — returns combined server overview (connection + config)
async fn get_server_overview(
    auth: AuthUser,
    State(state): State<Arc<AppState>>,
) -> ApiResult<Json<serde_json::Value>> {
    let license_id = auth.license_id.ok_or(ApiError::LicenseInvalid)?;

    let connection = db::servers::get_server_connection(&state.db, license_id)
        .await
        .map_err(|e| ApiError::Internal(e.to_string()))?;

    let config = db::servers::get_server_config(&state.db, license_id)
        .await
        .map_err(|e| ApiError::Internal(e.to_string()))?;

    Ok(Json(serde_json::json!({
        "connection": connection,
        "config": config,
    })))
}

/// GET /api/servers/connection
async fn get_connection(
    auth: AuthUser,
    State(state): State<Arc<AppState>>,
) -> ApiResult<Json<serde_json::Value>> {
    let license_id = auth.license_id.ok_or(ApiError::LicenseInvalid)?;

    let connection = db::servers::get_server_connection(&state.db, license_id)
        .await
        .map_err(|e| ApiError::Internal(e.to_string()))?;

    Ok(Json(serde_json::json!({ "connection": connection })))
}

/// GET /api/servers/config
async fn get_config(
    auth: AuthUser,
    State(state): State<Arc<AppState>>,
) -> ApiResult<Json<serde_json::Value>> {
    let license_id = auth.license_id.ok_or(ApiError::LicenseInvalid)?;

    let config = db::servers::get_server_config(&state.db, license_id)
        .await
        .map_err(|e| ApiError::Internal(e.to_string()))?;

    Ok(Json(serde_json::json!({ "config": config })))
}

#[derive(serde::Deserialize)]
struct UpdateConfigRequest {
    server_name: Option<String>,
    max_players: Option<i32>,
    world_size: Option<i32>,
    current_seed: Option<i32>,
}

/// PUT /api/servers/config
async fn update_config(
    auth: AuthUser,
    State(state): State<Arc<AppState>>,
    Json(body): Json<UpdateConfigRequest>,
) -> ApiResult<Json<serde_json::Value>> {
    let license_id = auth.license_id.ok_or(ApiError::LicenseInvalid)?;

    db::servers::update_server_config(
        &state.db,
        license_id,
        body.server_name.as_deref(),
        body.max_players,
        body.world_size,
        body.current_seed,
    )
    .await
    .map_err(|e| ApiError::Internal(e.to_string()))?;

    Ok(Json(serde_json::json!({ "message": "Config updated" })))
}

/// GET /api/servers/admins
async fn get_admins(
    auth: AuthUser,
    State(state): State<Arc<AppState>>,
) -> ApiResult<Json<serde_json::Value>> {
    let license_id = auth.license_id.ok_or(ApiError::LicenseInvalid)?;

    let admins = db::servers::get_game_admins(&state.db, license_id)
        .await
        .map_err(|e| ApiError::Internal(e.to_string()))?;

    Ok(Json(serde_json::json!({ "admins": admins })))
}

/// POST /api/servers/command
async fn send_command(
    _auth: AuthUser,
    State(_state): State<Arc<AppState>>,
) -> ApiResult<Json<serde_json::Value>> {
    // TODO: Route command through PanelAdapter or NATS to game server
    Err(ApiError::BadRequest("Server command not yet implemented".to_string()))
}

/// POST /api/servers/start
async fn start_server(
    _auth: AuthUser,
    State(_state): State<Arc<AppState>>,
) -> ApiResult<Json<serde_json::Value>> {
    // TODO: Route through PanelAdapter
    Err(ApiError::BadRequest("Server start not yet implemented".to_string()))
}

/// POST /api/servers/stop
async fn stop_server(
    _auth: AuthUser,
    State(_state): State<Arc<AppState>>,
) -> ApiResult<Json<serde_json::Value>> {
    // TODO: Route through PanelAdapter
    Err(ApiError::BadRequest("Server stop not yet implemented".to_string()))
}

/// POST /api/servers/restart
async fn restart_server(
    _auth: AuthUser,
    State(_state): State<Arc<AppState>>,
) -> ApiResult<Json<serde_json::Value>> {
    // TODO: Route through PanelAdapter
    Err(ApiError::BadRequest("Server restart not yet implemented".to_string()))
}
