console.time('StartUp');
const express = require('express');
var app = express();
const path = require('path');
const http = require('http');
const {Server} = require('socket.io');
const mongoose = require('mongoose');
const port = process.env.PORT || 5000;
const {Client, GatewayIntentBits,Partials, ActivityType} = require('./lib.js');
const Spawner = require('child_process');
const guildsM = require('./models/guilds')

app.use(express.static(path.join(__dirname, "public")));
app.set("view engine", "ejs");
app.use(require('cors')())
app.use(express.json());
app.use(express.urlencoded({extended:true}));

const mongoDB = process.env.mongoDB;
  
const server = http.createServer(app);
const io = new Server(server);

var Childs = [];

server.listen(port, () => 
{
    app.use('/', require('./routes/routes')(io));
    console.log(`Http-Server UP`);
});

const bot = new Client({ intents: [
    GatewayIntentBits.Guilds,  
    GatewayIntentBits.GuildMembers,
    GatewayIntentBits.GuildBans,
    GatewayIntentBits.GuildEmojisAndStickers,
    GatewayIntentBits.GuildIntegrations ,
    GatewayIntentBits.GuildWebhooks ,
    GatewayIntentBits.GuildInvites ,
    GatewayIntentBits.GuildVoiceStates,
    GatewayIntentBits.GuildPresences,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.GuildMessageReactions,
    GatewayIntentBits.GuildMessageTyping,
    GatewayIntentBits.DirectMessages,
    GatewayIntentBits.DirectMessageReactions,
    GatewayIntentBits.DirectMessageTyping,
    GatewayIntentBits.MessageContent,
    GatewayIntentBits.GuildScheduledEvents,
    GatewayIntentBits.AutoModerationConfiguration,
    GatewayIntentBits.AutoModerationExecution],
    partials: [
        Partials.Reaction,
        Partials.Message 
      ]
});
bot.login(process.env.discord_token);

bot.on('ready', () => 
{
    mongoose.Promise = global.Promise;
    mongoose.connect(mongoDB).catch(err=>console.log(err));
    console.log(`--------------------------\n    ${bot.user.tag.split('#')[0]}   \n          Ready           \n       on `+bot.guilds.cache.size+" guilds         \n    serving "+bot.users.cache.size+" users        \n--------------------------")
    bot.user.setPresence({
        activities: [{ name: `!help`, type: ActivityType.Listening }],
        status: 'online',
    });
    console.timeEnd('StartUp');

    /* spawining a singe music worker for legendary
        
        Spawner.fork('./musicWorker.js',['334456736633323520', 'Legendary']) 
    
    */
    
    music();
  setInterval(() => 
  {
    music();
  }, 60000);
    setInterval(() => {
        moveAFKs();
    }, 5*60*1000);
});
bot.on('guildCreate', guild=> 
{
    console.log('Added To guild', guild);
    var guild = new GuildM()
});
bot.on('guildDelete', guild => 
{

});
async function music()
{
    //console.log('Music: Looking for Servers.')
    const ServersWithMusicOn = await serversWithMusicOn(bot.guilds.cache);
    if(!ServersWithMusicOn) return 
    for(var server of ServersWithMusicOn)
    {
        if(!Childs[server.name])
        {
            console.log('Index: Starting Music Worker:', server.name,`(${server.gID})`)
            Childs[server.name] = Spawner.fork('./musicWorker.js',[server.gID, server.name]);
        }
        else
        {       //Health check
           (function (server)
           {
                Childs[server.name].on('exit', ()=>
                {
                    console.log('Child DIED, spawning another.')
                    Childs[server.name] = Spawner.fork('./musicWorker.js',[server.gID, server.name]);
                })
            })(server);
        }

    } 
}

function moveAFKs(){
    //Gets the members inside the AFK channel
    let auxmembers = bot.channels.cache.get("335494006890823680").members
    //console.log("MoveAFK: Member list with "+ auxmembers.size+" members.")
    //Sorts through them looking for those who have the SS - Secret Services Role
    if(auxmembers.size >0)
    {
        //console.log("hosting:");
    }
    for(var [key, values] of auxmembers){
       //console.log(values.id);;
        if(values.roles.cache.has('693413934715240498')){ 
            //Upon fiding someoe that has said role.           
            //Moves it to the correct Channel.
            values.voice.setChannel('839266096401874974')
                    .then(() => console.log(`MoveAFK: Moved ${values.displayName}.`))
                    .catch(console.error);
        }
    }
}

async function serversWithMusicOn()
{
    return await guildsM.find({music:true}).then(g=>{return g})
}