//! `pic topics {ls,create,update,rm}` — manage the pub/sub topic
//! registry that controls external SSE subscribability.
//!
//! Note the distinction from `pic triggers create-from-json --kind pubsub`:
//! a *pubsub trigger* runs a script when a message is published; a *topic*
//! (here) is the registry row that lets an outside client subscribe to a
//! topic over SSE (`/realtime/topics/{name}`). Publishing from a script
//! needs neither — only external subscribers need the topic registered.

use anyhow::Result;

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

pub async fn ls(app: &str, mode: OutputMode) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let topics = client.topics_list(app).await?;
    let mut table = Table::new([
        "name",
        "external_subscribable",
        "auth_mode",
        "created_at",
        "updated_at",
    ]);
    for t in topics {
        table.row([
            t.name.clone(),
            t.external_subscribable.to_string(),
            t.auth_mode.clone(),
            t.created_at.to_rfc3339(),
            t.updated_at.to_rfc3339(),
        ]);
    }
    table.print(mode);
    Ok(())
}

pub async fn create(
    app: &str,
    name: &str,
    external: bool,
    auth_mode: &str,
    mode: OutputMode,
) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let t = client.topics_create(app, name, external, auth_mode).await?;
    print_topic(&t, mode);
    Ok(())
}

pub async fn update(
    app: &str,
    name: &str,
    external: Option<bool>,
    auth_mode: Option<&str>,
    mode: OutputMode,
) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let t = client.topics_update(app, name, external, auth_mode).await?;
    print_topic(&t, mode);
    Ok(())
}

pub async fn rm(app: &str, name: &str) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    client.topics_delete(app, name).await?;
    println!("Deleted topic {name}");
    Ok(())
}

fn print_topic(t: &TopicDto, mode: OutputMode) {
    let mut block = KvBlock::new();
    block
        .field("name", t.name.clone())
        .field("external_subscribable", t.external_subscribable.to_string())
        .field("auth_mode", t.auth_mode.clone())
        .field("created_at", t.created_at.to_rfc3339())
        .field("updated_at", t.updated_at.to_rfc3339());
    block.print(mode);
}
