package com.r3944realms.modernlifepatch.client.event;

import com.dairymoose.modernlife.core.CustomBlocks;
import com.dairymoose.modernlife.core.ModernLife;
import com.r3944realms.modernlifepatch.ModernLifePatch;
import com.r3944realms.modernlifepatch.client.gui.widget.IconButton;
import com.r3944realms.modernlifepatch.client.gui.widget.TagButton;
import com.r3944realms.modernlifepatch.common.ModTags;
import com.r3944realms.modernlifepatch.datagen.lang.ModLangKeyValue;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen;
import net.minecraft.core.NonNullList;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.tags.TagKey;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
import net.minecraftforge.client.event.ScreenEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.commons.compress.utils.Lists;
import org.lwjgl.glfw.GLFW;

import java.util.*;

public class CreativeScreenEvents {
    private static final ResourceLocation ICONS = new ResourceLocation(ModernLifePatch.MOD_ID, "textures/gui/icons.png");
    private static int startIndex;

    private List<TagFilter> filters;
    private List<TagButton> buttons;
    private Button ScrollUp, ScrollDown, EnableAll, DisableAll;
    private boolean viewThisCreativeTab;
    private int guiCenterX = 0, guiCenterY = 0;

    @SubscribeEvent
    public void onPlayerLogOut(ClientPlayerNetworkEvent.LoggedOutEvent event) {
        this.filters = null;
    }

    @SubscribeEvent
    public void onScreenInit(ScreenEvent.InitScreenEvent.Post event) {
        if(event.getScreen() instanceof CreativeModeInventoryScreen creativeScreen) {
            if(this.filters == null) {
                //初始化过滤器
                compileItems();
            }
            this.viewThisCreativeTab = false;
            this.guiCenterX = creativeScreen.getGuiLeft();
            this.guiCenterY = creativeScreen.getGuiTop();
            this.buttons = new ArrayList<>();

            event.addListener(
                    this.ScrollUp =
                            new IconButton(this.guiCenterX - 22, this.guiCenterY - 12, new TranslatableComponent(ModLangKeyValue.CREATIVE_TAB_SCROLL_UP_BUTTON.getKey()), button -> {
                                if(startIndex > 0)
                                    startIndex--;
                                //更新TagButtons;
                                updatedTagButtons();
                            },ICONS, 64, 0));

            event.addListener(
                    this.ScrollDown =
                            new IconButton(this.guiCenterX - 22, this.guiCenterY + 127, new TranslatableComponent(ModLangKeyValue.CREATIVE_TAB_SCROLL_DOWN_BUTTON.getKey()), button -> {
                                if(startIndex <= filters.size() - 4 - 1)
                                    startIndex++;
                                this.updatedTagButtons();
                            }, ICONS, 80,0)
            );

            event.addListener(
                    this.EnableAll =
                            new IconButton(this.guiCenterX - 50, this.guiCenterY + 10, new TranslatableComponent(ModLangKeyValue.CREATIVE_TAB_ENABLE_FILTERS_BUTTON.getKey()), button -> {
                                this.filters.forEach(filters -> filters.setEnabled(true));
                                this.buttons.forEach(TagButton::updateState);
                                Screen screen = Minecraft.getInstance().screen;
                                if(screen instanceof CreativeModeInventoryScreen creativeModeScreen) {
                                    this.updateItems(creativeModeScreen);
                                }
                            }, ICONS, 96, 0)
            );

            event.addListener(
                    this.DisableAll =
                            new IconButton(this.guiCenterX - 50, this.guiCenterY + 32, new TranslatableComponent(ModLangKeyValue.CREATIVE_TAB_DISABLE_FILTERS_BUTTON.getKey()), button -> {
                                this.filters.forEach(filters -> filters.setEnabled(false));
                                this.buttons.forEach(TagButton::updateState);
                                Screen screen = Minecraft.getInstance().screen;
                                if(screen instanceof CreativeModeInventoryScreen creativeModeScreen) {
                                    this.updateItems(creativeModeScreen);
                                }
                            }, ICONS, 112, 0)
            );

            this.ScrollDown.visible = false;
            this.ScrollUp.visible = false;
            this.EnableAll.visible = false;
            this.DisableAll.visible = false;

            this.updatedTagButtons();

            if(creativeScreen.getSelectedTab() == ModernLifePatch.MLP_CREATIVE_TAB.getId()) {
                this.ScrollDown.visible = true;
                this.ScrollUp.visible = true;
                this.EnableAll.visible = true;
                this.DisableAll.visible = true;
                this.viewThisCreativeTab = true;
                this.buttons.forEach(button -> button.visible = true);
                this.updateItems(creativeScreen);
            }

        }
    }
    @SubscribeEvent
    public void onScreenClick(ScreenEvent.MouseClickedEvent.Pre event)
    {
        if(event.getButton() != GLFW.GLFW_MOUSE_BUTTON_LEFT)
            return;

        if(event.getScreen() instanceof CreativeModeInventoryScreen)
        {
            for(Button button : this.buttons)
            {
                if(button.isMouseOver(event.getMouseX(), event.getMouseY()))
                {
                    if(button.mouseClicked(event.getMouseX(), event.getMouseY(), event.getButton()))
                    {
                        return;
                    }
                }
            }
        }
    }
    @SubscribeEvent
    public void onScreenDrawPre(ScreenEvent.DrawScreenEvent.Pre event) {
        if(event.getScreen() instanceof CreativeModeInventoryScreen creativeModeInventoryScreen) {
            if(creativeModeInventoryScreen.getSelectedTab() == ModernLifePatch.MLP_CREATIVE_TAB.getId()) {
                if(!this.viewThisCreativeTab) {
                    this.updateItems(creativeModeInventoryScreen);
                    this.viewThisCreativeTab = true;
                }
            } else {
                this.viewThisCreativeTab = false;
            }
        }
    }

