use crate::model::{
    boat::Boat,
    boathouse::Boathouse,
    user::{AdminUser, UserWithDetails, VorstandUser},
};
use rocket::{
    form::Form,
    get, post,
    request::FlashMessage,
    response::{Flash, Redirect},
    routes, FromForm, Route, State,
};
use rocket_dyn_templates::{tera::Context, Template};
use sqlx::SqlitePool;

#[get("/boathouse")]
async fn index(
    db: &State<SqlitePool>,
    admin: VorstandUser,
    flash: Option<FlashMessage<'_>>,
) -> Template {
    let mut context = Context::new();
    if let Some(msg) = flash {
        context.insert("flash", &msg.into_inner());
    }

    let boats = Boat::all_for_boatshouse(db).await;
    let mut final_boats = Vec::new();
    for boat in boats {
        if boat.boat.boathouse(db).await.is_none() && !boat.boat.external {
            final_boats.push(boat);
        }
    }

    context.insert("boats", &final_boats);

    let boathouse = Boathouse::get(db).await;
    context.insert("boathouse", &boathouse);

    context.insert(
        "loggedin_user",
        &UserWithDetails::from_user(admin.into_inner(), db).await,
    );

    Template::render("board/boathouse", context.into_json())
}

#[derive(FromForm)]
pub struct FormBoathouseToAdd {
    pub boat_id: i32,
    pub aisle: String,
    pub side: String,
    pub level: i32,
}
#[post("/boathouse", data = "<data>")]
async fn new<'r>(
    db: &State<SqlitePool>,
    data: Form<FormBoathouseToAdd>,
    _admin: AdminUser,
) -> Flash<Redirect> {
    match Boathouse::create(db, data.into_inner()).await {
        Ok(_) => Flash::success(Redirect::to("/board/boathouse"), "Boot hinzugefügt"),
        Err(e) => Flash::error(Redirect::to("/board/boathouse"), e),
    }
}

#[get("/boathouse/<boathouse_id>/delete")]
async fn delete(db: &State<SqlitePool>, _admin: AdminUser, boathouse_id: i32) -> Flash<Redirect> {
    let boat = Boathouse::find_by_id(db, boathouse_id).await;
    match boat {
        Some(boat) => {
            boat.delete(db).await;
            Flash::success(Redirect::to("/board/boathouse"), "Bootsplatz gelöscht")
        }
        None => Flash::error(Redirect::to("/board/boathouse"), "Boatplace does not exist"),
    }
}
//#[post("/boat/new", data = "<data>")]
//async fn create(
//    db: &State<SqlitePool>,
//    data: Form<BoatToAdd<'_>>,
//    _admin: AdminUser,
//) -> Flash<Redirect> {
//    match Boat::create(db, data.into_inner()).await {
//        Ok(_) => Flash::success(Redirect::to("/admin/boat"), "Boot hinzugefügt"),
//        Err(e) => Flash::error(Redirect::to("/admin/boat"), e),
//    }
//}

pub fn routes() -> Vec<Route> {
    routes![index, new, delete]
}