/**
    List of intents
    https://discord.com/developers/docs/topics/gateway#privileged-intents
*/

const Discord = require('discord.js');
const {
    Client,
    Collection,
    Intents,
    MessageAttachment,
} = require('discord.js');
const client = new Client({
    intents: [
        Intents.FLAGS.GUILDS,
        Intents.FLAGS.GUILD_MESSAGES,
        Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
        Intents.FLAGS.GUILD_MEMBERS,
    ],
});

const fs = require('fs');
client.commands = new Collection();
const commandFiles = fs.readdirSync('./commands')
    .filter(file => !file.includes('WIP'));

for (const file of commandFiles) {
    const command = require(`./commands/${file}`);
    // Set a new item in the Collection
    // With the key as the command name and the value as the exported module
    client.commands.set(command.data.name, command);
}
const cron = require('node-cron');
const mongoose = require('mongoose');

mongoose
    .connect(process.env.DBSRV, {
        useNewUrlParser: true,
        useUnifiedTopology: true,
    }).then(() => {
        console.log('Connected to database');
    }).catch((err) => {
        console.log(err);
    });

require('dotenv').config();
const help = require('./helpFunctions.js');
const resp = require('./responses.js');
const bModel = require('./database/birthdaySchema');
const eModel = require('./database/eventSchema');

const turnOnMsg = ['AAAAAAAAAAAAA', 'Just turned on!', 'Just woke up!', 'May have crashed... sowwyyy >.<',
    'Heyyyy!', 'I\'m baaaack', 'Whom\'st have summoned they ancient one?'];

client.once('ready', async () => {
    if (client.user.username != 'MOOver Debug') {
        client.channels.cache.get('780439236867653635').send(turnOnMsg[help.RNG(turnOnMsg.length)]);
    }
    cron.schedule('0 13 * * *', async function() {
        pingEvent();
    });
    console.log('Running!');
});

client.on('messageCreate', gotMessage);

client.on('interactionCreate', async interaction => {
    if (!interaction.isCommand()) return;

    const command = client.commands.get(interaction.commandName);

    if (!command) return;

    try {
        await command.execute(interaction);
    }
    catch (error) {
        console.error(error);
        await interaction.reply({
            content: 'There was an error while executing this command!',
            ephemeral: true,
        });
    }
});

function gotMessage(message) {
    if (message.content.includes('https://media.discordapp.net') &&
    (message.content.includes('webm') ||
    message.content.includes('mov') ||
    message.content.includes('mp4') ||
    message.embeds[0]?.type == 'video')) {
        const linkArr = message.content.split('https://media.discordapp.net');
        message.channel.send('https://cdn.discordapp.com' + linkArr[1]);
    }

    if (process.env.DEBUG == "ON") {
        const debugger_ = require('./.debug.js');
        debugger_.debug(message);
    }

/**
 * kokot v piči
    const chance = help.RNG(50000);
    if (chance == 420) {
        resp.whoAsked(message);
    }
*/

    const msg = message.content.toLowerCase();

    const content = message.content.trim();

    const msgContentSplit = content.split(/[ ]+/);

    /**
     * reference can't be null => must be a reply to message
     * must contain only one argument
     * that argument mentions channel
     */

    if (message.reference != null && msgContentSplit.length == 1 &&
        message.mentions.channels.first() != undefined) {
        moveMessage(message, msgContentSplit[0]);
    }

    const isBot = message.author.bot;

    if (!isBot) {
        if (msg.includes('henlo')) {
            resp.henlo(message);
        }
        else if (msg.includes('how ye')) {
            resp.mood(message);
        }
        else if (msg.includes('tylko jedno')) {
            message.reply('Koksu pięć gram odlecieć sam');
        }
    }
}

