package protocolsupport.protocol.serializer.chat;

import org.bukkit.inventory.ItemStack;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import protocolsupport.api.ProtocolVersion;
import protocolsupport.api.chat.components.BaseComponent;
import protocolsupport.api.chat.modifiers.HoverAction;
import protocolsupport.api.chat.modifiers.HoverAction.EntityInfo;
import protocolsupport.protocol.typeremapper.entity.LegacyNetworkEntityRegistry;
import protocolsupport.protocol.typeremapper.entity.LegacyNetworkEntityRegistry.LegacyNetworkEntityTable;
import protocolsupport.protocol.typeremapper.entity.NetworkEntityDataFormatTransformRegistry;
import protocolsupport.protocol.typeremapper.entity.NetworkEntityDataFormatTransformRegistry.NetworkEntityDataFormatTransformerTable;
import protocolsupport.protocol.typeremapper.itemstack.FlatteningItemId;
import protocolsupport.protocol.typeremapper.itemstack.ItemStackRemappingHelper;
import protocolsupport.protocol.typeremapper.legacy.LegacyEntityId;
import protocolsupport.protocol.typeremapper.utils.MappingTable.ArrayBasedIntMappingTable;
import protocolsupport.protocol.types.NetworkBukkitItemStack;
import protocolsupport.protocol.types.NetworkItemStack;
import protocolsupport.protocol.types.nbt.NBTByte;
import protocolsupport.protocol.types.nbt.NBTCompound;
import protocolsupport.protocol.types.nbt.NBTShort;
import protocolsupport.protocol.types.nbt.NBTString;
import protocolsupport.protocol.types.nbt.mojangson.LegacyMojangsonSerializer;
import protocolsupport.protocol.types.nbt.mojangson.MojangsonSerializer;
import protocolsupport.protocol.types.networkentity.NetworkEntityType;
import protocolsupport.protocol.utils.ItemMaterialLookup;
import protocolsupport.protocol.utils.ItemStackWriteEventHelper;
import protocolsupport.protocol.utils.json.SimpleJsonTreeSerializer;
import protocolsupport.utils.JsonUtils;

public class LegacyValueHoverActionSerializer extends HoverActionSerializer {

	protected final ProtocolVersion version;
	protected final LegacyNetworkEntityTable legacyEntityEntryTable;
	protected final NetworkEntityDataFormatTransformerTable entityDataFormatTable;
	protected final ArrayBasedIntMappingTable flatteningItemFromClientTable;

	public LegacyValueHoverActionSerializer(ProtocolVersion version) {
		this.version = version;
		this.legacyEntityEntryTable = LegacyNetworkEntityRegistry.INSTANCE.getTable(version);
		this.entityDataFormatTable = NetworkEntityDataFormatTransformRegistry.INSTANCE.getTable(version);
		this.flatteningItemFromClientTable = FlatteningItemId.REGISTRY_FROM_CLIENT.getTable(version);
	}

	@Override
	public JsonElement serialize(SimpleJsonTreeSerializer<String> serializer, HoverAction action, String locale) {
		JsonObject json = new JsonObject();

		json.addProperty(key_action, action.getType().toString().toLowerCase());

		switch (action.getType()) {
			case SHOW_TEXT: {
				json.add("value", serializer.serialize(action.getContents(), locale));
				break;
			}
			case SHOW_ENTITY: {
				EntityInfo entityinfo = (EntityInfo) action.getContents();
				NetworkEntityType etype = legacyEntityEntryTable.get(NetworkEntityType.getByBukkitType(entityinfo.getType())).getType();
				if (etype != NetworkEntityType.NONE) {
					etype = entityDataFormatTable.get(etype).getKey();
				}
				NBTCompound rootTag = new NBTCompound();
				rootTag.setTag("type", new NBTString(version.isAfterOrEq(ProtocolVersion.MINECRAFT_1_11) ? etype.getKey() : LegacyEntityId.getStringId(etype)));
				rootTag.setTag("id", new NBTString(entityinfo.getUUID().toString()));
				BaseComponent name = entityinfo.getDisplayName();
				if (name != null) {
					rootTag.setTag("name", new NBTString(JsonUtils.GSON.toJson(serializer.serialize(name, locale))));
				}
				json.addProperty("value", serializeTagToMojanson(rootTag));
				break;
			}
			case SHOW_ITEM: {
				NetworkItemStack itemstack = NetworkBukkitItemStack.create((ItemStack) action.getContents());
				ItemStackWriteEventHelper.callEvent(version, locale, itemstack);
				itemstack = ItemStackRemappingHelper.toLegacyItemDataFormat(version, locale, itemstack);
				NBTCompound rootTag = new NBTCompound();
				if (version.isAfterOrEq(ProtocolVersion.MINECRAFT_1_13)) {
					//TODO: create and use mappings for legacy item id -> item material
					rootTag.setTag("id", new NBTString(ItemMaterialLookup.getByRuntimeId(flatteningItemFromClientTable.get(itemstack.getTypeId())).getKey().toString()));
				} else {
					if (version.isAfterOrEq(ProtocolVersion.MINECRAFT_1_8)) {
						rootTag.setTag("id", new NBTString(String.valueOf(itemstack.getTypeId())));
					} else {
						rootTag.setTag("id", new NBTShort((short) itemstack.getTypeId()));
					}
					rootTag.setTag("Damage", new NBTShort((short) itemstack.getLegacyData()));
				}
				rootTag.setTag("Count", new NBTByte((byte) itemstack.getAmount()));
				rootTag.setTag("tag", itemstack.getNBT());
				json.addProperty("value", serializeTagToMojanson(rootTag));
			}
		}

		return json;
	}

	protected String serializeTagToMojanson(NBTCompound tag) {
		return version.isAfterOrEq(ProtocolVersion.MINECRAFT_1_12) ? MojangsonSerializer.serialize(tag) : LegacyMojangsonSerializer.serialize(tag);
	}

}

@@ -798,81 +798,8 @@
 le;%0A
-import protocolsupport.protocol.typeremapper.itemstack.FlatteningItemId;%0A
 impo
@@ -947,99 +947,8 @@
 Id;%0A
-import protocolsupport.protocol.typeremapper.utils.MappingTable.ArrayBasedIntMappingTable;%0A
 impo
@@ -1998,82 +1998,8 @@
 ble;
-%0A%09protected final ArrayBasedIntMappingTable flatteningItemFromClientTable;
 %0A%0A%09p
@@ -2282,104 +2282,8 @@
 n);%0A
-%09%09this.flatteningItemFromClientTable = FlatteningItemId.REGISTRY_FROM_CLIENT.getTable(version);%0A
 %09%7D%0A%0A
@@ -3758,22 +3758,16 @@
 ItemData
-Format
 (version
@@ -3913,67 +3913,56 @@
 DO: 
-create and use mappings for legacy item id -%3E item material
+also apply legacy string id (after creating one)
 %0A%09%09%09
@@ -4036,42 +4036,8 @@
 eId(
-flatteningItemFromClientTable.get(
 item
@@ -4054,17 +4054,16 @@
 ypeId())
-)
 .getKey(
@@ -4087,24 +4087,114 @@
 %09%09%09%7D else %7B%0A
+%09%09%09%09%09itemstack = ItemStackRemappingHelper.toLegacyItemFormat(version, locale, itemstack);%0A
 %09%09%09%09%09if (ver
@@ -4689,16 +4689,27 @@
 tTag));%0A
+%09%09%09%09break;%0A
 %09%09%09%7D%0A%09%09%7D

Use 2 stage items mapping in legacy hover serializer