use anyhow::Result;
use bpx_api_client::BpxClient;
use indicatif::{ProgressBar, ProgressStyle};
use std::time::Duration;

use crate::auth;
use crate::config::ResolvedConfig;

/// Creates an unauthenticated client for public endpoints.
pub fn public_client(config: &ResolvedConfig, base_url_flag: Option<&str>) -> Result<BpxClient> {
    let base_url = auth::resolve_base_url(base_url_flag, config);
    let client = BpxClient::builder()
        .base_url(base_url)
        .build()
        .map_err(|e| anyhow::anyhow!("{e}"))?;
    Ok(client)
}

/// Creates an authenticated client. Fails if no secret is available.
pub fn authenticated_client(
    config: &ResolvedConfig,
    secret_flag: Option<&str>,
    base_url_flag: Option<&str>,
) -> Result<BpxClient> {
    let secret = auth::resolve_secret(secret_flag, config)?;
    let base_url = auth::resolve_base_url(base_url_flag, config);
    let client = BpxClient::builder()
        .base_url(base_url)
        .secret(&secret)
        .build()
        .map_err(|e| anyhow::anyhow!("{e}"))?;
    Ok(client)
}

pub fn spinner_for(msg: &str, format: crate::output::OutputFormat) -> ProgressBar {
    if format == crate::output::OutputFormat::Json {
        return ProgressBar::hidden();
    }
    spinner(msg)
}

pub fn spinner(msg: &str) -> ProgressBar {
    let pb = ProgressBar::new_spinner();
    pb.set_style(
        ProgressStyle::default_spinner()
            .tick_strings(&["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"])
            .template("{spinner:.bright.cyan} {msg}")
            .expect("valid template"),
    );
    pb.set_message(msg.to_string());
    pb.enable_steady_tick(Duration::from_millis(80));
    pb
}
