-- Registers chat commands

-- Import libraries
local fs, monsters, move_stats = ...

-- Translations
local S = core.get_translator("zoonami")
local F = core.formspec_escape

-- Monster Stats
core.register_chatcommand("monster-stats", {
	func = function(name, param)
		param = tonumber(param) or 0
		param = math.floor(param)
		if param < 1 or param > 5 then
			return true, S("Invalid number. Use 1, 2, 3, 4, or 5.")
		end
		local player = core.get_player_by_name(name)
		if not player then
			return true, S("Player must be online to view monster stats.")
		end
		local meta = player:get_meta()
		local monster = meta:get_string("zoonami_monster_"..param)
		monster = core.deserialize(monster)
		monster = monster and monsters.load_stats(monster)
		if not monster then
			return true, S("Monster Slot @1 is empty.", "#"..param)
		end
		local next_level = monster.level + 1
		local next_exp_milestone = next_level * next_level * monster.base.exp_per_level
		local exp_needed_for_level_up = next_exp_milestone - monster.exp_total
		if monster.level >= 100 then
			exp_needed_for_level_up = 0
		end
		local monster_moves = ""
		for i = 1, #monster.move_pool do
			local move_name = monster.move_pool[i]
			monster_moves = monster_moves..
				(i > 1 and ", " or "")..move_stats[move_name].name
		end
		local textarea = F(S("Monster Slot @1", "#"..param)).."\n"..
			F(S("Name: "))..monster.name.."\n"..
			(monster.nickname and F(S("Nickname: "))..monster.nickname.."\n" or "")..
			F(S("Level: "))..monster.level.."\n"..
			F(S("Type: "))..monster.type.."\n\n"..
			F(S("Energy: "))..monster.max_energy.."\n"..
			F(S("Energy Cap: "))..monster.base.energy_cap.."\n\n"..
			F(S("Health: "))..monster.max_health.."\n"..
			F(S("Health Base: "))..monster.base.health.."\n"..
			F(S("Per Level: "))..monster.base.health_per_level.."\n"..
			F(S("Boost: "))..((monster.boost.health - 1) * 100).."%".."\n\n"..
			F(S("Attack: "))..monster.attack.."\n"..
			F(S("Attack Base: "))..monster.base.attack.."\n"..
			F(S("Per Level: "))..monster.base.attack_per_level.."\n"..
			F(S("Boost: "))..((monster.boost.attack - 1) * 100).."%".."\n\n"..
			F(S("Defense: "))..monster.defense.."\n"..
			F(S("Defense Base: "))..monster.base.defense.."\n"..
			F(S("Per Level: "))..monster.base.defense_per_level.."\n"..
			F(S("Boost: "))..((monster.boost.defense - 1) * 100).."%".."\n\n"..
			F(S("Agility: "))..monster.agility.."\n"..
			F(S("Agility Base: "))..monster.base.agility.."\n"..
			F(S("Per Level: "))..monster.base.agility_per_level.."\n"..
			F(S("Boost: "))..((monster.boost.agility - 1) * 100).."%".."\n\n"..
			F(S("Next Level: "))..exp_needed_for_level_up.." EXP".."\n"..
			F(S("EXP Total: "))..monster.exp_total.." EXP".."\n\n"..
			F(S("Tier: "))..monster.base.tier.."\n\n"..
			(monster.prisma_id and F(S("Prisma Color: "))..monster.prisma_id.."\n\n" or "")..
			F(S("Personality: "))..monster.personality.."\n\n"..
			(monster.base.morph_level and F(S("Morph Level: "))..monster.base.morph_level.."\n" or "")..
			(monster.base.morphs_into and F(S("Morphs Into: "))..monsters.stats[monster.base.morphs_into].name.."\n\n" or "")..
			F(S("Moves: "))..monster_moves.."\n"
		local formspec = fs.header(12, 10, "false", "#00000000")..
			fs.background9(0, 0, 1, 1, "zoonami_gray_background.png", "true", 88)..
			fs.font_style("textarea", "mono", "*1", "#FFFFFF")..
			fs.textarea(0.5, 0.5, 11, 9, textarea)
		fsc.show(name, formspec, nil, function() end)
		return true, S("Showing stats for Monster Slot @1.", "#"..param)
	end,
})

