//! `pic kv ls | get` — read-only KV inspection (G2).
//!
//! Wraps the read-only `/api/v1/admin/apps/{id}/kv*` surface. There is no
//! `set`/`rm` on purpose: KV writes go through `kv::set` in scripts (which
//! emit the change events triggers depend on); an admin write would bypass
//! that, so the CLI stays read-only (matching the queues precedent).

use std::io::Write;

use anyhow::Result;

use crate::client::Client;
use crate::config;
use crate::output::{OutputMode, Table};

pub async fn ls(
    app: Option<&str>,
    group: Option<&str>,
    collection: &str,
    limit: u32,
    mode: OutputMode,
) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let page = match crate::cmds::require_one_owner(app, group)? {
        crate::cmds::OwnerRef::App(a) => client.kv_list(a, collection, limit).await?,
        // §11.6 M4: a group's shared-KV collection.
        crate::cmds::OwnerRef::Group(g) => client.group_kv_list(g, collection, limit).await?,
    };
    let mut table = Table::new(["key"]);
    for k in page.keys {
        table.row([k]);
    }
    table.print(mode);
    if page.next_cursor.is_some() {
        let _ = writeln!(
            std::io::stderr(),
            "(more keys available — raise --limit to see them)"
        );
    }
    Ok(())
}

pub async fn get(
    app: Option<&str>,
    group: Option<&str>,
    collection: &str,
    key: &str,
) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let value = match crate::cmds::require_one_owner(app, group)? {
        crate::cmds::OwnerRef::App(a) => client.kv_get(a, collection, key).await?,
        crate::cmds::OwnerRef::Group(g) => client.group_kv_get(g, collection, key).await?,
    };
    // Always emit the JSON value (pretty) so it pipes cleanly into jq.
    let pretty = serde_json::to_string_pretty(&value).unwrap_or_else(|_| value.to_string());
    println!("{pretty}");
    Ok(())
}
