use std::io::{self, Write};

use crate::api::ApiClient;
use crate::config::{Config, UserState};

pub fn login() -> crate::Result<()> {
    let config = Config::load();

    if let Some(ref token) = config.api_token {
        let mut api_client = ApiClient::new(&config)?;
        if api_client.is_signed_in() {
            println!("Already signed in via BIOLIB_TOKEN environment variable.");
            return Ok(());
        }
        api_client.sign_in_with_api_token(token)?;
        println!("Successfully signed in.");
        return Ok(());
    }

    print!("Email: ");
    io::stdout().flush()?;
    let mut email = String::new();
    io::stdin().read_line(&mut email)?;
    let email = email.trim();

    print!("Password: ");
    io::stdout().flush()?;
    let mut password = String::new();
    io::stdin().read_line(&mut password)?;
    let password = password.trim();

    let mut api_client = ApiClient::new_unauthenticated(&config.base_url);
    api_client.sign_in_with_credentials(email, password)?;

    println!("Successfully signed in.");
    Ok(())
}

pub fn logout() -> crate::Result<()> {
    Config::save_user_state(&UserState::default())?;
    println!("Successfully signed out.");
    Ok(())
}

pub fn whoami() -> crate::Result<()> {
    let config = Config::load();
    let mut api_client = ApiClient::new(&config)?;

    if !api_client.is_signed_in() {
        eprintln!("Not logged in");
        std::process::exit(1);
    }

    let user = api_client.get_current_user()?;
    println!(
        "Name: {}\nEmail: {}\nLogged into: {}",
        user.account.display_name, user.email, config.base_url
    );
    Ok(())
}
