use telers::{errors::SessionErrorKind as ErrorKind, event::EventReturn, Bot};

use crate::types::{enums::target_user::TargetUser, structs::message_sender::MessageSender};
use std::future::Future;

use super::demote::demote_user;

const DEMOTE_FAILURE_MESSAGE: &str = "\
    Нельзя выдать ограничение пользователю, т.к. невозможно демотнуть \
    участника посредством бота, если ему выдан админ при помощи других \
    админов или владельца чата.\
    ";

pub async fn try_restrict<F, R>(
    future_callback: F,
    demote_args: (&Bot, i64, i64),
    failure_sender: MessageSender,
) -> Result<(), EventReturn>
where
    R: Future<Output = Result<bool, ErrorKind>>,
    F: Copy + Fn() -> R,
{
    let (bot, user_id, chat_id): (&Bot, i64, i64) = demote_args;

    if future_callback().await.is_err() {
        if demote_user(bot, user_id, chat_id).await.is_err() {
            MessageSender::builder(chat_id)
                .text(DEMOTE_FAILURE_MESSAGE)
                .build()
                .send(bot)
                .await
                .unwrap();
            return Err(EventReturn::Cancel);
        }

        if future_callback().await.is_err() {
            failure_sender.send(bot).await.unwrap();
            return Err(EventReturn::Cancel);
        }
    }

    Ok(())
}