// SPDX-FileCopyrightText: 2021 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0

package dan200.computercraft.api;

import net.minecraft.core.registries.Registries;
import net.minecraft.resources.Identifier;
import net.minecraft.tags.BlockItemTagId;
import net.minecraft.tags.TagKey;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.context.UseOnContext;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;

/**
 * Tags provided by ComputerCraft.
 */
public class ComputerCraftTags {
    public static final class Items {
        public static final TagKey<Item> COMPUTER = BlockItems.COMPUTER.item();
        public static final TagKey<Item> TURTLE = BlockItems.TURTLE.item();
        public static final TagKey<Item> WIRED_MODEM = BlockItems.WIRED_MODEM.item();
        public static final TagKey<Item> MONITOR = BlockItems.MONITOR.item();

        /**
         * Floppy disks. Both the read/write version, and treasure disks.
         *
         * @since 1.116.0
         */
        public static final TagKey<Item> DISKS = make("disks");

        /**
         * All pocket computers.
         *
         * @since 1.116.0
         */
        public static final TagKey<Item> POCKET_COMPUTERS = make("pocket_computers");

        /**
         * Items which can be {@linkplain Item#use(Level, Player, InteractionHand) used} when calling
         * {@code turtle.place()}.
         * <p>
         * This does not cover items who handle placing inside {@link Item#useOn(UseOnContext)}, as that is always
         * called.
         */
        public static final TagKey<Item> TURTLE_CAN_PLACE = make("turtle_can_place");

        /**
         * Items which can be dyed.
         * <p>
         * These items can be dyed with a recipe, and cleaned with a sponge.
         */
        public static final TagKey<Item> DYEABLE = make("dyeable");

        private static TagKey<Item> make(String name) {
            return TagKey.create(Registries.ITEM, Identifier.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, name));
        }

        private Items() {
        }
    }

    public static final class Blocks {
        public static final TagKey<Block> COMPUTER = BlockItems.COMPUTER.block();
        public static final TagKey<Block> TURTLE = BlockItems.TURTLE.block();
        public static final TagKey<Block> WIRED_MODEM = BlockItems.WIRED_MODEM.block();
        public static final TagKey<Block> MONITOR = BlockItems.MONITOR.block();

        /**
         * Blocks which should be ignored by a {@code peripheral_hub} peripheral.
         * <p>
         * This should include blocks which themselves expose a peripheral hub (such as {@linkplain #WIRED_MODEM wired
         * modems}).
         */
        public static final TagKey<Block> PERIPHERAL_HUB_IGNORE = make("peripheral_hub_ignore");

        /**
         * Blocks which can be broken by any turtle tool.
         */
        public static final TagKey<Block> TURTLE_ALWAYS_BREAKABLE = make("turtle_always_breakable");

        /**
         * Blocks which can be broken by the default shovel tool.
         */
        public static final TagKey<Block> TURTLE_SHOVEL_BREAKABLE = make("turtle_shovel_harvestable");

        /**
         * Blocks which can be broken with the default sword tool.
         */
        public static final TagKey<Block> TURTLE_SWORD_BREAKABLE = make("turtle_sword_harvestable");

        /**
         * Blocks which can be broken with the default hoe tool.
         */
        public static final TagKey<Block> TURTLE_HOE_BREAKABLE = make("turtle_hoe_harvestable");

        /**
         * Block which can be {@linkplain BlockState#useItemOn(ItemStack, Level, Player, InteractionHand, BlockHitResult) used}
         * when calling {@code turtle.place()}.
         */
        public static final TagKey<Block> TURTLE_CAN_USE = make("turtle_can_use");

        private Blocks() {
        }

        private static TagKey<Block> make(String name) {
            return TagKey.create(Registries.BLOCK, Identifier.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, name));
        }
    }

    public static final class BlockItems {
        public static final BlockItemTagId COMPUTER = make("computer");
        public static final BlockItemTagId TURTLE = make("turtle");
        public static final BlockItemTagId WIRED_MODEM = make("wired_modem");
        public static final BlockItemTagId MONITOR = make("monitor");

        private BlockItems() {
        }

        private static BlockItemTagId make(String name) {
            var id = Identifier.fromNamespaceAndPath(ComputerCraftAPI.MOD_ID, name);
            return BlockItemTagId.create(id, id);
        }
    }
}
