use serde::{Deserialize, Serialize};

use crate::{
    consts::MINUTE,
    models::CtxData,
    utils::{Extract, Recordable},
    Context, Error,
};

#[derive(Serialize, Deserialize, Extract)]
pub struct Options {
    minutes: Option<i64>,
    seconds: Option<i64>,
}

impl Recordable for Options {
    async fn run(self, ctx: Context<'_>) -> Result<(), Error> {
        let combined_time =
            self.minutes.map_or(0, |m| m * MINUTE as i64) + self.seconds.map_or(0, |s| s);

        if combined_time < i16::MIN as i64 || combined_time > i16::MAX as i64 {
            ctx.say("Nudge times must be less than 500 minutes").await?;
        } else {
            let mut channel_data = ctx.channel_data().await.unwrap();

            channel_data.nudge = combined_time as i16;
            channel_data.commit_changes(&ctx.data().database).await;

            ctx.say(format!("Future reminders will be nudged by {} seconds", combined_time))
                .await?;
        }

        Ok(())
    }
}

/// Nudge all future reminders on this channel by a certain amount (don't use for DST! See `/offset`)
#[poise::command(
    slash_command,
    rename = "nudge",
    identifying_name = "nudge",
    default_member_permissions = "MANAGE_GUILD"
)]
pub async fn command(
    ctx: Context<'_>,
    #[description = "Number of minutes to nudge new reminders by"] minutes: Option<i64>,
    #[description = "Number of seconds to nudge new reminders by"] seconds: Option<i64>,
) -> Result<(), Error> {
    (Options { minutes, seconds }).run(ctx).await
}
