/*
    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

*/


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


use std::sync::Arc;

use chrono::{TimeZone,Local};
use twitch_irc::message::ReplyToMessage;


use crate::core::bot_actions::ExecBodyParams;
use crate::core::botinstance::Channel;
use crate::core::botlog;

use casual_logger::Log;

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

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

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


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

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

    // If enabling by defauling at instance level , uncomment the following
    // mgr.set_instance_enabled(BotModule(String::from("experiments002"))).await;


}


async fn sayout(params : ExecBodyParams) {


    /*
        usage :
        <target channel> <message>
     */



    let reply_parent = if let Some(Some(reply)) = params.msg.source.tags.0.get("reply-parent-msg-body") {
            Some(reply)
        } else { None }
    ;


    let reply_parent_ts = if let Some(Some(replyts)) = params.msg.source.tags.0.get("tmi-sent-ts") {

        let a: i64 = replyts.parse().unwrap();
        let b = Local.timestamp_millis_opt(a).unwrap();
        Some(b.format("%m-%d %H:%M"))
        } else { None }
    ;

    // [x] Unwraps arguments from message


    let argrslt = 
        if let Some((_,str1)) = params.msg.message_text.split_once(' ') {
            if reply_parent.is_none() {
                if let Some((channelstr,msgstr)) = str1.split_once(' ') {
                    Some((channelstr,msgstr))
                } 
                else { None }
            } else if let Some((_,str2)) = str1.split_once(' ') {
                if let Some((channelstr,msgstr)) = str2.split_once(' ') {
                Some((channelstr,msgstr))
                } 
                else { None }
            } else { None }
        }
        else { None };


    

    match argrslt {
        Some((trgchnl,outmsg)) => {

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

            let botlock = bot.read().await;

            // [x] Validate first if trgchnl exists

            botlog::trace(
                &format!("[TRACE] Evaluated status of {} : {:?}",
                    trgchnl.to_string().clone(),botlock.botmgrs.chat.client.get_channel_status(trgchnl.to_string().clone()).await),
                Some("Chat > send_botmsg".to_string()),
                None,
            );

            /*
                1. If a Reply , 
                [ ] Get Parent Content message - reply_parent
                [ ] Get Parent Chatter - reply_parent_usr 
                [ ] Get Parent Channel - msg.channel_login
                -> Share this first then
                [ ] Get Reply Message (that triggered bot command) - msgstr
                [ ] Get Reply Sender - msg.sender.name
                [ ] Get Target Channel - trgchnl

                2. If not a reply
                [ ] Get Reply Message (that triggered bot command) - msgstr
                [ ] Get Reply Sender - msg.sender.name
                [ ] Get Target Channel - trgchnl
             */

             // reply_parent_ts
            
            let newoutmsg = if let Some(srcmsg) = reply_parent {

                format!("{} {} @ {} : {}",
                    reply_parent_ts.unwrap(),
                    params.msg.sender.name,
                    params.msg.channel_login,
                    srcmsg)
            } else {
                format!("in {} - {} : {}",
                    params.msg.channel_login,
                    params.msg.sender.name, 
                    outmsg)
            };

            botlock
                .botmgrs
                .chat
                .say(
                    trgchnl.to_string(), 
                    newoutmsg.to_string(),
                    params.clone(),
                ).await;


        },
        None => {
            botlog::debug(
                "sayout had issues trying to parse arguments",
                Some("experiment002 > sayout".to_string()),
                Some(&params.msg),
            );

            let bot = Arc::clone(&params.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(
                Channel(params.clone().msg.channel_login().to_string()),
                params.clone().msg.message_id().to_string(), 
                String::from("Invalid arguments"),
                params.clone()
            ).await;


        },

    }

    Log::flush();
}