//! `pic users {ls,show,reset-password,revoke-sessions}` — admin view of
//! an app's *end-users* (people who registered via `users::create` in a
//! script), distinct from `pic admins` (instance control-plane accounts)
//! and app membership/collaborators.
//!
//! Scoped to read + the two admin actions the E2E report needed. Create,
//! delete, and invitations are deferred to a follow-up.

use anyhow::Result;

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

pub async fn ls(app: &str, limit: u32, mode: OutputMode) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let users = client.app_users_list(app, limit).await?;
    let mut table = Table::new(["id", "email", "display_name", "last_login_at", "created_at"]);
    for u in users {
        table.row([
            u.id.to_string(),
            u.email.clone(),
            u.display_name.clone().unwrap_or_else(|| "-".into()),
            u.last_login_at
                .map(|t| t.to_rfc3339())
                .unwrap_or_else(|| "-".into()),
            u.created_at.to_rfc3339(),
        ]);
    }
    table.print(mode);
    Ok(())
}

pub async fn show(app: &str, user_id: &str, mode: OutputMode) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let u = client.app_user_get(app, user_id).await?;
    let mut block = KvBlock::new();
    block
        .field("id", u.id.to_string())
        .field("email", u.email.clone())
        .field(
            "display_name",
            u.display_name.clone().unwrap_or_else(|| "-".into()),
        )
        .field(
            "email_verified_at",
            u.email_verified_at
                .map(|t| t.to_rfc3339())
                .unwrap_or_else(|| "-".into()),
        )
        .field(
            "last_login_at",
            u.last_login_at
                .map(|t| t.to_rfc3339())
                .unwrap_or_else(|| "-".into()),
        )
        .field(
            "roles",
            if u.roles.is_empty() {
                "-".into()
            } else {
                u.roles.join(",")
            },
        )
        .field("created_at", u.created_at.to_rfc3339())
        .field("updated_at", u.updated_at.to_rfc3339());
    block.print(mode);
    Ok(())
}

/// Mint a one-shot password-reset token for an end-user. The token is
/// returned exactly once — the admin pastes it into a manual reset link.
pub async fn reset_password(app: &str, user_id: &str, mode: OutputMode) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let resp = client.app_user_reset_password(app, user_id).await?;
    let mut block = KvBlock::new();
    block
        .field("token", resp.token.clone())
        .field("expires_in_seconds", resp.expires_in_seconds.to_string());
    block.print(mode);
    Ok(())
}

pub async fn revoke_sessions(app: &str, user_id: &str, mode: OutputMode) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let resp = client.app_user_revoke_sessions(app, user_id).await?;
    let mut block = KvBlock::new();
    block.field("revoked", resp.revoked.to_string());
    block.print(mode);
    Ok(())
}
