use rouille::{input::json_input, Request, Response};
use serde_json::json;
use std::sync::Arc;

use super::helpers::{get_conn, json_error, require_auth};
use super::AppState;

pub fn get_health(_request: &Request, state: &Arc<AppState>) -> Response {
    let _conn = match get_conn(state) {
        Ok(c) => c,
        Err(e) => return e,
    };
    let healthy = state.pool.state().connections > 0;
    Response::json(&json!({
        "status": "healthy",
        "database": { "status": "connected", "healthy": healthy }
    }))
}

pub fn get_config(request: &Request, state: &Arc<AppState>) -> Response {
    let mut conn = match get_conn(state) {
        Ok(c) => c,
        Err(e) => return e,
    };
    if let Err(e) = require_auth(request, &mut conn) {
        return e;
    }

    match conn.query("SELECT key, value::text FROM config ORDER BY key", &[]) {
        Ok(rows) => {
            let config: std::collections::HashMap<String, serde_json::Value> = rows
                .into_iter()
                .map(|row| {
                    let key: String = row.get(0);
                    let value: String = row.get(1);
                    (key, serde_json::from_str(&value).unwrap_or(serde_json::Value::Null))
                })
                .collect();
            Response::json(&json!({ "config": config }))
        }
        Err(_) => json_error(500, "Database error"),
    }
}

pub fn put_config(request: &Request, state: &Arc<AppState>) -> Response {
    let mut conn = match get_conn(state) {
        Ok(c) => c,
        Err(e) => return e,
    };
    if let Err(e) = require_auth(request, &mut conn) {
        return e;
    }

    let form: sap_sync_backend::models::ConfigUpdate = match json_input(request) {
        Ok(f) => f,
        Err(_) => return json_error(400, "Invalid JSON"),
    };

    let _ = conn.execute(
        "INSERT INTO config (key, value) VALUES ($1, $2::text::jsonb) \
         ON CONFLICT (key) DO UPDATE SET value = $2::text::jsonb",
        &[&form.key, &serde_json::to_string(&form.value).unwrap_or_default()],
    );
    Response::json(&json!({"message": "Config updated"}))
}
