package com.hypixel.hytale.builtin.asseteditor;

import com.hypixel.hytale.assetstore.AssetStore;
import com.hypixel.hytale.assetstore.AssetUpdateQuery;
import com.hypixel.hytale.assetstore.event.LoadedAssetsEvent;
import com.hypixel.hytale.assetstore.map.BlockTypeAssetMap;
import com.hypixel.hytale.assetstore.map.IndexedLookupTableAssetMap;
import com.hypixel.hytale.builtin.asseteditor.assettypehandler.AssetStoreTypeHandler;
import com.hypixel.hytale.builtin.asseteditor.assettypehandler.AssetTypeHandler;
import com.hypixel.hytale.builtin.asseteditor.event.AssetEditorActivateButtonEvent;
import com.hypixel.hytale.builtin.asseteditor.event.AssetEditorAssetCreatedEvent;
import com.hypixel.hytale.builtin.asseteditor.event.AssetEditorClientDisconnectEvent;
import com.hypixel.hytale.builtin.asseteditor.event.AssetEditorFetchAutoCompleteDataEvent;
import com.hypixel.hytale.builtin.asseteditor.event.AssetEditorRequestDataSetEvent;
import com.hypixel.hytale.builtin.asseteditor.event.AssetEditorSelectAssetEvent;
import com.hypixel.hytale.builtin.asseteditor.event.AssetEditorUpdateWeatherPreviewLockEvent;
import com.hypixel.hytale.component.Ref;
import com.hypixel.hytale.component.Store;
import com.hypixel.hytale.event.EventRegistry;
import com.hypixel.hytale.logger.HytaleLogger;
import com.hypixel.hytale.protocol.InstantData;
import com.hypixel.hytale.protocol.Model;
import com.hypixel.hytale.protocol.Vector2f;
import com.hypixel.hytale.protocol.Vector3f;
import com.hypixel.hytale.protocol.packets.asseteditor.AssetEditorPopupNotificationType;
import com.hypixel.hytale.protocol.packets.asseteditor.AssetEditorPreviewCameraSettings;
import com.hypixel.hytale.protocol.packets.asseteditor.AssetEditorUpdateModelPreview;
import com.hypixel.hytale.protocol.packets.asseteditor.AssetEditorUpdateSecondsPerGameDay;
import com.hypixel.hytale.protocol.packets.world.ClearEditorTimeOverride;
import com.hypixel.hytale.protocol.packets.world.UpdateEditorTimeOverride;
import com.hypixel.hytale.protocol.packets.world.UpdateEditorWeatherOverride;
import com.hypixel.hytale.server.core.Message;
import com.hypixel.hytale.server.core.asset.type.blocktype.config.BlockType;
import com.hypixel.hytale.server.core.asset.type.environment.config.Environment;
import com.hypixel.hytale.server.core.asset.type.item.config.AssetIconProperties;
import com.hypixel.hytale.server.core.asset.type.item.config.Item;
import com.hypixel.hytale.server.core.asset.type.item.config.ItemArmor;
import com.hypixel.hytale.server.core.asset.type.model.config.ModelAsset;
import com.hypixel.hytale.server.core.asset.type.weather.config.Weather;
import com.hypixel.hytale.server.core.entity.entities.Player;
import com.hypixel.hytale.server.core.inventory.ItemStack;
import com.hypixel.hytale.server.core.io.PacketHandler;
import com.hypixel.hytale.server.core.modules.entity.component.ModelComponent;
import com.hypixel.hytale.server.core.modules.entity.player.PlayerSkinComponent;
import com.hypixel.hytale.server.core.modules.i18n.I18nModule;
import com.hypixel.hytale.server.core.modules.item.ItemModule;
import com.hypixel.hytale.server.core.modules.time.WorldTimeResource;
import com.hypixel.hytale.server.core.universe.PlayerRef;
import com.hypixel.hytale.server.core.universe.world.PlayerUtil;
import com.hypixel.hytale.server.core.universe.world.World;
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import java.nio.file.Path;
import java.time.Instant;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