    @SubscribeEvent
    public void OnScreenDrawPost(ScreenEvent.DrawScreenEvent.Post event) {
        if(event.getScreen() instanceof CreativeModeInventoryScreen creativeModeInventoryScreen) {
            this.guiCenterX = creativeModeInventoryScreen.getGuiLeft();
            this.guiCenterY = creativeModeInventoryScreen.getGuiTop();

            if(creativeModeInventoryScreen.getSelectedTab() == ModernLifePatch.MLP_CREATIVE_TAB.getId()) {
                this.ScrollDown.visible = true;
                this.ScrollUp.visible = true;
                this.EnableAll.visible = true;
                this.DisableAll.visible = true;
                this.viewThisCreativeTab = true;
                this.buttons.forEach(button -> button.visible = true);

                this.buttons.forEach(button -> button.render(
                        event.getPoseStack(), event.getMouseX(), event.getMouseY(), event.getPartialTicks()
                ));
                this.buttons.forEach(button -> {
                    if(button.isMouseOver(event.getMouseX(), event.getMouseY()))
                        creativeModeInventoryScreen.renderTooltip(event.getPoseStack(), button.getCategory().getName(), event.getMouseX(), event.getMouseY());
                });

                if(this.EnableAll.isMouseOver(event.getMouseX(), event.getMouseY()))
                    creativeModeInventoryScreen.renderTooltip(event.getPoseStack(), this.EnableAll.getMessage(), event.getMouseX(), event.getMouseY());
                if(this.DisableAll.isMouseOver(event.getMouseX(), event.getMouseY()))
                    creativeModeInventoryScreen.renderTooltip(event.getPoseStack(), this.DisableAll.getMessage(), event.getMouseX(), event.getMouseY());
            } else {
                this.ScrollDown.visible = false;
                this.ScrollUp.visible = false;
                this.EnableAll.visible = false;
                this.DisableAll.visible = false;
                this.buttons.forEach(buttons -> buttons.visible = false);
            }
        }
    }

    private void updatedTagButtons() {
        final Button.OnPress onPress = buttons -> {
            Screen screen = Minecraft.getInstance().screen;
            if(screen instanceof CreativeModeInventoryScreen creativeScreen) {
                //更新物品
                this.updateItems(creativeScreen);
            }
        };
        this.buttons.clear();
        for(int i = startIndex; i < startIndex + 4 && i < this.filters.size(); i++) {
            TagButton button = new TagButton(this.guiCenterX - 28, this.guiCenterY + 29 * (i - startIndex) + 10, this.filters.get(i), onPress);
            this.buttons.add(button);
        }
        this.ScrollUp.active = startIndex > 0;
        this.ScrollDown.active = startIndex <= this.filters.size() - 4 - 1;
    }