function moveMessage(message, channelId) {
    message.react('🐮');

    const originalChannel = message.channel;
    const msgToMooveId = message.reference.messageId;
    const mentionedChannelId = channelId.substring(2, channelId.length - 1);

    originalChannel.messages.fetch(msgToMooveId).then(msg => {
        if (msg.embeds.length > 0 && msg.content == '' && msg.attachments.size == 0) {
            client.channels.cache.get(mentionedChannelId).send({embeds: msg.embeds });
        }
        else if (msg.attachments.size > 0) {

            let attachmentsURL = "";
            const originalMsgAttachments = msg.attachments.values();

            for (let i = 0; i < msg.attachments.size; i++) {
                const currAttachment = originalMsgAttachments.next().value;
                attachmentsURL += `${currAttachment.url}\n`;
            }

            let messStr = "";
            if (msg.content != '') {
                messStr = "\nMessage:\n";
            }

            newContent = `Sent by ${msg.author}\nmooved ${message.author}\n${messStr}${msg.content}\nAttachments:\n${attachmentsURL}`;
            
            client.channels.cache.get(mentionedChannelId).send({content: newContent});
            if (msg.embeds.length > 0) {
                client.channels.cache.get(mentionedChannelId)
                    .send({ embeds: msg.embeds })
            }
        }
        else {
            // ? Empty, Has embeds
            if (msg.content == '') {
                client.channels.cache.get(mentionedChannelId).send({
                    content: `Sent by ${msg.author}\nmooved ${message.author}\nMessage:\n${msg.content}`});
                }
            // ? Has content, No embeds
            else {
                const embed = new Discord.MessageEmbed()
                    .setColor(help.randomColor())
                    .addField('MOO', `Sent by ${msg.author}\nmooved ${message.author}`)
                    .addField('Message', msg.content);
                client.channels.cache.get(mentionedChannelId).send({ embeds: [embed] });
            }
        }

        setTimeout(() => msg.delete(), 3000);
    });
    setTimeout(() => message.delete(), 3000);
}

async function pingEvent() {
    const currentDay = new Date().getDate();
    const currentMonth = new Date().getMonth() + 1;

    let query = bModel.find({ day: currentDay, month: currentMonth });
    const birthdayList = await query.exec();

    query = eModel.find({ guild: 'global', day: currentDay, month: currentMonth });
    const globalEventList = await query.exec();
    const guildIds = [];
    const sysChannelIds = [];
    client.guilds.cache.forEach(element => {
        sysChannelIds.push(element.channels.guild.systemChannelId);
        guildIds.push(element.id);
    });

    // TODO deduplicate
    const todayBirthdays = [];
    if (todayBirthdays != []) {
        for (let i = 0; i < guildIds.length; i++) {
            const guildId = guildIds[i];
            const sysChannelId = sysChannelIds[i];
            const guild = client.guilds.cache.find((g) => g.id == guildId);
            for (let j = 0; j < birthdayList.length; j++) {
                const userId = birthdayList[j].id;
                if ((await guild.members.fetch()).find(user => user.id == userId) != undefined) {
                    const gifAmount = 12;
                    const embed = await help.getGifEmbed(`https://g.tenor.com/v1/search?q=anime-hug&key=${process.env.TENOR}&limit=${gifAmount}`, gifAmount);
                    embed.setDescription(`Happy Birthday <@${userId}> !!!`);
                    client.channels.cache.get(sysChannelId)
                        .send({ embeds: [embed] });
                }
            }
        }
    }

    for (let i = 0; i < guildIds.length; i++) {
        const guildId = guildIds[i];
        const sysChannelId = sysChannelIds[i];
        query = eModel.find({ guild: guildId, day: currentDay, month: currentMonth });
        const guildEvents = await query.exec();
        for (let j = 0; j < globalEventList.length; j++) {
            let specialMessage = '';
            if (globalEventList[j].name == 'Valentine\'s Day') {
                specialMessage = '\n Don\'t forget I love you all with all my hart 🥺';
            }
            client.channels.cache.get(sysChannelId)
            .send(`It's **${globalEventList[j].name}** today!` + specialMessage);
        }
        for (let j = 0; j < guildEvents.length; j++) {
            client.channels.cache.get(sysChannelId)
                .send(`It's **${guildEvents[j].name}** today!`);
        }
    }
}

client.login(process.env.TOKEN);