@Deprecated
public class AssetSpecificFunctionality {
   private static final Message NO_GAME_CLIENT_MESSAGE = Message.translation("server.assetEditor.messages.noGameClient");
   private static final ClearEditorTimeOverride CLEAR_EDITOR_TIME_OVERRIDE_PACKET = new ClearEditorTimeOverride();
   private static final UpdateEditorWeatherOverride CLEAR_WEATHER_OVERRIDE_PACKET = new UpdateEditorWeatherOverride(0);
   private static final String MODEL_ASSET_ID = ModelAsset.class.getSimpleName();
   private static final String ITEM_ASSET_ID = Item.class.getSimpleName();
   private static final String WEATHER_ASSET_ID = Weather.class.getSimpleName();
   private static final String ENVIRONMENT_ASSET_ID = Environment.class.getSimpleName();
   private static final Map<UUID, AssetSpecificFunctionality.PlayerPreviewData> activeWeatherPreviewMapping = new ConcurrentHashMap<>();
   private static final AssetEditorPreviewCameraSettings DEFAULT_PREVIEW_CAMERA_SETTINGS = new AssetEditorPreviewCameraSettings(
      0.25F, new Vector3f(0.0F, 75.0F, 0.0F), new Vector3f(0.0F, (float)Math.toRadians(45.0), 0.0F)
   );

   public static void setup() {
      getEventRegistry().register(LoadedAssetsEvent.class, ModelAsset.class, AssetSpecificFunctionality::onModelAssetLoaded);
      getEventRegistry().register(LoadedAssetsEvent.class, Item.class, AssetSpecificFunctionality::onItemAssetLoaded);
      getEventRegistry().register(AssetEditorActivateButtonEvent.class, "EquipItem", AssetSpecificFunctionality::onEquipItem);
      getEventRegistry().register(AssetEditorActivateButtonEvent.class, "UseModel", AssetSpecificFunctionality::onUseModel);
      getEventRegistry().register(AssetEditorActivateButtonEvent.class, "ResetModel", AssetSpecificFunctionality::onResetModel);
      getEventRegistry().register(AssetEditorUpdateWeatherPreviewLockEvent.class, AssetSpecificFunctionality::onUpdateWeatherPreviewLockEvent);
      getEventRegistry().register(AssetEditorAssetCreatedEvent.class, ITEM_ASSET_ID, AssetSpecificFunctionality::onItemAssetCreated);
      getEventRegistry().register(AssetEditorAssetCreatedEvent.class, MODEL_ASSET_ID, AssetSpecificFunctionality::onModelAssetCreated);
      getEventRegistry().register(AssetEditorFetchAutoCompleteDataEvent.class, "BlockGroups", AssetSpecificFunctionality::onRequestBlockGroupsDataSet);
      getEventRegistry().register(AssetEditorFetchAutoCompleteDataEvent.class, "LocalizationKeys", AssetSpecificFunctionality::onRequestLocalizationKeyDataSet);
      getEventRegistry().register(AssetEditorRequestDataSetEvent.class, "ItemCategories", AssetSpecificFunctionality::onRequestItemCategoriesDataSet);
      getEventRegistry().registerGlobal(AssetEditorSelectAssetEvent.class, AssetSpecificFunctionality::onSelectAsset);
      getEventRegistry().registerGlobal(AssetEditorClientDisconnectEvent.class, AssetSpecificFunctionality::onClientDisconnected);
   }