-- PVP Stats
core.register_chatcommand("pvp-stats", {
	func = function(name, param)
		local player_name = param:split(" ")[1] or ""
		local player = core.get_player_by_name(player_name)
		if not player then
			return true, S("Player name is invalid or offline.")
		end
		local meta = player:get_meta()
		local pvp_wins = meta:get_int("zoonami_pvp_wins")
		local pvp_loses = meta:get_int("zoonami_pvp_loses")
		local pvp_forfeits = meta:get_int("zoonami_pvp_forfeits")
		local message = player_name.." PVP Stats"..
			"\n\nPVP Wins: "..pvp_wins..
			"\nPVP Loses: "..pvp_loses..
			"\nPVP Forfeits: "..pvp_forfeits
		local formspec = fs.header(12, 10, "false", "#00000000")..
			fs.background9(0, 0, 1, 1, "zoonami_gray_background.png", "true", 88)..
			fs.font_style("textarea", "mono", "*1", "#FFFFFF")..
			fs.textarea(0.5, 0.5, 11, 9, message)
		fsc.show(name, formspec, nil, function() end)
		return true, S("Showing PVP stats for @1.", player_name)
	end,
})

-- Transfer Zoonami Coins
core.register_chatcommand("transfer-zc", {
	func = function(sender_name, param)
		local receiver_name = param:split(" ")[1] or ""
		if receiver_name == "" then
			return true, S("Invalid player name.")
		elseif sender_name == receiver_name then
			return true, S("You can't transfer money to yourself.")
		end
		local transfer_amount = param:split(" ")[2]
		transfer_amount = tonumber(transfer_amount) or 0
		transfer_amount = math.floor(transfer_amount)
		if transfer_amount <= 0 then
			return true, S("Invalid amount. You must transfer at least 1 ZC.")
		end
		local receiver_player = core.get_player_by_name(receiver_name)
		local sender_player = core.get_player_by_name(sender_name)
		if not sender_player or not receiver_player then
			return true, S("Both players must be online to transfer ZC.")
		end
		local sender_meta = sender_player:get_meta()
		local sender_zc = sender_meta:get_int("zoonami_coins")
		if sender_zc < transfer_amount then
			return true, S("You don't have enough ZC to transfer that amount.")
		end
		sender_meta:set_string("zoonami_coins", sender_zc - transfer_amount)
		local receiver_meta = receiver_player:get_meta()
		local receiver_zc = receiver_meta:get_int("zoonami_coins")
		receiver_meta:set_string("zoonami_coins", receiver_zc + transfer_amount)
		core.log("action", sender_name.." transfered "..transfer_amount.." ZC to "..receiver_name..".")
		core.chat_send_player(receiver_name, S("@1 transfered @2 to you.", sender_name, transfer_amount.." ZC"))
		return true, S("You transferred @1 to @2.", transfer_amount.." ZC", receiver_name)
	end,
})

-- Withdraw Zoonami Coins
core.register_chatcommand("withdraw-zc", {
	func = function(name, param)
		local player = core.get_player_by_name(name)
		local inv = player:get_inventory()
		local meta = player:get_meta()
		local player_zc = meta:get_int("zoonami_coins")
		local withdrew_zc = tonumber(param) or 0
		withdrew_zc = math.floor(withdrew_zc)
		if withdrew_zc < 1 then
			return true, S("Invalid number. Please try again.")
		elseif withdrew_zc > player_zc then
			return true, S("You don't have enough ZC to withdraw that amount.")
		end
		local denominations = {1000, 100, 10, 1}
		local remaining_zc = withdrew_zc
		for i = 1, 4 do
			local max_stack = ItemStack("zoonami:"..denominations[i].."_zc_coin"):get_stack_max()
			local coin_count = math.floor(remaining_zc / denominations[i])
			while coin_count > 0 do
				local stack_count = math.min(coin_count, max_stack)
				local coin_stack = ItemStack("zoonami:"..denominations[i].."_zc_coin "..stack_count)
				local leftover = inv:add_item("main", coin_stack)
				if leftover:get_count() > 0 then
					core.add_item(player:get_pos(), leftover)
				end
				coin_count = coin_count - stack_count
				remaining_zc = remaining_zc - (stack_count * denominations[i])
			end
		end
		meta:set_int("zoonami_coins", player_zc - withdrew_zc)
		core.log("action", name.." withdrew "..withdrew_zc.." ZC from their bank.")
		core.sound_play("zoonami_coins", {to_player = name, gain = 0.9}, true)
		return true, S("You withdrew @1.", withdrew_zc.." ZC")
	end,
})
