package com.thebrokenrail.twine.util.boat;

import com.thebrokenrail.twine.Twine;
import net.minecraft.block.Block;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.PlayerInventory;
import net.minecraft.inventory.Inventory;
import net.minecraft.item.ItemStack;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.sound.SoundEvent;
import net.minecraft.text.Text;

import java.util.ArrayList;
import java.util.function.Function;

public class BoatChestMode {
    private static final ArrayList<BoatChestMode> values = new ArrayList<>();

    private final Block block;
    private final boolean hasItems;
    private final boolean containsItems;

    private final int size;

    private final BoatScreenHandlerFactory screenHandlerFactory;
    private final Function<ItemStack, Text> screenHandlerNameFactory;

    private final int id;

    private final SoundEvent openSound;
    private final SoundEvent closeSound;

    BoatChestMode(Block block, boolean hasItems, boolean containsItems, int size, BoatScreenHandlerFactory screenHandlerFactory, Function<ItemStack, Text> screenHandlerNameFactory, SoundEvent openSound, SoundEvent closeSound) {
        this.screenHandlerFactory = screenHandlerFactory;
        this.size = size;
        this.screenHandlerNameFactory = screenHandlerNameFactory;
        this.openSound = openSound;
        this.closeSound = closeSound;
        this.id = values.size();
        this.block = block;
        this.hasItems = hasItems;
        this.containsItems = containsItems;
        values.add(this);
    }

    public BoatChestMode(Block block, BoatScreenHandlerFactory screenHandlerFactory, Function<ItemStack, Text> screenHandlerNameFactory, SoundEvent openSound, SoundEvent closeSound) {
        this(block, false, false, 0, screenHandlerFactory, screenHandlerNameFactory, openSound, closeSound);
    }

    public static BoatChestMode valueOf(Block block) {
        for (BoatChestMode mode : values) {
            if (mode.getBlock() == block) {
                return mode;
            }
        }
        return BoatChestModes.NONE;
    }

    public static BoatChestMode valueOf(int index) {
        BoatChestMode mode = values.get(index);
        return mode != null ? mode : BoatChestModes.NONE;
    }

    public int getSize() {
        return size;
    }

    public BoatScreenHandlerFactory getScreenHandlerFactory() {
        return screenHandlerFactory;
    }

    public Text getScreenHandlerName(ItemStack stack) {
        return screenHandlerNameFactory.apply(stack);
    }

    public void triggerAdvancement(ServerPlayerEntity player) {
        Twine.BOAT_CRITERION.trigger(player, getBlock());
    }

    public SoundEvent getOpenSound() {
        return openSound;
    }

    public SoundEvent getCloseSound() {
        return closeSound;
    }

    public Block getBlock() {
        return block;
    }

    public boolean hasItems() {
        return hasItems;
    }

    public boolean containsItems() {
        return containsItems;
    }

    public int getID() {
        return id;
    }

    static {
        BoatChestModes.register();
    }

    public interface BoatScreenHandlerFactory {
        ScreenHandler createMenu(int syncId, PlayerInventory inv, PlayerEntity player, BoatUtil boat, Function<Inventory, Inventory> inventoryWrapper);
    }
}
