//! `pic workflows` subcommands (v1.2 Workflows M5).
//!
//! Read-only listing + starting/inspecting runs. Workflow *definitions* are
//! authored declaratively (`[[workflows]]` in `picloud.toml` → `pic apply`);
//! this surface starts runs and reads run history.

use anyhow::{Context, Result};
use serde_json::Value;

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

/// `pic workflows ls --app <a>` — the app's workflow definitions.
pub async fn ls(app: &str, mode: OutputMode) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let workflows = client.workflows_list(app).await?;
    let mut table = Table::new(["name", "enabled", "steps"]);
    for w in workflows {
        table.row([w.name, w.enabled.to_string(), w.steps.to_string()]);
    }
    table.print(mode);
    Ok(())
}

/// `pic workflows run <name> --app <a> [--input JSON]` — start a run.
pub async fn run(app: &str, name: &str, input: Option<&str>, mode: OutputMode) -> Result<()> {
    let input_json: Value = match input {
        Some(s) => serde_json::from_str(s)
            .context("--input must be valid JSON (e.g. '{\"date\":\"2026-07-12\"}')")?,
        None => Value::Null,
    };
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let run = client.workflow_run_start(app, name, input_json).await?;
    KvBlock::new()
        .field("run_id", run.id)
        .field("status", run.status)
        .print(mode);
    Ok(())
}

/// `pic workflows runs <name> --app <a>` — recent runs of a workflow.
pub async fn runs(app: &str, name: &str, mode: OutputMode) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let runs = client.workflow_runs_list(app, name).await?;
    let mut table = Table::new(["run_id", "status", "depth", "created_at"]);
    for r in runs {
        table.row([r.id, r.status, r.workflow_depth.to_string(), r.created_at]);
    }
    table.print(mode);
    Ok(())
}

/// `pic workflows run-status <run_id> --app <a>` — one run + its steps.
pub async fn run_status(app: &str, run_id: &str, mode: OutputMode) -> Result<()> {
    let creds = config::resolve()?;
    let client = Client::from_creds(&creds)?;
    let detail = client.workflow_run_status(app, run_id).await?;
    KvBlock::new()
        .field("run_id", detail.run.id)
        .field("status", detail.run.status)
        .field("error", detail.run.error.unwrap_or_default())
        .print(mode);
    let mut table = Table::new(["step", "status", "attempt", "error", "child_run"]);
    for s in detail.steps {
        table.row([
            s.name,
            s.status,
            format!("{}/{}", s.attempt, s.max_attempts),
            s.error.unwrap_or_default(),
            s.child_run_id.unwrap_or_default(),
        ]);
    }
    table.print(mode);
    Ok(())
}
