use std::sync::Arc;
use axum::Json;
use axum::extract::State;
use axum::response::Response;

use crate::state::AppState;

pub async fn well_known(
    State(state): State<Arc<AppState>>,
) -> Result<Json<serde_json::Value>, Response> {
    let ap = state.ap.as_ref().ok_or_else(|| {
        (axum::http::StatusCode::NOT_FOUND, "not found").into_response()
    })?;

    Ok(Json(serde_json::json!({
        "links": [{
            "rel": "http://nodeinfo/2.1",
            "href": format!("https://{}/nodeinfo/2.1", ap.domain),
        }]
    })))
}

use axum::response::IntoResponse;

pub async fn nodeinfo(
    State(state): State<Arc<AppState>>,
) -> Result<Json<serde_json::Value>, Response> {
    let ap = state.ap.as_ref().ok_or_else(|| {
        (axum::http::StatusCode::NOT_FOUND, "not found").into_response()
    })?;

    let dbi = state.db.lock().await;
    let users: i64 = dbi.db.query_row("SELECT COUNT(*) FROM sessions", [], |r| r.get(0)).unwrap_or(0);
    let puzzles: i64 = dbi.db.query_row("SELECT COUNT(*) FROM puzzles", [], |r| r.get(0)).unwrap_or(0);

    Ok(Json(serde_json::json!({
        "version": "2.1",
        "software": {
            "name": "cruciverb",
            "version": env!("CARGO_PKG_VERSION"),
            "repository": "https://git.lashman.live/lashman/cruciverb",
        },
        "protocols": ["activitypub"],
        "services": { "inbound": [], "outbound": ["atom1.0", "rss2.0"] },
        "openRegistrations": true,
        "usage": {
            "users": { "total": users },
            "localPosts": puzzles,
        },
        "metadata": {
            "nodeName": format!("cruciverb @ {}", ap.domain),
            "nodeDescription": "self-hosted crossword puzzles",
            "features": ["daily_puzzles", "community_clues", "puzzle_editor", "cryptic_mode"],
        },
    })))
}