    private void updateItems(CreativeModeInventoryScreen screen) {
        CreativeModeInventoryScreen.ItemPickerMenu menu = screen.getMenu();
        LinkedHashSet<Item> categorisedItems = new LinkedHashSet<>();
        for(TagFilter filter : this.filters) {
            if(filter.isEnabled()) {
                categorisedItems.addAll(filter.getItems());
            }
        }
        NonNullList<ItemStack> newItems = NonNullList.create();
        for(Item item : categorisedItems) {
//            item.fillItemCategory(ModernLifePatch.MLP_CREATIVE_TAB, newItems);
            newItems.add(item.getDefaultInstance());
        }
        menu.items.clear();
        menu.items.addAll(newItems);
        menu.items.sort(Comparator.comparingInt(o -> Item.getId(o.getItem())));
        menu.scrollTo(0);
    }
    private void compileItems() {
        TagFilter[] filters = new TagFilter[] {
                new TagFilter(ModTags.Items.GENERAL, new ItemStack(CustomBlocks.BLOCK_INSET_LIGHT.get())),
                new TagFilter(ModTags.Items.KITCHEN, new ItemStack(CustomBlocks.BLOCK_MICROWAVE.get())),
                new TagFilter(ModTags.Items.BEDCHAMBER, new ItemStack(CustomBlocks.BLOCK_BIRCH_NIGHT_STAND.get())),
                new TagFilter(ModTags.Items.BATHROOM, new ItemStack(CustomBlocks.BLOCK_BATHTUB.get())),
                new TagFilter(ModTags.Items.LOUNGE, new ItemStack(CustomBlocks.BLOCK_COFFEE_MUG.get())),
                new TagFilter(ModTags.Items.OUTSIDE, new ItemStack(CustomBlocks.BLOCK_HEDGE.get())),
                new TagFilter(ModTags.Items.TOOL, new ItemStack(CustomBlocks.ITEM_HANDGUN.get())),
                new TagFilter(ModTags.Items.SEAT, new ItemStack(CustomBlocks.BLOCK_PINK_SOFA.get())),
                new TagFilter(ModTags.Items.TABLE, new ItemStack(CustomBlocks.BLOCK_BIRCH_ROUND_TABLE.get())),
                new TagFilter(ModTags.Items.SHELF, new ItemStack(CustomBlocks.BLOCK_MODERN_BIRCH_BOOKSHELF.get())),
                new TagFilter(ModTags.Items.DOOR, new ItemStack(CustomBlocks.BLOCK_JAIL_DOOR.get())),
        };
        ForgeRegistries.ITEMS.getValues().stream()
                    .filter(item -> {
                        assert item.getRegistryName() != null;
                        return item.getRegistryName().getNamespace().equals(ModernLife.MODID) || item.getRegistryName().getNamespace().equals(ModernLifePatch.MOD_ID);
                    })
                    .forEach(item -> {
                        //noinspection deprecation
                        item.builtInRegistryHolder().tags().forEach(tag -> {
                           for(final TagFilter filter : filters) {
                               if(tag == filter.getTag()) {
                                   filter.add(item);
                               }
                           }
                        });
                });
        this.filters = new ArrayList<>();
        this.filters.addAll(Arrays.asList(filters));
    }

    public static class TagFilter {
        private final List<Item> items = Lists.newArrayList();
        private final TagKey<Item> tag;
        private final TranslatableComponent name;
        private final ItemStack icon;
        private boolean enabled = true;

        public TagFilter(TagKey<Item> tag, ItemStack icon) {
            this.tag = tag;
            this.icon = icon;
            this.name = new TranslatableComponent(
                    String.format("gui.tag_filter.%s.%s", tag.location().getNamespace(), tag.location().getPath().replace("/", "."))
            );
        }

        public TagKey<Item> getTag()
        {
            return tag;
        }

        public ItemStack getIcon()
        {
            return this.icon;
        }

        public TranslatableComponent getName()
        {
            return this.name;
        }

        public void setEnabled(boolean enabled)
        {
            this.enabled = enabled;
        }

        public boolean isEnabled()
        {
            return this.enabled;
        }

        public void add(Item item)
        {
            this.items.add(item);
        }

        public void add(Block block)
        {
            //noinspection deprecation
            this.items.add(Item.byBlock(block));
        }

        public List<Item> getItems()
        {
            return this.items;
        }
    }
}
