const Command = require("../../base/Command"),
	Discord = require("discord.js");

const currentGames = {};

class FindWords extends Command {
	constructor(client) {
		super(client, {
			name: "findwords",
			dirname: __dirname,
			enabled: true,
			guildOnly: true,
			aliases: ["findw"],
			memberPermissions: [],
			botPermissions: ["SEND_MESSAGES", "EMBED_LINKS"],
			nsfw: false,
			ownerOnly: false,
			cooldown: 2000
		});
	}

	async run(message, args, data) {
		if (currentGames[message.guild.id]) return message.error("economy/number:GAME_RUNNING");

		// Reads words file
		let lang = null;
		if (message.guild.data.language === "uk-UA") return lang = "ru-RU";
		else lang = message.guild.data.language;

		const wordList = require(`../../assets/json/words/${lang}.json`);

		// Init some utils variables
		const participants = [],
			winners = [],
			words = [],
			nbGames = this.client.functions.randomNum(4, 10);

		// Store the date wich the game has started
		const createdAt = Date.now(); // 20929038303

		for (let i = 0; i < nbGames; i++) {
			const result = Math.floor((Math.random() * wordList.length));
			words.push(wordList[result].substring(0, 3).toLowerCase());
		}

		let i = 0; // Inits i variable to count games
		currentGames[message.guild.id] = true; // Update current game variable
		generateGame.call(this, words[i]); // Generate a new round

		function generateGame(word) {
			word = word.toLowerCase();

			// Launch timer
			const delay = (i === 0) ? 10000 : 0;
			if (i === 0) message.sendT("economy/findwords:GAME_STARTING");

			setTimeout(() => {
				// Send announcment message
				message.sendT("economy/findwords:FIND_WORD", {
					word: word.toUpperCase()
				}, false, false, "warn");

				// init a collector to receive the answers
				const filter = m => !m.author.bot;
				const collector = new Discord.MessageCollector(message.channel, {
					filter,
					time: 20000
				});

				collector.on("collect", (msg) => {
					if (this.client.functions.getPrefix(msg, data)) return;
					if (!participants.includes(msg.author.id)) participants.push(msg.author.id);
					if (msg.content === "STOP") return collector.stop("force");
					if (msg.content.toLowerCase().indexOf(word) >= 0 && wordList.map((word) => word.toLowerCase()).indexOf(msg.content.toLowerCase()) >= 0) {
						collector.stop(msg.author.id); // Stop the collector
					} else msg.error("economy/findwords:INVALID_WORD", { member: msg.author.toString() });
				});

				collector.on("end", async (collected, reason) => {
					if (reason === "time") message.error("economy/findwords:NO_WINNER");
					else if (reason === "force") return message.error("misc:FORCE_STOP", { user: message.author.toString() });
					else {
						message.success("economy/findwords:WORD_FOUND", {
							winner: `<@${reason}>`
						});
						winners.push(reason);
					}

					if (i < nbGames - 1) {
						i++;
						generateGame.call(this, words[i]);
					} else {
						currentGames[message.guild.id] = false;
						if (winners.length < 1) return message.error("economy/findwords:NO_WINNER_ALL");

						const winnerID = await getWinner(winners);
						const time = message.convertTime(createdAt, "from", true);
						const user = await this.client.users.fetch(winnerID);
						message.sendT("economy/findwords:GAME_STATS", {
							winner: user.username,
							duration: time,
							participantCount: participants.length,
							participants: participants.map((p) => `<@${p}>`).join(", ")
						});
						if (participants.length > 1 && data.guild.disabledCategories && !data.guild.disabledCategories.includes("Economy")) {
							const won = 150 * (participants.length * 0.5);

							message.sendT("economy/findwords:CREDITS", {
								winner: user.username,
								credits: `**${won}** ${message.getNoun(won, message.translate("misc:NOUNS:CREDIT:1"), message.translate("misc:NOUNS:CREDIT:2"), message.translate("misc:NOUNS:CREDIT:5"))}`
							});

							const memberData = await this.client.findOrCreateMember({
								id: user.id,
								guildID: message.guild.id
							});

							const info = {
								user: message.translate("economy/transactions:WORDS"),
								amount: won,
								date: Date.now(),
								type: "got"
							};

							data.memberData.transactions.push(info);

							memberData.money += won;
							memberData.save();
						}
					}
				});
			}, delay);
		}

		async function getWinner(array) {
			return new Promise(function (resolve) {
				const counts = {};
				let compare = 0,
					mostFrequent;

				for (let i = 0, len = array.length; i < len; i++) {
					const winner = array[i];
					if (!counts[winner]) counts[winner] = 1;
					else counts[winner] = counts[winner] + 1;

					if (counts[winner] > compare) {
						compare = counts[winner];
						mostFrequent = array[i];
					}
				}
				resolve(mostFrequent);
			});
		}
	}
}

module.exports = FindWords;