/*
    Custom Modules -

    Usage :
    [ ] within the file's init(), define BotActions & Load them into the ModulesManager
    [ ] Define Execution Bodies for these BotActions
    [ ] Afterwards, add  the following to parent modules.rs file
        - mod <modulename>;
        - within init(), <modulename>::init(mgr).await

*/

use rand::Rng;
use std::sync::Arc;

use twitch_irc::message::PrivmsgMessage;

// use crate::core::botinstance::ChType::Channel;
use crate::core::botinstance::ChType;
use ChType::Channel;
use crate::core::botlog;

use crate::core::bot_actions::actions_util::{self, BotAR};
use crate::core::botmodules::{BotActionTrait, BotCommand, BotModule, Listener, ModulesManager};

use crate::core::identity::UserRole::*;

use tokio::time::{sleep, Duration};

pub async fn init(mgr: Arc<ModulesManager>) {

    const OF_CMD_CHANNEL:ChType = Channel(String::new());

    // 1. Define the BotAction
    let botc1 = BotCommand {
        module: BotModule(String::from("experiments001")),
        command: String::from("test1"), // command call name
        alias: vec![
            String::from("tester1"), 
            String::from("testy1")], // String of alternative names
        exec_body: actions_util::asyncbox(testy),
        help: String::from("Test Command tester"),
        required_roles: vec![
            BotAdmin,
            Mod(OF_CMD_CHANNEL),
        ], 
    };

    // 2. Add the BotAction to ModulesManager
    botc1.add_to_modmgr(Arc::clone(&mgr)).await;

    // 1. Define the BotAction
    let list1 = Listener {
        module: BotModule(String::from("experiments001")),
        name: String::from("GoodGirl Listener"),
        exec_body: actions_util::asyncbox(good_girl),
        help: String::from(""),
    };

    // 2. Add the BotAction to ModulesManager
    list1.add_to_modmgr(Arc::clone(&mgr)).await;


    //     // 1. Define the BotAction
    // let list1 = Listener {
    //         module: BotModule(String::from("experiments001")),
    //         name: String::from("babygirl Listener"),
    //         exec_body: actions_util::asyncbox(babygirl),
    //         help: String::from(""),
    //     };
    
    //     // 2. Add the BotAction to ModulesManager
    //     list1.add_to_modmgr(Arc::clone(&mgr)).await;

    // 1. Define the BotAction
    let botc1 = BotCommand {
        module: BotModule(String::from("experiments001")),
        command: String::from("babygirl"), // command call name
        alias: vec![], // String of alternative names
        exec_body: actions_util::asyncbox(babygirl),
        help: String::from("Babygirl"),
        required_roles: vec![
            BotAdmin,
            // Mod(OF_CMD_CHANNEL),
            Broadcaster,
        ], 
    };

    // 2. Add the BotAction to ModulesManager
    botc1.add_to_modmgr(Arc::clone(&mgr)).await;

}

async fn good_girl(bot: BotAR, msg: PrivmsgMessage) {
    // [ ] Uses gen_ratio() to output bool based on a ratio probability .
    //   - For example gen_ratio(2,3) is 2 out of 3 or 0.67% (numerator,denomitator)
    //   - More Info : https://rust-random.github.io/rand/rand/trait.Rng.html#method.gen_ratio

    if msg.sender.name.to_lowercase() == "ModulatingForce".to_lowercase()
        || msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase()
    // if msg.sender.name.to_lowercase() == "mzNToRi".to_lowercase()
    {
        botlog::debug(
            "Good Girl Detected > Pausechamp",
            Some("experiments > goodgirl()".to_string()),
            Some(&msg),
        );

        let rollwin = rand::thread_rng().gen_ratio(1, 8);

        if rollwin {
            botlog::debug(
                "Oh that's a good girl!",
                Some("experiments > goodgirl()".to_string()),
                Some(&msg),
            );

            let bot = Arc::clone(&bot);

            let botlock = bot.read().await;

            // uses chat.say_in_reply_to() for the bot controls for messages
            botlock
                .botmgrs
                .chat
                .say_in_reply_to(&msg, String::from("GoodGirl xdd "))
                .await;
        }
    }
}

async fn testy(mut _chat: BotAR, msg: PrivmsgMessage) {
    println!("testy triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call
    botlog::debug(
        "testy triggered!",
        Some("experiments > testy()".to_string()),
        Some(&msg),
    );
}


async fn babygirl(bot: BotAR, msg: PrivmsgMessage) {
    println!("babygirl triggered!"); // NOTE : This test function intends to print (e.g., to stdout) at fn call
    botlog::debug(
        "babygirl triggered!",
        Some("experiments > babygirl()".to_string()),
        Some(&msg),
    );


    let bot = Arc::clone(&bot);

    let botlock = bot.read().await;

    // uses chat.say_in_reply_to() for the bot controls for messages
    botlock
        .botmgrs
        .chat
        .say_in_reply_to(&msg, String::from("16:13 notohh: cafdk"))
        .await;


    sleep(Duration::from_secs_f64(0.5)).await;

    botlock
    .botmgrs
    .chat
    .say_in_reply_to(&msg, String::from("16:13 notohh: have fun eating princess"))
    .await;


    sleep(Duration::from_secs_f64(2.0)).await;

    botlock
    .botmgrs
    .chat
    .say_in_reply_to(&msg, String::from("16:13 notohh: baby girl"))
    .await;


}