   @Nullable
   private static PlayerRef tryGetPlayer(@Nonnull EditorClient editorClient) {
      PlayerRef playerRef = editorClient.tryGetPlayer();
      if (playerRef == null) {
         editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Warning, NO_GAME_CLIENT_MESSAGE);
         return null;
      } else {
         return playerRef;
      }
   }

   private static void onModelAssetLoaded(@Nonnull LoadedAssetsEvent<String, ModelAsset, ?> event) {
      if (!event.isInitial()) {
         Map<EditorClient, AssetPath> clientOpenAssetPathMapping = AssetEditorPlugin.get().getClientOpenAssetPathMapping();
         if (!clientOpenAssetPathMapping.isEmpty()) {
            for (ModelAsset modelAsset : event.getLoadedAssets().values()) {
               for (Entry<EditorClient, AssetPath> editor : clientOpenAssetPathMapping.entrySet()) {
                  Path path = editor.getValue().path();
                  if (!path.toString().isEmpty()) {
                     AssetTypeHandler assetType = AssetEditorPlugin.get().getAssetTypeRegistry().getAssetTypeHandlerForPath(path);
                     if (assetType instanceof AssetStoreTypeHandler
                        && ((AssetStoreTypeHandler)assetType).getAssetStore().getAssetClass().equals(ModelAsset.class)) {
                        String id = ModelAsset.getAssetStore().decodeFilePathKey(path);
                        if (modelAsset.getId().equals(id)) {
                           Model modelPacket = com.hypixel.hytale.server.core.asset.type.model.config.Model.createUnitScaleModel(modelAsset).toPacket();
                           AssetEditorUpdateModelPreview packet = new AssetEditorUpdateModelPreview(
                              editor.getValue().toPacket(), modelPacket, null, DEFAULT_PREVIEW_CAMERA_SETTINGS
                           );
                           editor.getKey().getPacketHandler().write(packet);
                        }
                     }
                  }
               }
            }
         }
      }
   }

   private static void onItemAssetLoaded(@Nonnull LoadedAssetsEvent<String, Item, ?> event) {
      if (!event.isInitial()) {
         Map<EditorClient, AssetPath> clientOpenAssetPathMapping = AssetEditorPlugin.get().getClientOpenAssetPathMapping();
         if (!clientOpenAssetPathMapping.isEmpty()) {
            AssetUpdateQuery.RebuildCache rebuildCache = event.getQuery().getRebuildCache();
            if (rebuildCache.isBlockTextures() || rebuildCache.isModelTextures() || rebuildCache.isItemIcons() || rebuildCache.isModels()) {
               for (Item item : event.getLoadedAssets().values()) {
                  for (Entry<EditorClient, AssetPath> editor : clientOpenAssetPathMapping.entrySet()) {
                     Path path = editor.getValue().path();
                     if (!path.toString().isEmpty()) {
                        AssetTypeHandler assetType = AssetEditorPlugin.get().getAssetTypeRegistry().getAssetTypeHandlerForPath(path);
                        if (assetType instanceof AssetStoreTypeHandler && ((AssetStoreTypeHandler)assetType).getAssetStore().getAssetClass().equals(Item.class)
                           )
                         {
                           String id = Item.getAssetStore().decodeFilePathKey(path);
                           if (item.getId().equals(id)) {
                              AssetEditorUpdateModelPreview packet = getModelPreviewPacketForItem(editor.getValue(), item);
                              if (packet != null) {
                                 editor.getKey().getPacketHandler().write(packet);
                              }
                           }
                        }
                     }
                  }
               }
            }
         }
      }
   }

   private static void onItemAssetCreated(@Nonnull AssetEditorAssetCreatedEvent event) {
      if ("EquipItem".equals(event.getButtonId())) {
         equipItem(event.getAssetPath(), event.getEditorClient());
      }
   }

   private static void onModelAssetCreated(@Nonnull AssetEditorAssetCreatedEvent event) {
      if ("UseModel".equals(event.getButtonId())) {
         useModel(event.getAssetPath(), event.getEditorClient());
      }
   }

   private static void onEquipItem(@Nonnull AssetEditorActivateButtonEvent event) {
      AssetPath currentAssetPath = AssetEditorPlugin.get().getOpenAssetPath(event.getEditorClient());
      if (currentAssetPath != null && !currentAssetPath.path().toString().isEmpty()) {
         equipItem(currentAssetPath.path(), event.getEditorClient());
      }
   }

   private static void onUseModel(@Nonnull AssetEditorActivateButtonEvent event) {
      AssetPath currentAssetPath = AssetEditorPlugin.get().getOpenAssetPath(event.getEditorClient());
      if (currentAssetPath != null && !currentAssetPath.path().toString().isEmpty()) {
         useModel(currentAssetPath.path(), event.getEditorClient());
      }
   }

   private static void onUpdateWeatherPreviewLockEvent(@Nonnull AssetEditorUpdateWeatherPreviewLockEvent event) {
      AssetSpecificFunctionality.PlayerPreviewData currentPreviewSettings = activeWeatherPreviewMapping.computeIfAbsent(
         event.getEditorClient().getUuid(), k -> new AssetSpecificFunctionality.PlayerPreviewData()
      );
      currentPreviewSettings.keepPreview = event.isLocked();
   }

   private static void onResetModel(@Nonnull AssetEditorActivateButtonEvent event) {
      EditorClient editorClient = event.getEditorClient();
      PlayerRef playerRef = tryGetPlayer(editorClient);
      if (playerRef != null) {
         Ref<EntityStore> ref = playerRef.getReference();
         if (ref != null && ref.isValid()) {
            Store<EntityStore> store = ref.getStore();
            World world = store.getExternalData().getWorld();
            world.execute(() -> {
               if (!store.getArchetype(ref).contains(PlayerSkinComponent.getComponentType())) {
                  Message message = Message.translation("server.assetEditor.messages.model.noAuthSkinForPlayer").param("model", "Player");
                  editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, message);
               } else {
                  PlayerUtil.resetPlayerModel(ref, store);
               }
            });
         }
      }
   }

   private static void equipItem(@Nonnull Path assetPath, @Nonnull EditorClient editorClient) {
      PlayerRef playerRef = tryGetPlayer(editorClient);
      if (playerRef != null) {
         Player player = playerRef.getComponent(Player.getComponentType());
         String key = Item.getAssetStore().decodeFilePathKey(assetPath);
         Item item = Item.getAssetMap().getAsset(key);
         if (item == null) {
            editorClient.sendPopupNotification(
               AssetEditorPopupNotificationType.Error, Message.translation("server.assetEditor.messages.unknownItem").param("id", key.toString())
            );
         } else {
            ItemArmor itemArmor = item.getArmor();
            if (itemArmor != null) {
               player.getInventory().getArmor().setItemStackForSlot((short)itemArmor.getArmorSlot().ordinal(), new ItemStack(key));
            } else {
               player.getInventory().getCombinedHotbarFirst().addItemStack(new ItemStack(key));
            }
         }
      }
   }

   private static void useModel(@Nonnull Path assetPath, @Nonnull EditorClient editorClient) {
      PlayerRef playerRef = tryGetPlayer(editorClient);
      if (playerRef != null) {
         Ref<EntityStore> ref = playerRef.getReference();
         if (ref != null && ref.isValid()) {
            Store<EntityStore> store = ref.getStore();
            World world = store.getExternalData().getWorld();
            world.execute(
               () -> {
                  String key = ModelAsset.getAssetStore().decodeFilePathKey(assetPath);
                  ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset(key);
                  if (modelAsset == null) {
                     Message unknownModelMessage = Message.translation("server.assetEditor.messages.unknownModel").param("id", key);
                     editorClient.sendPopupNotification(AssetEditorPopupNotificationType.Error, unknownModelMessage);
                  } else {
                     com.hypixel.hytale.server.core.asset.type.model.config.Model model = com.hypixel.hytale.server.core.asset.type.model.config.Model.createRandomScaleModel(
                        modelAsset
                     );
                     store.putComponent(ref, ModelComponent.getComponentType(), new ModelComponent(model));
                  }
               }
            );
         }
      }
   }

   private static void onRequestLocalizationKeyDataSet(@Nonnull AssetEditorFetchAutoCompleteDataEvent event) {
      ObjectArrayList<String> results = new ObjectArrayList<>();
      String query = event.getQuery().toLowerCase();

      for (String key : I18nModule.get().getMessages("en-US").keySet()) {
         if (key.toLowerCase().startsWith(query)) {
            results.add(key);
         }

         if (results.size() >= 25) {
            break;
         }
      }

      event.setResults(results.toArray(String[]::new));
   }

   private static void onRequestBlockGroupsDataSet(@Nonnull AssetEditorFetchAutoCompleteDataEvent event) {
      ObjectArrayList<String> results = new ObjectArrayList<>();
      String query = event.getQuery().toLowerCase();

      for (String group : BlockType.getAssetMap().getGroups()) {
         if (group != null && !group.trim().isEmpty() && (query.isEmpty() || group.toLowerCase().contains(query))) {
            results.add(group);
         }
      }

      event.setResults(results.toArray(String[]::new));
   }

   private static void onRequestItemCategoriesDataSet(@Nonnull AssetEditorRequestDataSetEvent event) {
      ItemModule itemModule = ItemModule.get();
      if (itemModule.isDisabled()) {
         HytaleLogger.getLogger().at(Level.WARNING).log("Received ItemCategories dataset request but ItemModule is disabled!");
      } else {
         event.setResults(itemModule.getFlatItemCategoryList().toArray(String[]::new));
      }
   }

   private static void onClientDisconnected(@Nonnull AssetEditorClientDisconnectEvent event) {
      AssetEditorPlugin plugin = AssetEditorPlugin.get();
      EditorClient editorClient = event.getEditorClient();
      PlayerRef player = editorClient.tryGetPlayer();
      UUID uuid = editorClient.getUuid();
      Set<EditorClient> editorClients = plugin.getEditorClients(uuid);
      if (editorClients != null && editorClients.size() != 1) {
         AssetPath openAssetPath = plugin.getOpenAssetPath(editorClient);
         if (openAssetPath != null && !openAssetPath.equals(AssetPath.EMPTY_PATH)) {
            AssetTypeHandler assetType = plugin.getAssetTypeRegistry().getAssetTypeHandlerForPath(openAssetPath.path());
            if (assetType != null && Weather.class.getSimpleName().equals(assetType.getConfig().id)) {
               activeWeatherPreviewMapping.remove(uuid);
               if (player != null) {
                  player.getPacketHandler().write(new UpdateEditorWeatherOverride(0));
               }
            }
         }
      } else {
         if (player != null) {
            player.getPacketHandler().write(CLEAR_EDITOR_TIME_OVERRIDE_PACKET);
            player.getPacketHandler().write(CLEAR_WEATHER_OVERRIDE_PACKET);
         }

         activeWeatherPreviewMapping.remove(uuid);
      }
   }

   static void resetTimeSettings(@Nonnull EditorClient editorClient, @Nonnull PlayerRef playerRef) {
      Ref<EntityStore> ref = playerRef.getReference();
      if (ref != null && ref.isValid()) {
         Store<EntityStore> store = ref.getStore();
         World world = store.getExternalData().getWorld();
         Player playerComponent = playerRef.getComponent(Player.getComponentType());

         assert playerComponent != null;

         WorldTimeResource worldTimeResource = store.getResource(WorldTimeResource.getResourceType());
         PacketHandler packetHandler = editorClient.getPacketHandler();
         AssetEditorUpdateSecondsPerGameDay settingsPacket = new AssetEditorUpdateSecondsPerGameDay(
            world.getDaytimeDurationSeconds(), world.getNighttimeDurationSeconds()
         );
         packetHandler.write(settingsPacket);
         Instant gameTime = worldTimeResource.getGameTime();
         UpdateEditorTimeOverride packet = new UpdateEditorTimeOverride(
            new InstantData(gameTime.getEpochSecond(), gameTime.getNano()), world.getWorldConfig().isGameTimePaused()
         );
         packetHandler.write(packet);
         playerRef.getPacketHandler().write(CLEAR_EDITOR_TIME_OVERRIDE_PACKET);
      }
   }

   static void handleWeatherOrEnvironmentUnselected(@Nonnull EditorClient editorClient, @Nonnull Path assetPath, boolean wasWeather) {
      PlayerRef player = editorClient.tryGetPlayer();
      if (player != null) {
         AssetSpecificFunctionality.PlayerPreviewData currentPreviewSettings = activeWeatherPreviewMapping.computeIfAbsent(
            editorClient.getUuid(), k -> new AssetSpecificFunctionality.PlayerPreviewData()
         );
         if (!currentPreviewSettings.keepPreview) {
            resetTimeSettings(editorClient, player);
            if (wasWeather) {
               if (!assetPath.equals(currentPreviewSettings.weatherAssetPath)) {
                  return;
               }

               currentPreviewSettings.weatherAssetPath = null;
               player.getPacketHandler().write(CLEAR_WEATHER_OVERRIDE_PACKET);
            }
         }
      }
   }

   static void handleWeatherOrEnvironmentSelected(@Nonnull EditorClient editorClient, @Nonnull Path assetPath, boolean isWeather) {
      PlayerRef player = editorClient.tryGetPlayer();
      if (player != null) {
         AssetSpecificFunctionality.PlayerPreviewData currentPreviewSettings = activeWeatherPreviewMapping.computeIfAbsent(
            editorClient.getUuid(), k -> new AssetSpecificFunctionality.PlayerPreviewData()
         );
         if (!currentPreviewSettings.keepPreview) {
            resetTimeSettings(editorClient, player);
         }

         if (isWeather) {
            AssetStore<String, Weather, IndexedLookupTableAssetMap<String, Weather>> assetStore = Weather.getAssetStore();
            String key = assetStore.decodeFilePathKey(assetPath);
            int weatherIndex = ((IndexedLookupTableAssetMap)assetStore.getAssetMap()).getIndex(key);
            currentPreviewSettings.weatherAssetPath = assetPath;
            player.getPacketHandler().write(new UpdateEditorWeatherOverride(weatherIndex));
         }
      }
   }

   private static void onSelectAsset(@Nonnull AssetEditorSelectAssetEvent event) {
      String assetType = event.getAssetType();
      if (MODEL_ASSET_ID.equals(assetType)) {
         String key = ModelAsset.getAssetStore().decodeFilePathKey(event.getAssetFilePath().path());
         ModelAsset modelAsset = ModelAsset.getAssetMap().getAsset(key);
         if (modelAsset != null) {
            Model modelPacket = com.hypixel.hytale.server.core.asset.type.model.config.Model.createUnitScaleModel(modelAsset).toPacket();
            event.getEditorClient()
               .getPacketHandler()
               .write(new AssetEditorUpdateModelPreview(event.getAssetFilePath().toPacket(), modelPacket, null, DEFAULT_PREVIEW_CAMERA_SETTINGS));
         }
      }

      if (ITEM_ASSET_ID.equals(assetType)) {
         AssetPath assetPath = event.getAssetFilePath();
         String key = Item.getAssetStore().decodeFilePathKey(assetPath.path());
         Item item = Item.getAssetMap().getAsset(key);
         if (item != null) {
            AssetEditorUpdateModelPreview packet = getModelPreviewPacketForItem(assetPath, item);
            if (packet != null) {
               event.getEditorClient().getPacketHandler().write(packet);
            }
         }
      }

      String previousAssetType = event.getPreviousAssetType();
      boolean wasWeather = WEATHER_ASSET_ID.equals(previousAssetType);
      if (wasWeather || ENVIRONMENT_ASSET_ID.equals(previousAssetType)) {
         handleWeatherOrEnvironmentUnselected(event.getEditorClient(), event.getPreviousAssetFilePath().path(), wasWeather);
      }

      boolean isWeather = WEATHER_ASSET_ID.equals(assetType);
      if (isWeather || ENVIRONMENT_ASSET_ID.equals(assetType)) {
         handleWeatherOrEnvironmentSelected(event.getEditorClient(), event.getAssetFilePath().path(), isWeather);
      }
   }

   public static AssetEditorUpdateModelPreview getModelPreviewPacketForItem(@Nonnull AssetPath assetPath, @Nullable Item item) {
      if (item == null) {
         return null;
      } else {
         AssetIconProperties iconProperties = item.getIconProperties();
         AssetIconProperties defaultIconProperties = getDefaultItemIconProperties(item);
         if (iconProperties == null) {
            iconProperties = defaultIconProperties;
         }

         AssetEditorPreviewCameraSettings camera = new AssetEditorPreviewCameraSettings();
         camera.modelScale = iconProperties.getScale() * item.getScale();
         Vector2f translation = iconProperties.getTranslation() != null ? iconProperties.getTranslation() : defaultIconProperties.getTranslation();
         camera.cameraPosition = new Vector3f(-translation.x, -translation.y, 0.0F);
         Vector3f rotation = iconProperties.getRotation() != null ? iconProperties.getRotation() : defaultIconProperties.getRotation();
         camera.cameraOrientation = new Vector3f(
            (float)(-Math.toRadians(rotation.x)), (float)(-Math.toRadians(rotation.y)), (float)(-Math.toRadians(rotation.z))
         );
         if (item.getBlockId() != null) {
            BlockType blockType = (BlockType)((BlockTypeAssetMap)BlockType.getAssetStore().getAssetMap()).getAsset(item.getBlockId());
            if (blockType != null) {
               camera.modelScale = camera.modelScale * blockType.getCustomModelScale();
               return new AssetEditorUpdateModelPreview(assetPath.toPacket(), null, blockType.toPacket(), camera);
            }
         }

         Model modelPacket = convertToModelPacket(item);
         return new AssetEditorUpdateModelPreview(assetPath.toPacket(), modelPacket, null, camera);
      }
   }

   @Nonnull
   public static AssetIconProperties getDefaultItemIconProperties(@Nonnull Item item) {
      if (item.getWeapon() != null) {
         return new AssetIconProperties(0.37F, new Vector2f(-24.6F, -24.6F), new Vector3f(45.0F, 90.0F, 0.0F));
      } else if (item.getTool() != null) {
         return new AssetIconProperties(0.5F, new Vector2f(-17.4F, -12.0F), new Vector3f(45.0F, 270.0F, 0.0F));
      } else if (item.getArmor() != null) {
         return switch (item.getArmor().getArmorSlot()) {
            case Chest -> new AssetIconProperties(0.5F, new Vector2f(0.0F, -5.0F), new Vector3f(22.5F, 45.0F, 22.5F));
            case Head -> new AssetIconProperties(0.5F, new Vector2f(0.0F, -3.0F), new Vector3f(22.5F, 45.0F, 22.5F));
            case Legs -> new AssetIconProperties(0.5F, new Vector2f(0.0F, -25.8F), new Vector3f(22.5F, 45.0F, 22.5F));
            case Hands -> new AssetIconProperties(0.92F, new Vector2f(0.0F, -10.8F), new Vector3f(22.5F, 45.0F, 22.5F));
         };
      } else {
         return new AssetIconProperties(0.58823F, new Vector2f(0.0F, -13.5F), new Vector3f(22.5F, 45.0F, 22.5F));
      }
   }

   @Nonnull
   public static Model convertToModelPacket(@Nonnull Item item) {
      Model packet = new Model();
      packet.path = item.getModel();
      packet.texture = item.getTexture();
      return packet;
   }

   @Nonnull
   private static EventRegistry getEventRegistry() {
      return AssetEditorPlugin.get().getEventRegistry();
   }

   public static class PlayerPreviewData {
      @Nullable
      private Path weatherAssetPath;
      private boolean keepPreview;
   }
}
