use clap::{Arg, ArgMatches, Command};
use std::path::Path;

use crate::cmd::resolve_db_path;

pub fn command() -> Command {
    Command::new("settings")
        .about("Show key/value settings stored in the local SQLite database")
        .long_about(
            "Read and display all rows from the `settings` table of the local \
             commonmeta SQLite database. Settings record installed vocabulary \
             versions and bulk-import dates.\n\n\
             Examples:\n\n\
             commonmeta settings\n\
             commonmeta settings --file /data/commonmeta.sqlite3\n\
             commonmeta settings --people-db /data/people.sqlite3",
        )
        .arg(
            Arg::new("file")
                .long("file")
                .help("Path to the works SQLite database (overrides COMMONMETA_DB and platform default)"),
        )
        .arg(
            Arg::new("people-db")
                .long("people-db")
                .help("Path to the people SQLite database (shows ORCID Public Data File version)"),
        )
}

pub fn execute(matches: &ArgMatches) -> Result<(), String> {
    let db_path_str = resolve_db_path(matches.get_one::<String>("file"));
    let db_path = Path::new(&db_path_str);

    print_settings_table(db_path, &db_path_str)?;

    if let Some(people_str) = matches.get_one::<String>("people-db") {
        let people_path = Path::new(people_str);
        if people_path != db_path {
            println!();
            print_settings_table(people_path, people_str)?;
        }
    }

    Ok(())
}

fn print_settings_table(path: &Path, label: &str) -> Result<(), String> {
    if !path.exists() {
        return Err(format!("database not found at '{}'", label));
    }

    let rows = commonmeta::get_all_sqlite_settings(path).map_err(|e| e.to_string())?;

    println!("{}:", label);
    if rows.is_empty() {
        println!("  (no settings)");
        return Ok(());
    }

    let key_width = rows.iter().map(|(k, _)| k.len()).max().unwrap_or(0);
    for (key, value) in &rows {
        println!("  {:<width$}  {}", key, value, width = key_width);
    }
    Ok(())
}
