package xyz.tront.trontmod;

import java.util.function.Function;

import net.fabricmc.fabric.api.creativetab.v1.CreativeModeTabEvents;
import net.minecraft.core.Registry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.CreativeModeTabs;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.ToolMaterial;

/**
 * All items live here. Each one is a static final field so the registry entry is created
 * exactly once, when this class is first touched (from TrontMod.onInitialize via initialize()).
 * TUTORIAL.md lessons 3 and 4 walk this file top to bottom; the TUTORIAL(n) markers point at sections.
 */
public final class ModItems {
	private ModItems() {}

	// ---- materials ----

	/**
	 * TUTORIAL(4.3): a tag is a named list of item ids defined in JSON, not here.
	 * What repairs emerald gear in an anvil. Backed by data/trontmod/tags/item/emerald_tool_materials.json
	 */
	public static final TagKey<Item> EMERALD_TOOL_MATERIALS =
		TagKey.create(Registries.ITEM, TrontMod.id("emerald_tool_materials"));

	/**
	 * TUTORIAL(4.2): the emerald tier. Fields: blocks-it-can't-mine tag, durability, mining speed,
	 * attack damage bonus, enchantability, repair-items tag.
	 * Vanilla for reference (durability/speed/bonus/enchantability): IRON 250/6/2/14, DIAMOND 1561/8/3/10,
	 * NETHERITE 2031/9/4/15. Emerald hits like diamond, wears faster, enchants better.
	 */
	public static final ToolMaterial EMERALD_MATERIAL = new ToolMaterial(
		BlockTags.INCORRECT_FOR_DIAMOND_TOOL, 1200, 8.0F, 3.0F, 20, EMERALD_TOOL_MATERIALS);

	// ---- items ----

	/** TUTORIAL(3.1): the simplest possible item. No behaviour, stacks to 64, shows in Ingredients. */
	public static final Item TRONT_COIN = register("tront_coin", Item::new, new Item.Properties());

	/**
	 * TUTORIAL(4.1): same shape as vanilla Items.DIAMOND_SWORD. There is no SwordItem class any more; a plain
	 * Item whose Properties.sword(...) call attaches the durability / attribute / TOOL / WEAPON components.
	 * Damage = 3 baseline + 3 material bonus + 1 player base = 7. Attack speed -2.4 (same as every sword).
	 */
	public static final Item EMERALD_SWORD = register("emerald_sword", Item::new,
		new Item.Properties().sword(EMERALD_MATERIAL, 3.0F, -2.4F));

	/**
	 * TUTORIAL(3.1): how every item gets into the game. Build the key (registry + trontmod:<name>),
	 * tell the properties their id, construct the item, put it in the item registry.
	 *
	 * @param name    path part of the id; becomes trontmod:<name>. Must match the JSON/PNG filenames.
	 * @param factory usually Item::new, or MyItem::new for custom behaviour
	 * @param props   stack size, durability, food, etc. setId() is applied for you
	 */
	public static Item register(String name, Function<Item.Properties, Item> factory, Item.Properties props) {
		ResourceKey<Item> key = ResourceKey.create(Registries.ITEM, TrontMod.id(name));
		Item item = factory.apply(props.setId(key));
		return Registry.register(BuiltInRegistries.ITEM, key, item);
	}

	/**
	 * TUTORIAL(3.3): registered items are invisible in the creative menu until you add them to a tab.
	 * Calling this method also forces the static fields above to run (that's the registration moment).
	 */
	public static void initialize() {
		CreativeModeTabEvents.modifyOutputEvent(CreativeModeTabs.INGREDIENTS)
			.register(output -> output.accept(TRONT_COIN));
		CreativeModeTabEvents.modifyOutputEvent(CreativeModeTabs.COMBAT)
			.register(output -> output.insertAfter(Items.DIAMOND_SWORD, EMERALD_SWORD));
	}
}
