//! `GET /api/peers` — paginated peer list for the Group tab in the desktop
//! client. Flutter decoder at flutter/lib/common/hbbs/hbbs.dart:77 expects
//! `{ id, user, user_name, device_group_name, note, status, info: {...} }`
//! per row.

use crate::api::error::ApiError;
use crate::api::middleware::AuthedUser;
use crate::api::pagination::{Page, PageQuery};
use crate::api::state::AppState;
use axum::extract::{Extension, Query};
use axum::Json;
use serde::Serialize;
use serde_json::{json, Value};
use std::sync::Arc;

#[derive(Debug, Serialize)]
pub struct PeerOut {
    pub id: String,
    pub user: String,
    pub user_name: String,
    pub device_group_name: String,
    pub note: String,
    pub status: i64,
    pub info: Value,
}

pub async fn list(
    Extension(state): Extension<Arc<AppState>>,
    user: AuthedUser,
    Query(q): Query<PageQuery>,
) -> Result<Json<Page<PeerOut>>, ApiError> {
    let (total, rows) = state
        .db
        .peers_list_accessible(user.user_id, user.is_admin, q.offset(), q.limit())
        .await
        .map_err(|e| ApiError::Internal(e.to_string()))?;
    let data: Vec<PeerOut> = rows
        .into_iter()
        .map(|r| {
            // Trim the full sysinfo blob to what the client actually reads.
            let parsed: Value = serde_json::from_str(&r.sysinfo_payload).unwrap_or(Value::Null);
            let pick = |k: &str| -> String {
                parsed
                    .get(k)
                    .and_then(|v| v.as_str())
                    .unwrap_or_default()
                    .to_string()
            };
            let info = json!({
                "username":    pick("username"),
                "device_name": pick("hostname"),
                "os":          pick("os"),
            });
            PeerOut {
                id: r.id,
                user: r.owner_username,
                user_name: r.owner_display_name,
                device_group_name: r.device_group_name,
                note: r.note,
                status: r.status,
                info,
            }
        })
        .collect();
    Ok(Json(Page { total, data }))
}
