use async_nats::jetstream::{
    stream::{Config as StreamConfig, RetentionPolicy, StorageType},
    Context,
};
use tracing::info;

use crate::Error;

/// Provision all six JetStream streams required by the provisioning platform.
/// Idempotent — uses `get_or_create_stream` so safe to call on every startup.
pub async fn ensure_provisioning_streams(js: &Context) -> Result<(), Error> {
    let streams: &[(&str, &[&str], RetentionPolicy)] = &[
        (
            "TASKS",
            &["provisioning.tasks.>"],
            RetentionPolicy::WorkQueue,
        ),
        (
            "VAULT",
            &["provisioning.vault.>"],
            RetentionPolicy::Interest,
        ),
        ("AUTH", &["provisioning.auth.>"], RetentionPolicy::Interest),
        (
            "WORKSPACE",
            &["provisioning.workspace.>"],
            RetentionPolicy::Limits,
        ),
        ("AUDIT", &["provisioning.audit.>"], RetentionPolicy::Limits),
        (
            "HEALTH",
            &["provisioning.health.>"],
            RetentionPolicy::Interest,
        ),
    ];

    for (name, subjects, retention) in streams {
        let cfg = StreamConfig {
            name: name.to_string(),
            subjects: subjects.iter().map(|s| s.to_string()).collect(),
            retention: *retention,
            storage: StorageType::File,
            ..Default::default()
        };

        js.get_or_create_stream(cfg)
            .await
            .map_err(|e| Error::Stream(format!("failed to ensure stream {name}: {e}")))?;

        info!(stream = name, "JetStream stream ready");
    }

    Ok(())
}
