import { getUserRecord } from "db/dbUser";
import items, { changeItemCount } from "items";
import { Command, sendMessage } from "lib/commandUtils";
import { ANIVNAMES } from "lib/handleAnivMessage";
import logger from "lib/logger";
import parseCommandArgs from "lib/parseCommandArgs";
import { timeout } from "lib/timeout";
import User from "user";

export default new Command({
	name: "give",
	aliases: ["give"],
	usertype: "chatter",
	execution: async (msg, user) => {
		if (Array.from<string>(ANIVNAMES).includes(msg.chatterName)) {
			await sendMessage("CLANKERS CAN'T GIVE ITEMS UltraMad UltraMad UltraMad");
			await timeout(user, "STUPID CLANKER", 30);
			return;
		}
		const args = parseCommandArgs(msg.messageText);
		if (!args[0]) {
			await sendMessage("Please specify a user", msg.messageId);
			return;
		}
		const target = await User.initUsername(args[0].toLowerCase());
		if (!target) {
			await sendMessage(`Chatter ${args[0]} doesn't exist`, msg.messageId);
			return;
		}
		if (target.username === user.username) {
			await sendMessage("You can't give yourself items", msg.messageId);
			return;
		}
		const targetRecord = await getUserRecord(target);
		if (!args[1]) {
			await sendMessage("Please specify an item to give", msg.messageId);
			return;
		}
		const item = items.get(args[1].toLowerCase());
		if (!item) {
			await sendMessage(`Item ${args[1]} doesn't exist`, msg.messageId);
			return;
		}
		if (!args[2]) {
			await sendMessage(
				"Please specify the amount of the item you want to give",
				msg.messageId,
			);
			return;
		}
		const amount = parseInt(args[2], 10);
		if (Number.isNaN(amount) || amount < 1) {
			await sendMessage(`'${args[2]}' is not a valid amount`);
			return;
		}
		const userRecord = await getUserRecord(user);
		if (userRecord.inventory[item.name]! < amount) {
			await sendMessage(`You can't give items you don't have!`, msg.messageId);
			return;
		}

		if ((await user.itemLock()) || (await target.itemLock())) {
			await sendMessage("Cannot give item (itemlock)", msg.messageId);
			return;
		}

		await Promise.all([user.setLock(), target.setLock()]);

		const data = await Promise.all([
			await changeItemCount(target, targetRecord, item.name, amount),
			await changeItemCount(user, userRecord, item.name, -amount),
		]);

		if (data[0] !== false && data[1] !== false) {
			const tempdata = data[0];
			const newamount = tempdata.inventory[item.name]!;
			await sendMessage(
				`${user.displayName} gave ${amount} ${item.prettyName + (amount === 1 ? "" : item.plural)} to ${target.displayName}. They now have ${newamount} ${item.prettyName + (newamount === 1 ? "" : item.plural)}`,
				msg.messageId,
			);
		} else {
			// TODO: Rewrite this section
			await sendMessage(
				`Failed to give ${target.displayName} ${amount} ${item.prettyName + (amount === 1 ? "" : item.plural)}`,
				msg.messageId,
			);
			logger.warn(
				`WARNING: Item donation failed: target success: ${data[0] !== false ? "yes" : "no"}, donator success: ${data[1] !== false ? "yes" : "no"}`,
			);
		}
		await user.clearLock();
		await target.clearLock();
	},
});
