use csv::ReaderBuilder;
use rocket::{form::Form, get, post, routes, FromForm, Route, State};
use rocket_dyn_templates::{context, Template};
use sqlx::SqlitePool;

use crate::{
    model::{log::Log, role::Role, user::AdminUser},
    tera::Config,
};

pub mod boat;
pub mod mail;
pub mod notification;
pub mod planned_event;
pub mod schnupper;
pub mod user;

#[get("/rss?<key>")]
async fn rss(db: &State<SqlitePool>, key: &str, config: &State<Config>) -> String {
    if key.eq(&config.rss_key) {
        Log::generate_feed(db).await
    } else {
        "Not allowed".into()
    }
}

#[get("/rss", rank = 2)]
async fn show_rss(db: &State<SqlitePool>, _admin: AdminUser) -> String {
    Log::show(db).await
}

#[get("/list")]
async fn show_list(_admin: AdminUser) -> Template {
    Template::render("admin/list/index", context!())
}

#[derive(FromForm)]
struct ListForm {
    list: String,
}

#[post("/list", data = "<list_form>")]
async fn list(db: &State<SqlitePool>, _admin: AdminUser, list_form: Form<ListForm>) -> Template {
    let role = Role::find_by_name(db, "Donau Linz").await.unwrap();
    let acceptable_users = role.names_from_role(db).await;

    let mut rdr = ReaderBuilder::new()
        .has_headers(true)
        .delimiter(b';')
        .from_reader(list_form.list.trim().as_bytes());

    let mut names_not_in_acceptable_users = Vec::new();

    for result in rdr.records() {
        println!("{result:?}");
        let record = result.unwrap();

        // Concatenate Vorname and Nachname
        let vorname = record.get(2).unwrap_or_default().trim();
        let nachname = record.get(3).unwrap_or_default().trim();
        let full_name = format!("{} {}", vorname, nachname);

        // Check if the concatenated name is not in the acceptable_users vector
        if !acceptable_users.contains(&full_name) {
            names_not_in_acceptable_users.push(full_name);
        }
    }

    let context = context! {
        result: names_not_in_acceptable_users
    };

    Template::render("admin/list/result", context)
}

pub fn routes() -> Vec<Route> {
    let mut ret = Vec::new();
    ret.append(&mut user::routes());
    ret.append(&mut schnupper::routes());
    ret.append(&mut boat::routes());
    ret.append(&mut notification::routes());
    ret.append(&mut mail::routes());
    ret.append(&mut planned_event::routes());
    ret.append(&mut routes![rss, show_rss, show_list, list]);
    ret
}
