use log::warn;
use rocket::{
    delete, get,
    http::CookieJar,
    post,
    serde::json::{json, Json},
    State,
};
use serenity::all::GuildId;
use serenity::client::Context;
use sqlx::{MySql, Pool};

use crate::web::guards::transaction::Transaction;
use crate::web::routes::dashboard::create_reminder_template;
use crate::web::{
    check_authorization,
    routes::{
        dashboard::{DeleteReminderTemplate, ReminderTemplate},
        JsonResult,
    },
};

#[get("/api/guild/<id>/templates")]
pub async fn get_reminder_templates(
    id: u64,
    cookies: &CookieJar<'_>,
    ctx: &State<Context>,
    pool: &State<Pool<MySql>>,
) -> JsonResult {
    check_authorization(cookies, ctx.inner(), id).await?;

    match sqlx::query_as_unchecked!(
        ReminderTemplate,
        "SELECT * FROM reminder_template WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?)",
        id
    )
    .fetch_all(pool.inner())
    .await
    {
        Ok(templates) => Ok(json!(templates)),
        Err(e) => {
            warn!("Could not fetch templates from {}: {:?}", id, e);

            json_err!("Could not get templates")
        }
    }
}

#[post("/api/guild/<id>/templates", data = "<reminder_template>")]
pub async fn create_guild_reminder_template(
    id: u64,
    reminder_template: Json<ReminderTemplate>,
    cookies: &CookieJar<'_>,
    ctx: &State<Context>,
    mut transaction: Transaction<'_>,
) -> JsonResult {
    check_authorization(cookies, ctx.inner(), id).await?;

    match create_reminder_template(
        ctx.inner(),
        &mut transaction,
        GuildId::new(id),
        reminder_template.into_inner(),
    )
    .await
    {
        Ok(r) => match transaction.commit().await {
            Ok(_) => Ok(r),
            Err(e) => {
                warn!("Couldn't commit transaction: {:?}", e);
                json_err!("Couldn't commit transaction.")
            }
        },

        Err(e) => Err(e),
    }
}

#[delete("/api/guild/<id>/templates", data = "<delete_reminder_template>")]
pub async fn delete_reminder_template(
    id: u64,
    delete_reminder_template: Json<DeleteReminderTemplate>,
    cookies: &CookieJar<'_>,
    ctx: &State<Context>,
    pool: &State<Pool<MySql>>,
) -> JsonResult {
    check_authorization(cookies, ctx.inner(), id).await?;

    match sqlx::query!(
        "DELETE FROM reminder_template WHERE guild_id = (SELECT id FROM guilds WHERE guild = ?) AND id = ?",
        id, delete_reminder_template.id
    )
    .fetch_all(pool.inner())
    .await
    {
        Ok(_) => {
            Ok(json!({}))
        }
        Err(e) => {
            warn!("Could not delete template from {}: {:?}", id, e);

            json_err!("Could not delete template")
        }
    }
}
