package com.cimeyclust.addonreader.resources;

import cn.nukkit.block.Block;
import cn.nukkit.block.customblock.CustomBlock;
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.EntityIntelligent;
import cn.nukkit.entity.custom.CustomEntity;
import cn.nukkit.entity.provider.CustomClassEntityProvider;
import cn.nukkit.item.Item;
import cn.nukkit.item.customitem.CustomItem;
import cn.nukkit.plugin.PluginBase;
import org.reflections.Reflections;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class Plugin extends PluginBase {
    private static Plugin instance;
    private List<Class <? extends Entity>> entities;

    @Override
    public void onLoad() {
        instance = this;
        entities = new ArrayList<>();
    }

    @Override
    public void onEnable() {
        // Register Blocks
        Reflections blockReflections = new Reflections("com.cimeyclust.addonreader.resources.custom_blocks");
        // Log super classes of each class in the package
        blockReflections.getSubTypesOf(Object.class).forEach(clazz -> getLogger().info(clazz + " extends " + clazz.getSuperclass()));

        // Log block classes
        blockReflections.getSubTypesOf(Object.class).forEach(clazz -> getLogger().info(clazz + " is a block class"));

        Set<Class<? extends CustomBlock>> blocks = blockReflections.getSubTypesOf(Object.class).stream()
                .filter(clazz -> clazz.getSuperclass() == CustomBlock.class)
                .map(clazz -> (Class<? extends CustomBlock>) clazz)
                .collect(Collectors.toSet());

        for (Class<? extends CustomBlock> clazz : blocks) {
            getLogger().info("§aLoading custom block " + clazz + "...");
            try {
                Block.registerCustomBlock(Collections.singletonList(clazz)).assertOK();
            } catch (AssertionError e) {
                e.printStackTrace();
            }
        }

        // Register Items
        Reflections itemReflections = new Reflections("com.cimeyclust.addonreader.resources.custom_items");
        // Log super classes of each class in the package
        itemReflections.getSubTypesOf(Object.class).forEach(clazz -> getLogger().info(clazz + " extends " + clazz.getSuperclass()));

        Set<Class<? extends CustomItem>> items = itemReflections.getSubTypesOf(Object.class).stream()
                .filter(clazz -> clazz.getSuperclass() == CustomItem.class)
                .map(clazz -> (Class<? extends CustomItem>) clazz)
                .collect(Collectors.toSet());

        for (Class<? extends CustomItem> clazz : items) {
            getLogger().info("§aLoading custom item " + clazz + "...");
            try {
                Item.registerCustomItem(clazz).assertOK();
            } catch (AssertionError e) {
                e.printStackTrace();
            }
        }

        // Register Entities
        Reflections entityReflections = new Reflections("com.cimeyclust.addonreader.resources.custom_entities");
        // Log super classes of each class in the package
        entityReflections.getSubTypesOf(Object.class).forEach(clazz -> getLogger().info(clazz + " extends " + clazz.getSuperclass()));

        Set<Class<? extends Entity>> entities = itemReflections.getSubTypesOf(Object.class).stream()
                .filter(clazz -> clazz.getSuperclass() == Entity.class)
                .map(clazz -> (Class<? extends Entity>) clazz)
                .collect(Collectors.toSet());

        for (Class<? extends Entity> clazz : entities) {
            getLogger().info("§aLoading custom entity " + clazz + "...");
            try {
                Entity.registerCustomEntity(new CustomClassEntityProvider(clazz)).assertOK();
                entities.add(clazz);
            } catch (AssertionError e) {
                e.printStackTrace();
            }
        }

        getLogger().info("§aCustomResources has been enabled!");
    }

    public static void tickComponents(Entity entity) {
        if (!(entity instanceof EntityIntelligent)) return;
        getInstance().getServer().getPluginManager().getPlugin("NukkitAddonReader").getLogger().info("Ticking components for entity: " + entity.getName());
        if (getInstance().getServer().getPluginManager().getPlugin("NukkitAddonReader") instanceof com.cimeyclust.addonreader.Plugin pl) {
            pl.tickComponents((EntityIntelligent) entity);
        }
    }

    public static Plugin getInstance() {
        return instance;
    }

    public List<Class<? extends Entity>> getEntities() {
        return entities;
    }
}
