use crate::{
  chat::{create_message_response, edit_response},
  commands::fun::roll::parse_dice,
};
use serenity::all::{
  ButtonStyle,
  CommandInteraction,
  CommandOptionType,
  Context,
  CreateActionRow,
  CreateButton,
  CreateCommand,
  CreateCommandOption,
  CreateMessage,
  Mentionable,
  UserId,
};

pub async fn run(ctx: &Context, command: &CommandInteraction) {
  // Check if the roll result is hidden
  let hidden = command
    .data
    .options
    .iter()
    .find(|opt| opt.name == "hidden")
    .and_then(|o| o.value.as_bool())
    .unwrap_or(false);

  // Retrieve the user
  let user = command
    .data
    .options
    .iter()
    .find(|opt| opt.name == "user")
    .and_then(|o| o.value.as_mentionable())
    .unwrap();

  let user_id = UserId::new(user.get());

  create_message_response(
    ctx,
    command,
    format!("Sending request to {}", user_id.mention()),
    true,
  )
  .await;

  let dice_string = command
    .data
    .options
    .first()
    .and_then(|o| o.value.as_str())
    .map(|s| s.split_whitespace().collect::<String>())
    .unwrap();

  let dice_result = parse_dice(dice_string.as_str());
  match dice_result {
    Ok(dice) => {
      let roll_button = CreateButton::new(format!(
        "request_dice_roll|{}|{}|{}|{}|{}",
        dice.0,
        dice.1,
        dice.2,
        command.user.id.get(),
        hidden
      ))
      .label(format!("🎲 Roll {} 🎲", dice_string)) // The label you want on the button
      .style(ButtonStyle::Primary);

      let action_row = CreateActionRow::Buttons(vec![roll_button]);

      let message = CreateMessage::new()
        .content(format!("-# Roll requested from {}", command.user.mention()))
        .components(vec![action_row]);

      if let Err(why) = user_id.dm(ctx, message).await {
        log::error!("failed to send request due to {}", why);
        edit_response(ctx, command, "Unable to send dice request".to_string()).await;
      };
    }
    Err(why) => {
      edit_response(ctx, command, why.to_string()).await;
    }
  }
}

pub fn register() -> CreateCommand {
  CreateCommand::new("requestroll")
    .description("Request a dice roll from a user")
    .add_option(
      CreateCommandOption::new(CommandOptionType::String, "dice", "Dice to roll").required(true),
    )
    .add_option(
      CreateCommandOption::new(
        CommandOptionType::Mentionable,
        "user",
        "User to receive the dice roll request",
      )
      .required(true),
    )
    .add_option(
      CreateCommandOption::new(
        CommandOptionType::Boolean,
        "hidden",
        "Hide the dice roll from the user (Default: False",
      )
      .required(false),
    )
}
