use anyhow::anyhow;
use clap::Parser;
use dialtone_common::utils::make_acct::make_acct;
use validator::Validate;

use dialtone_common::utils::version::DT_VERSION;
use dialtone_sqlx::constants::HOST_NAME_RE;
use dialtone_sqlx::constants::USER_NAME_RE;
use dialtone_sqlx::db::get_pooled_connection;
use dialtone_sqlx::db::user_principal::fetch_info::fetch_user_info;

/// Fetch users information.
#[derive(Parser, Debug, Validate)]
#[clap(name = "fetch_user", version = DT_VERSION)]
struct Opts {
    /// Users names (i.e. the local part of users@thefoo.example)
    #[clap(value_parser, short, long)]
    #[validate(regex = "USER_NAME_RE")]
    user_name: String,

    /// DNS host names of the sites (e.g. thefoo.example)
    #[clap(value_parser, short, long)]
    #[validate(regex = "HOST_NAME_RE")]
    host_name: String,
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    dotenv::dotenv().ok();
    let opts: Opts = Opts::parse();
    let acct = make_acct(&opts.user_name, &opts.host_name);
    println!("Fetching users {}.", &acct);

    let pg_pool = get_pooled_connection().await?;
    let web_user = fetch_user_info(&pg_pool, &acct)
        .await?
        .ok_or(anyhow!(format!("Cannot find users {}", &acct)))?;

    println!("\nUser Authorization:");
    println!(
        "{}",
        serde_json::to_string_pretty(&web_user.user_authz).unwrap()
    );

    println!("\nUser Status:");
    println!("{}", &web_user.status);

    println!("\n");
    println!("User Created      : {}", &web_user.created_at);
    println!("User Last Modified: {}", &web_user.modified_at);

    match web_user.preferences {
        None => {
            println!("\nNo users preferences.");
        }
        Some(user_prefs) => {
            println!("\nUser Preferences:");
            println!("{}", serde_json::to_string_pretty(&user_prefs).unwrap());
        }
    }

    println!("\nUser Last Login Data:");
    println!(
        "{}",
        serde_json::to_string_pretty(&web_user.last_login_data).unwrap()
    );

    println!("\nUser Last Seen Data:");
    println!(
        "{}",
        serde_json::to_string_pretty(&web_user.last_seen_data).unwrap()
    );

    Ok(())
}
