use crate::display::format_table;
use crate::{ham::Ham, CommonOpts};
use anyhow::Result;
use colored::*;
use holochain_client::AgentPubKey;
use holochain_types::dna::AgentPubKeyB64;
use rave_engine::types::{Actionable, Completed, Ledger, Pending};

pub async fn dashboard(value: CommonOpts) -> Result<()> {
    whoami(value.clone()).await?;
    get_ledger(value.clone()).await?;
    get_pending(value.clone()).await?;
    get_actionable_transactions(value.clone()).await?;
    get_completed(value.clone()).await?;
    Ok(())
}
pub async fn whoami(value: CommonOpts) -> Result<AgentPubKeyB64> {
    let agent = Ham::connect(value).await?;

    let agent_key: AgentPubKey = agent
        .zome_call("alliance", "transactor", "whoami", ())
        .await?;
    let agent_key_str = AgentPubKeyB64::from(agent_key);
    println!("===================");
    println!("Agent Public Key: {}", agent_key_str);
    println!("===================");

    Ok(agent_key_str)
}

pub async fn get_ledger(value: CommonOpts) -> Result<()> {
    let agent = Ham::connect(value).await?;

    let ledger: Ledger = agent
        .zome_call("alliance", "transactor", "get_ledger", ())
        .await?;

    println!("===================");
    println!("Your Ledger:");
    println!("{:#?}", ledger);
    println!("===================");

    Ok(())
}

pub async fn get_pending(value: CommonOpts) -> Result<()> {
    let agent = Ham::connect(value).await?;

    let pending: Pending = agent
        .zome_call("alliance", "transactor", "get_pending_transactions", ())
        .await?;

    println!("Your Pending Transactions:");
    if pending.invoice.is_empty() {
        println!("{}", "No pending transactions".dimmed());
    } else {
        let table = format_table(&pending.invoice, "Pending Transactions");
        table.printstd();
    }

    Ok(())
}

pub async fn get_completed(value: CommonOpts) -> Result<()> {
    let agent = Ham::connect(value).await?;

    let completed: Completed = agent
        .zome_call("alliance", "transactor", "get_completed_transactions", ())
        .await?;

    println!("Your Completed Transactions:");
    if !completed.accept.is_empty() {
        let table = format_table(&completed.accept, "Accepted Transactions");
        table.printstd();
    } else {
        println!("{}", "No accepted transactions".dimmed());
    }
    if !completed.spend.is_empty() {
        let table = format_table(&completed.spend, "Spendd Transactions");
        table.printstd();
    } else {
        println!("{}", "No spendd transactions".dimmed());
    }

    Ok(())
}

pub async fn get_actionable_transactions(value: CommonOpts) -> Result<()> {
    let agent = Ham::connect(value).await?;

    let txs: Actionable = agent
        .zome_call("alliance", "transactor", "get_actionable_transactions", ())
        .await?;

    println!("Your Actionable List is: ");
    if !txs.invoice_actionable.is_empty() {
        let table = format_table(&txs.invoice_actionable, "Invoices");
        table.printstd();
    } else {
        println!("{}", "No invoices".dimmed());
    }
    if !txs.spend_actionable.is_empty() {
        let table = format_table(&txs.spend_actionable, "Spends");
        table.printstd();
    } else {
        println!("{}", "No spends".dimmed());
    }
    println!(
        "Number of actionable: {:?}",
        txs.invoice_actionable.len() + txs.spend_actionable.len()
    );

    Ok(())
}
