/**
 * @type {Internal.Player}
 */
let currentPlayer = null;

ClientEvents.tick(event => {
	if (!currentPlayer && event.player) {
		currentPlayer = event.player;
	}
});

ItemEvents.tooltip(event => {

	function colorDurabilityText(p, t) {
		if (p > 0.6) {
			return Text.green(t);
		} else if (p > 0.4) {
			return Text.yellow(t);
		} else if (p > 0.2) {
			return Text.gold(t);
		}
		return Text.red(t);
	}

	/*
		2 nukes for tooltips
		First one completely removes descriptions of items
		Second one removes the mentions of items protecting against bleeding
	*/
	//priority: 100
	event.addAdvanced([
		'@mcdw',
		'sortilege:limitite',
		'botanicadds:dreaming_pool',
		'majruszsdifficulty:recall_potion',
		'heart_crystals:heart_crystal',
		'ars_nouveau:ring_of_lesser_discount',
		'ars_nouveau:ring_of_greater_discount'
	], (item, advanced, text) => {
		const original = text.toArray();

		for (let i = 1; i < original.length; i++) {
			if (text[1].toString().includes('Enchantments') || text[1].toString().includes('item.modifiers.')) {
				if (!event.shift) text.add(1, '')
				break
			};
			text.remove(1)
		}
	})
	//priority: 100
	event.addAdvancedToAll((item, advanced, text) => {
		const original = text.toArray();
		for (let i = original.length - 1; i > 0; i--) {
			if (text[i].toString().includes('item.majruszsdifficulty.bandage.effect')) {
				text.remove(i);
				text.remove(i - 1);
				text.remove(i - 2);
				break;
			}
		}
	})

	// Global tooltip modifications
	// Targetted mainly towards tools
	const attributesIgnoredItems = [
		'sortilege:lapis_shield'
	]
	/** @type {InputItem_} */
	const setBonusItems = [
		'botania:manasteel_helmet',
		'botania:manasteel_chestplate',
		'botania:manasteel_leggings',
		'botania:manasteel_boots',
		'botania:terrasteel_helmet',
		'botania:terrasteel_chestplate',
		'botania:terrasteel_leggings',
		'botania:terrasteel_boots',
		'majruszsdifficulty:enderium_helmet',
		'majruszsdifficulty:enderium_chestplate',
		'majruszsdifficulty:enderium_leggings',
		'majruszsdifficulty:enderium_boots',
		'born_in_chaos_v1:dark_metal_armor_helmet',
		'born_in_chaos_v1:dark_metal_armor_chestplate',
		'born_in_chaos_v1:dark_metal_armor_leggings',
		'born_in_chaos_v1:dark_metal_armor_boots'
	]
	//priority:-100
	event.addAdvancedToAll((item, advanced, text) => {
		// Remove attributes if SHIFT isn't pressed
		if (!event.shift && !attributesIgnoredItems.includes(item.id.toString())) {
			// Find from where to remove the lines
			let pos;
			for (let i = 1; i < text.length; i++) {
				if (text[i].toString().includes('item.modifiers.')) {
					pos = i - 1;
					break;
				};
			}

			for (let c = 0; c < 20; c++) {
				// Stop when there are either no attribute lines left
				// or we reach the advanced tooltips
				if (!text[pos] || text[pos].toString().includes('color=dark_gray')) break;
				text.remove(pos);
			}
		}
		else {
			for (let i = 1; i < text.length; i++) {
				let line = text[i].toString();
				if (line.includes('color=blue') && line.includes('Mining Speed')) {
					const match = line.match(/attributeslib\.value\.flat', args=\[(\d+(?:\.\d+)?)\]/);
					if (match) {
						let number = parseFloat(match[1]);

						// Round to 1 decimal, then remove trailing .0 if present
						number = Math.round(number * 10) / 10;

						text.remove(i);
						text.add(i, Text.darkGreen(' ' + number + ' Mining Speed'));
					}

				}
				else if (line.includes('color=blue') && line.includes('Harvest Level')) {
					const match = line.match(/attributeslib\.value\.flat', args=\[(\d+)\]/);
					if (match) {
						const number = parseInt(match[1], 10);
						text.remove(i);
						text.add(i, Text.darkGreen(' ' + number + ' Harvest Level'))
					}
				}
			}
		}

		if (item.maxDamage != 0) {
			let pos = (advanced) ? text.length - 2 : text.length;

			let damage = [item.maxDamage - item.damageValue, item.maxDamage]

			let firstNumber = Text.of(parseInt(damage[0]).toString().replace('.0', ''));
			let secondNumber = Text.of(parseInt(damage[1]).toString().replace('.0', ''));

			let percent = parseFloat(damage[0]) / parseFloat(damage[1]);

			text.add(pos, Text.join([
				Text.gray("Durability: "),
				colorDurabilityText(percent, firstNumber),
				Text.gray("/"),
				Text.of(secondNumber).white(),
				" ",
				Text.join([
					"(",
					colorDurabilityText(percent, Text.join([(percent * 100).toFixed(1).toString().replace('.0', ''), "%"])),
					")"
				]).gray()
			]))
			text.add(pos, '')
		}

		// Customize the enchantment line because I can
		for (let i = 1; i < text.length; i++) {
			if (text[i].toString().includes('Enchantments')) {
				let str = text[i].toString();
				let match = str.match(/'(\d+)\/(\d+) Enchantments'/);

				let firstNumber = Text.of(parseInt(match[1]).toString().replace('.0', ''));
				let secondNumber = Text.of(parseInt(match[2]).toString().replace('.0', ''));

				let grayFormatting = (match[1] == 0) ? true : false;
				let redFormatting = (match[1] === match[2]) ? true : false;

				text.remove(i)
				let enchantments = [];
				if (item.isEnchanted()) {
					for (let newEnchantLine = 1; newEnchantLine < text.length; newEnchantLine++) {
						if (text[newEnchantLine].toString().includes('enchantments')) {
							text.remove(newEnchantLine)
							for (let iter = 0; iter < match[1]; iter++) {
								enchantments.push(text[newEnchantLine]);
								text.remove(newEnchantLine)
							}
							text.remove(newEnchantLine - 1)
							break;
						}
					}
				}
				const enchLine = Text.join([
					Text.gray("Enchantments: "),
					(redFormatting) ? firstNumber.red() : ((grayFormatting) ? firstNumber.darkGray() : firstNumber.lightPurple()),
					Text.of("/").gray(),
					(redFormatting) ? secondNumber.darkRed() : ((grayFormatting) ? secondNumber.gray() : secondNumber.darkPurple()),
				]);
				const enchLinePos = (advanced) ? text.length - 3 : text.length - 1;
				text.add(enchLinePos, enchLine)
				text.add(enchLinePos + 1, '')

				if (enchantments.length > 0) {
					for (let iter = 0; iter < enchantments.length; iter++) {
						text.add(enchLinePos + 1 + iter, Text.join([
							Text.gray(" ◇"),
							Text.of(enchantments[iter])
						]));
					}
				}
				break;
			}
		}


		// Remove default set bonus items
		if (setBonusItems.includes(item.getId().toString())) {
			// for (let i = 0; i < text.length; i++) {
			// 	if (text[i].toString().includes('Enchantments')) pos = i + 1;
			// }

			for (let i = 0; i < 100; i++) {
				if (text[1].toString().includes('item.modifiers.') || text[1].toString().includes('Enchantments')) {
					text.add(1, '')
					break;
				}
				text.remove(1);
			}
		}
	})

	event.addAdvanced([
		'potion',
		'splash_potion',
		'lingering_potion'
	], (item, advanced, text) => {
		const original = text.toArray();

		let drinkingTime, cooldown;
		if (original[1] && original[1].toString().includes('sortilege.potion.drinking_time')) {
			drinkingTime = original[1].toString().match(/\d+/g);
		}
		if (original[1] && original[1].toString().includes('sortilege.staff.cooldown')) {
			cooldown = original[1].toString().match(/\d+/g);
		}
		else if (original[2] && original[2].toString().includes('sortilege.staff.cooldown')) {
			cooldown = original[2].toString().match(/\d+/g);
		};

		let potionLine;
		if (cooldown) {
			text.remove(1);
			potionLine = Text.join([
				((item.id != 'minecraft:potion') ? Text.gray('Tʜʀᴏᴡ ᴄᴏᴏʟᴅᴏᴡɴ: ') : Text.gray('Cᴏᴏʟᴅᴏᴡɴ: ')),
				Text.gold(Text.join([parseInt(cooldown).toString().replace('.0', ''), 's']))
			]);
		}

		if (drinkingTime) {
			text.remove(1);
			potionLine = Text.join([
				potionLine,
				Text.white(' | ').bold(),
				Text.gray('Dʀɪɴᴋɪɴɢ ᴛɪᴍᴇ: '),
				Text.gold(Text.join([parseInt(drinkingTime).toString().replace('.0', ''), 's'])),
			]);
		}

		if (potionLine) {
			text.add(1, potionLine);
			text.add(2, '');
		}
	})

	event.addAdvanced(global.blacklistedItems, (item, advanced, text) => {
		text.clear()
		text.add(0, Text.of('Removed item').darkGray())
		text.add(1, Text.of('This item is unobtainable in this modpack').darkGray())
	})

	//priority: 200
	event.addAdvancedToAll((item, advanced, text) => {
		const original = text.toArray();
		let chapters = [],
			exceptions = [];
		item.getTags().toArray().forEach(tag => {
			const str = tag.toString();
			if (!str.includes('chapter_')) return;
			const match = str.match(/adj:locked_until\/.*[^ ]*?(chapter_\w+)/);
			if (str.includes('exceptions')) {
				exceptions.push(match[1]);
			}
			else {
				chapters.push(match[1]);
			}
		});

		if (chapters.length == 0) return;

		let
			chapter = chapters.sort()[chapters.length - 1],
			exception = exceptions.sort()[exceptions.length - 1];;

		if ((!exception || chapter != exception) && !currentPlayer.stages.has(chapter)) {

			text.clear()

			text.add(0, Text.darkGray('Unknown Item'))
			text.add(1, Text.darkGray('Unlocked in Chapter ' + chapter.replace('chapter_', '')))

			if (advanced && global.developerMode) {
				let advancedTooltipLines = [];
				for (let i = 1; i < 3; i++) {
					if (original[original.length - i].toString().includes('color=dark_gray')) advancedTooltipLines.push(original[original.length - i]);
				}
				advancedTooltipLines.reverse();

				for (let i = 0; i < advancedTooltipLines.length; i++) {
					text.add(2 + i, Text.darkGray(advancedTooltipLines[i]));
				}
				text.add(2, '')
			}
		}
	})

	// Set bonus messages
	event.addAdvanced(['#adj:reforges/armor'], (item, advanced, text) => {
		let stages = currentPlayer.stages.getAll().toArray();
		let bonusID = null;
		for (let tag of stages) {
			let match = tag.match(/^set_bonus\.([a-z0-9_\-]+)\.([a-z0-9_\-/]+)$/);
			if (match) {
				bonusID = match[1] + ":" + match[2];
				break;
			}
		}
		if (bonusID == null) return;

		// Base armor type of the hovered item
		const itemId = item.id.toString()
		let armorType;
		outer: for (const [slot, names] of Object.entries(global.armorSuffixes)) {
			for (const type of names) {
				if (itemId.endsWith(type)) {
					armorType = itemId.replace(type, '')
					break outer;
				}
			}
		}

		if (bonusID.startsWith('ars_nouveau:arcanist')) {
			let tier = bonusID.split('_')[2];
			armorType = armorType + '_' + tier

		}

		// Build a list of allowed types for this bonus
		let allowedTypes = [bonusID];
		if (global.bonusOverrides && global.bonusOverrides[bonusID]) {
			global.bonusOverrides[bonusID].forEach(combo => {
				combo.forEach(piece => {
					if (!allowedTypes.includes(piece)) {
						allowedTypes.push(piece);
					}
				});
			});
		}

		// Only show tooltip if this armor piece matches any of the allowed types
		if (!allowedTypes.includes(armorType)) return;

		const bonus = global.setBonusMap[bonusID];
		const description = bonus.description;

		text.add(text.length, '');
		text.add(text.length, Text.gray('Full set bonus:'));

		description.forEach(line => {
			text.add(text.length, Text.gray(' ' + line));
		});
	});


	/**
	 * Adds tooltip lines to one or more items using the simplified `tip()` interface.
	 *
	 * @param {string|string[]|RegExp|RegExp[]} items  
	 * Item ID, array of IDs, or regex patterns.  
	 * - Strings must be full item IDs (e.g. `"minecraft:stick"`).  
	 * - Regex patterns match multiple items.  
	 * - Arrays can mix strings and regex.
	 *
	 * @param {string|string[]} text  
	 * Tooltip text to add.  
	 * - Single string → one line  
	 * - Array of strings → multiple lines
	 *
	 * @param {Object} [opts]  
	 * Optional settings that control how the tooltip behaves.
	 *
	 * @param {boolean} [opts.gray=true]  
	 * Whether to render the tooltip in gray text.  
	 * Set `false` to keep original coloring.
	 *
	 * @param {number|null} [opts.position=null]  
	 * Priority / ordering of the tooltip:  
	 * - `null` → default behavior  
	 * - Higher numbers push the tooltip lower  
	 * - Lower numbers pull it higher
	 *
	 * @param {boolean} [opts.last=false]  
	 * If true, forces these tooltip lines to appear at the bottom.
	 *
	 * @example
	 * // Simple tooltip
	 * tip("minecraft:apple", "A tasty snack!");
	 *
	 * // Multiple items, one tooltip line
	 * tip(["wooden_sword", "wooden_axe"], "We all start somewhere");
	 *
	 * // Multiple lines, requires SHIFT, placed last
	 * tip(/campfire/, ["Provides warmth", "Restores health"], { last: true });
	 */
	function tip(items, text, opts) {
		if (!opts) opts = {};

		addTooltipLine({
			items: Array.isArray(items) ? items : [items],
			text: Array.isArray(text) ? text : [text],
			gray: opts.gray !== undefined ? opts.gray : true,
			position: opts.position !== undefined ? opts.position : null,
			last: opts.last !== undefined ? opts.last : false
		});
	}

	function addTooltipLine(data) {
		// Unpack fields with manual defaults (KubeJS cannot use default parameters)
		var items = data.items;
		var text = Array.isArray(data.text) ? data.text : [data.text];
		var gray = data.gray !== undefined ? data.gray : true;
		var position = data.position !== undefined ? data.position : null;
		var last = data.last !== undefined ? data.last : false;

		event.addAdvanced(items, (item, advanced, tooltip) => {
			if (tooltip[0].toString().includes('Unknown Item')) return;

			var maxLen = 50;
			var iter = 0;

			var pos = last
				? (tooltip[tooltip.size() - 1].toString().includes('color=dark_gray')
					? tooltip.size() - 1
					: tooltip.size())
				: (position !== null ? position : 1);

			text.forEach(line => {
				wrapLine(line, maxLen).forEach(wrapped => {
					tooltip.add(pos + iter, gray ? Text.gray(wrapped) : Text.of(wrapped));
					iter++;
				});
			});
		});
	}

	function wrapLine(str, max) {
		var words = str.split(' ');
		var out = [];
		var current = '';

		words.forEach(word => {
			if ((current + word).length + 1 <= max)
				current += (current ? ' ' : '') + word;
			else {
				out.push(current);
				current = word;
			}
		});

		if (current) out.push(current);
		return out;
	}


	const TIP_CONFIG = [
		// Rediscovered
		{
			items: global.rediscoveredFurniture,
			text: 'Comes with a unique feeling of nostalgia'
		},
		{
			items: 'rediscovered:cyan_rose',
			text: 'Also known as Blue Rose'
		},

		// Starter tools
		{
			items: [
				'wooden_sword', 'wooden_axe', 'wooden_pickaxe',
				'wooden_hoe', 'wooden_shovel', 'shieldexp:wooden_shield'
			],
			text: 'We all have to start somewhere!'
		},

		// Bleeding items
		{
			items: [
				'golden_apple', 'enchanted_golden_apple',
				'majruszsdifficulty:bandage', 'majruszsdifficulty:golden_bandage'
			],
			text: 'Stops bleeding'
		},
		{
			items: 'enchanted_golden_apple',
			text: 'You can unenchant it. But why would you?',
			opts: { position: 2 }
		},

		// Campfires
		{
			items: /campfire/,
			text: 'Provides health regeneration'
		},

		// Sortilege
		{
			items: 'sortilege:limitite',
			text: [
				'Increases the maximum amount of enchantments an item can hold by 1, up to 3 total times',
				'Combine the item with it in a Smithing Table using Lapis Lazuli as the template for the recipe'
			]
		},

		// Dummy
		{
			items: 'dummmmmmy:target_dummy',
			text: [
				'An invulnerable, punchable dummy',
				'Quite perfect for measuring dealt damage'
			]
		},

		// Botania flowers
		{
			items: [
				/botania\:.*_mystical_flower/,
				/botania\:.*_double_flower/
			],
			text: 'It sparkles with magic'
		},
		{
			items: /botania\:apothecary.*/,
			text: 'The crafting table for all that is vivid'
		},
		{
			items: 'botania:diluted_pool',
			text: 'Has 10x smaller Mana capacity than a normal Mana Pool'
		},

		// Small misc
		{ items: 'berry_good:glowgurt', text: 'Gurt: Glow.' },
		{ items: 'suspicious_stew', text: 'Like a box of chocolates, just disgusting' },

		// Quark
		{
			items: 'quark:seed_pouch',
			text: 'Can hold 10 stacks of Bone Meal or any Seed, Sapling, Crop or Mushroom'
		},
		{
			items: 'quark:slime_in_a_bucket',
			text: 'Jumps with enthusiasm if you are in a slime chunk'
		},

		// Compass / time / depth
		{
			items: ['minecraft:compass', 'minecraft:recovery_compass'],
			text: 'Tells your horizontal location'
		},
		{
			items: ['minecraft:clock', 'mythicmetals:platinum_watch'],
			text: 'Tells the time and weather'
		},
		{
			items: 'additionaladditions:depth_meter',
			text: 'Tells your vertical location'
		},
		{
			items: [
				'additionaladditions:depth_meter',
				'minecraft:clock', 'minecraft:compass',
				'minecraft:recovery_compass', 'mythicmetals:platinum_watch'
			],
			text: 'Works from a Bundle',
			opts: { position: 2 }
		},
		{
			items: 'minecraft:recovery_compass',
			text: 'Points you towards the location of your last death',
			opts: { position: 3 }
		},

		// Botania floating + chibi
		{
			items: [
				/botania:floating/,
				/botanicadds:*.floating.*/
			],
			text: 'Can be planted on any surface'
		},
		{
			items: /botania:.*_chibi/,
			text: 'Has a smaller area of effect than its regular size counterpart',
			opts: { position: 1 }
		},

		// Netherexp
		{
			items: [
				/netherexp:etched_.*/,
				/netherexp:chiseled_soul_slate_.*/
			],
			text: 'Can be ignited with Flint and Steel'
		},

		// Domestication Innovation
		{
			items: /domesticationinnovation:pet_bed/,
			text: [
				'Allows your pets to respawn at dawn',
				'Move your pet onto the pet bed to set its respawn point'
			]
		},
		{
			items: 'domesticationinnovation:collar_tag',
			text: [
				'Can be enchanted',
				'Give it to your pet to transfer the enchantments\' power to it'
			]
		},

		// Misc single items
		{ items: 'bell', text: 'Ring while holding an Emerald to call a Wandering Trader' },
		{ items: 'upgrade_aquatic:elder_eye', text: 'Emits redstone signal if there is an entity in front of it' },
		{ items: 'cauldron', text: 'Can be used to brew some basic potions' },
		{ items: 'majruszsdifficulty:recall_potion', text: 'Teleports you to your spawn point' },
		{ items: 'naturescompass:naturescompass', text: 'Points in the direction of any biome in the world' },
		{ items: /bedroll/, text: 'Also known as \'sleeping bag\'' },

		// Alex’s Caves
		{
			items: 'alexscaves:dreadbow',
			text: [
				'Does the name \'Daedalous Stormbow\' ring a bell perchance?',
				'Rains Darkness Arrows around target location'
			]
		},
		{
			items: 'alexscaves:desolate_dagger',
			text: [
				'Summons extra copies of itself on hit which hit with a delayed impact',
				'Copies deal low, but armor-piercing damage'
			]
		},

		// Alloy Controllers (all last = true)
		{
			items: 'alloy_forgery:cracked_stone_bricks_forge_controller',
			text: ['Speed Multiplier: 1.0x', 'Building Material: Stone Bricks (+Variants)'],
			opts: { last: true }
		},
		{
			items: 'alloy_forgery:cracked_deepslate_bricks_forge_controller',
			text: ['Speed Multiplier: 1.25x', 'Building Material: Deepslate Bricks (+Variants)'],
			opts: { last: true }
		},
		{
			items: 'alloy_forgery:nether_bricks_forge_controller',
			text: ['Speed Multiplier: 1.75x', 'Building Material: Nether Bricks (+Variants)'],
			opts: { last: true }
		},
		{
			items: 'alloy_forgery:adamantite_forge_casing_forge_controller',
			text: ['Speed Multiplier: 2.0x', 'Building Material: Adamantite Forge Casing'],
			opts: { last: true }
		},
		{
			items: 'alloy_forgery:ender_forge_casing_forge_controller',
			text: ['Speed Multiplier: 2.5x', 'Building Material: Ender Forge Casing'],
			opts: { last: true }
		},

		// Alloy casing
		{
			items: /adj\:.*forge_casing/,
			text: 'Used to build an Alloy Forge'
		},

		// Mythic Metals / Majrusz
		{ items: 'majruszsdifficulty:enderium_helmet', text: 'Makes all Endermen less hostile' },
		{ items: 'mythicmetals:hallowed_ingot', text: 'Seems oddly familiar...' },
		{ items: 'mythicmetals:orichalcum_hammer', text: 'Mines a 3x2 area' },

		// Galosphere
		{ items: 'galosphere:allurite_block', text: 'Silences nearby blocks' },
		{ items: 'galosphere:monstrometer', text: 'Requires Lumiere Blocks as fuel' },
		{ items: 'galosphere:warped_anchor', text: 'Requires Allurite Blocks as fuel' },
		{ items: 'galosphere:combustion_table', text: 'Used to customize Silver Bombs' },
		{ items: 'galosphere:stranded_membrane_block', text: 'Pushes items and entities in the direction its facing' },
		{
			items: 'galosphere:silver_balance',
			text: 'Produces a redstone signal that gets stronger the harder the block placed directly on top of it is to break'
		},

		// Wither Storm Mod
		{
			items: 'witherstormmod:command_block_book',
			text: 'Combine with any Diamond tool in an Anvil to create a Command Block tool'
		},
		{
			items: 'witherstormmod:firework_bundle',
			text: 'Might distract The Wither Storm when activated'
		},
		{
			items: 'witherstormmod:super_tnt',
			text: 'Creates a bit bigger explosion than a regular TNT'
		},
		{
			items: 'witherstormmod:formidibomb',
			text: [
				'The key to defeating The Wither Storm',
				'Place it nearby and detonate once it has 3 heads',
				'Creates a massive explosion on its own'
			]
		},

		// Ars Nouveau
		{
			items: /ars_nouveau:arcanist/,
			text: [
				'Can be upgraded (twice total)',
				'Can be imbued with different magical threads'
			]
		},

		// Mutant Monsters
		{
			items: [
				'mutantmonsters:mutant_skeleton_skull',
				'mutantmonsters:mutant_skeleton_chestplate',
				'mutantmonsters:mutant_skeleton_leggings',
				'mutantmonsters:mutant_skeleton_boots'
			],
			text: 'WIP! PLEASE DON\'T USE'
		},

		// Delight stoves
		{
			items: /.*delight.*:.*stove.*/,
			text: 'Acts like a Campfire with 6 total slots'
		},

		// Heart crystals
		{
			items: 'heart_crystals:heart_crystal',
			text: 'Increases max health by 20, up to 400'
		},

		// Naturalist
		{
			items: 'naturalist:bug_net',
			text: 'Used to catch butterflies'
		},

		// Bumblezone
		{
			items: /the_bumblezone:string_curtain/,
			text: 'Can be extended downwards by right-clicking with a String'
		},

		// MCDW
		{
			items: /mcdw:soul_dagger/,
			text: 'Attacks temporarily boost mana regeneration'
		}
	];

	for (const entry of TIP_CONFIG) {
		tip(entry.items, entry.text, entry.opts);
	}
})
