use std::collections::HashMap;
use tokio_rusqlite::Connection;

use crate::db;
use crate::mail;
use crate::model::config::Config;
use crate::payer;

pub async fn send(
    config: &Config,
    db_conn: &Connection,
    env: &minijinja::Environment<'_>,
) -> bool {
    match get_weekly_report(db_conn, env).await {
        Ok(report) => {
            let users = db::users::list(db_conn).await;
            mail::send(
                config,
                users
                    .into_iter()
                    .map(|u| mail::Recipient {
                        name: u.name,
                        address: u.email,
                    })
                    .collect(),
                "Rapport hebdomadaire".to_string(),
                report,
            )
            .await
        }
        Err(err) => {
            log::error!(
                "Error preparing weekly report from template: {:?}",
                err
            );
            false
        }
    }
}

async fn get_weekly_report(
    db_conn: &Connection,
    env: &minijinja::Environment<'_>,
) -> Result<String, minijinja::Error> {
    let users = db::users::list(db_conn).await;
    let incomes_from = db::incomes::defined_for_all(db_conn).await;
    let user_incomes = match incomes_from {
        Some(from) => db::incomes::cumulative(db_conn, from).await,
        None => HashMap::new(),
    };
    let user_payments = db::payments::repartition(db_conn).await;
    let exceeding_payers =
        payer::exceeding(&users, &user_incomes, &user_payments);

    let last_week_payments = db::payments::last_week(db_conn).await;
    let last_week_incomes = db::incomes::last_week(db_conn).await;

    let template = env.get_template("report/report.j2")?;
    template.render(minijinja::context!(
        name => "John",
        exceeding_payers => exceeding_payers,
        payments => last_week_payments,
        incomes => last_week_incomes
    ))
}