use dotenvy::dotenv;

use telers::{
    enums::ContentType,
    event::ToServiceProvider,
    filters::{content_type::ContentType as CT, Command},
    Bot, Dispatcher, Router,
};

mod actions;
mod assets;
mod middlewares;
mod types;
mod utils;

use middlewares::admin_check_middleware::AdminCheck;

mod endpoints;
use endpoints::{
    commands::{
        ban_command::ban,
        info_commands::{help, privacy},
        mute_command::mute,
        unmute_command::unmute
    },
    dice::dice::dice_handler,
};

#[cfg(debug_assertions)]
fn logs() {
    use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt as _, EnvFilter};

    tracing_subscriber::registry()
        .with(fmt::layer())
        .with(EnvFilter::from_env("RUST_LOG"))
        .init();
}

#[cfg(not(debug_assertions))]
fn logs() {
    println!(
        "
        Logs is able in only debug mode. Start bot with command \"cargo run\"\n
        Логи доступны только в режиме дебаг. Запустите бота командой \"cargo run\".
        "
    );
}

#[tokio::main]
async fn main() {
    logs();

    dotenv().ok();

    let token_result = dotenvy::var("TOKEN");
    match token_result {
        Ok(token) => {
            let bot = Bot::new(token);

            let mut route = Router::new("main");
            let mut dice = Router::new("dice");

            dice.message
                .register(dice_handler)
                .filter(CT::one(ContentType::Dice));

            dice.message.inner_middlewares.register(AdminCheck {});

            let mut command = Router::new("commands");
            let mut admin_commands = Router::new("admin_commands");
            let mut default_commands = Router::new("default_commands");

            default_commands
                .message
                .register(help)
                .filter(Command::one("help"));

            default_commands
                .message
                .register(privacy)
                .filter(Command::one("privacy"));

            admin_commands
                .message
                .register(unmute)
                .filter(Command::one("unmute"));

            admin_commands
                .message
                .register(mute)
                .filter(Command::one("mute"));

            admin_commands
                .message
                .register(ban)
                .filter(Command::one("ban"));

            admin_commands
                .message
                .inner_middlewares
                .register(AdminCheck {});

            command.include(admin_commands).include(default_commands);

            route.include(command);
            route.include(dice);

            let dispatcher = Dispatcher::builder().main_router(route).bot(bot).build();

            dispatcher
                .to_service_provider_default()
                .unwrap()
                .run_polling()
                .await
                .unwrap();
        }
        Err(error) => {
            println!("Error text: {:?}", error);
        }
    }
}