package com.tiedup.remake.blocks;

import com.tiedup.remake.blocks.entity.KidnapBombBlockEntity;
import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityKidnapBomb;
import com.tiedup.remake.util.BondageItemLoaderUtility;
import java.util.List;
import javax.annotation.Nullable;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.SoundType;
import net.minecraft.world.level.block.TntBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.storage.loot.LootParams;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.BlockHitResult;

/**
 * Kidnap Bomb Block - TNT that applies bondage on explosion.
 *
 *
 * Features:
 * - TNT-like block that can be ignited
 * - Stores bondage items via BlockEntity
 * - On explosion, applies items to entities in radius (no block damage)
 * - Can be loaded by right-clicking with bondage items
 *
 * Based on original BlockKidnapBomb from 1.12.2
 */
public class BlockKidnapBomb
    extends TntBlock
    implements EntityBlock, ICanBeLoaded
{

    public BlockKidnapBomb() {
        super(
            BlockBehaviour.Properties.of()
                .strength(0.0f)
                .sound(SoundType.GRASS)
                .ignitedByLava()
        );
    }

    // BLOCK ENTITY

    @Nullable
    @Override
    public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
        return new KidnapBombBlockEntity(pos, state);
    }

    @Nullable
    public KidnapBombBlockEntity getBombEntity(
        BlockGetter level,
        BlockPos pos
    ) {
        BlockEntity be = level.getBlockEntity(pos);
        return be instanceof KidnapBombBlockEntity
            ? (KidnapBombBlockEntity) be
            : null;
    }

    // EXPLOSION HANDLING

    @Override
    public void onCaughtFire(
        BlockState state,
        Level level,
        BlockPos pos,
        @Nullable net.minecraft.core.Direction face,
        @Nullable LivingEntity igniter
    ) {
        if (!level.isClientSide) {
            KidnapBombBlockEntity bombTile = getBombEntity(level, pos);
            explode(level, pos, bombTile, igniter);
        }
    }

    /**
     * Spawn the primed kidnap bomb entity.
     */
    public void explode(
        Level level,
        BlockPos pos,
        @Nullable KidnapBombBlockEntity bombTile,
        @Nullable LivingEntity igniter
    ) {
        if (!level.isClientSide) {
            EntityKidnapBomb entity = new EntityKidnapBomb(
                level,
                pos.getX() + 0.5,
                pos.getY(),
                pos.getZ() + 0.5,
                igniter,
                bombTile
            );
            level.addFreshEntity(entity);
            level.playSound(
                null,
                entity.getX(),
                entity.getY(),
                entity.getZ(),
                SoundEvents.TNT_PRIMED,
                SoundSource.BLOCKS,
                1.0f,
                1.0f
            );
            level.gameEvent(igniter, GameEvent.PRIME_FUSE, pos);

            TiedUpMod.LOGGER.info(
                "[BlockKidnapBomb] Bomb primed at {} by {}",
                pos,
                igniter != null ? igniter.getName().getString() : "unknown"
            );
        }
    }

    // LOADING ITEMS

    @Override
    public InteractionResult use(
        BlockState state,
        Level level,
        BlockPos pos,
        Player player,
        InteractionHand hand,
        BlockHitResult hit
    ) {
        ItemStack heldItem = player.getItemInHand(hand);

        // First check if it's flint and steel (default TNT behavior)
        if (
            heldItem.is(Items.FLINT_AND_STEEL) || heldItem.is(Items.FIRE_CHARGE)
        ) {
            return super.use(state, level, pos, player, hand, hit);
        }

        if (hand != InteractionHand.MAIN_HAND) {
            return InteractionResult.PASS;
        }

        if (heldItem.isEmpty()) {
            return InteractionResult.PASS;
        }

        // Check if it's a bondage item
        if (!BondageItemLoaderUtility.isLoadableBondageItem(heldItem)) {
            return InteractionResult.PASS;
        }

        // Server-side only
        if (level.isClientSide) {
            return InteractionResult.SUCCESS;
        }

        KidnapBombBlockEntity bomb = getBombEntity(level, pos);
        if (bomb == null) {
            return InteractionResult.PASS;
        }

        // Try to load the held item into the appropriate slot
        if (
            BondageItemLoaderUtility.loadItemIntoHolder(bomb, heldItem, player)
        ) {
            SystemMessageManager.sendToPlayer(
                player,
                "Item loaded into bomb",
                ChatFormatting.YELLOW
            );
            return InteractionResult.SUCCESS;
        }

        return InteractionResult.PASS;
    }

    // DROPS WITH NBT

    @Override
    public List<ItemStack> getDrops(
        BlockState state,
        LootParams.Builder params
    ) {
        BlockEntity be = params.getOptionalParameter(
            LootContextParams.BLOCK_ENTITY
        );
        ItemStack stack = new ItemStack(this);

        if (be instanceof KidnapBombBlockEntity bomb) {
            CompoundTag beTag = new CompoundTag();
            bomb.writeBondageData(beTag);

            if (!beTag.isEmpty()) {
                stack.addTagElement("BlockEntityTag", beTag);
            }
        }

        return List.of(stack);
    }

    // TOOLTIP

    @Override
    public void appendHoverText(
        ItemStack stack,
        @Nullable BlockGetter level,
        List<Component> tooltip,
        TooltipFlag flag
    ) {
        tooltip.add(
            Component.translatable("block.tiedup.kidnap_bomb.desc").withStyle(
                ChatFormatting.GRAY
            )
        );

        CompoundTag nbt = stack.getTag();
        if (nbt != null && nbt.contains("BlockEntityTag")) {
            CompoundTag beTag = nbt.getCompound("BlockEntityTag");

            // Check if loaded with any items
            if (
                beTag.contains("bind") ||
                beTag.contains("gag") ||
                beTag.contains("blindfold") ||
                beTag.contains("earplugs") ||
                beTag.contains("collar")
            ) {
                tooltip.add(
                    Component.translatable("block.tiedup.kidnap_bomb.loaded").withStyle(
                        ChatFormatting.YELLOW
                    )
                );

                // List loaded items
                BondageItemLoaderUtility.addItemToTooltip(
                    tooltip,
                    beTag,
                    "bind"
                );
                BondageItemLoaderUtility.addItemToTooltip(
                    tooltip,
                    beTag,
                    "gag"
                );
                BondageItemLoaderUtility.addItemToTooltip(
                    tooltip,
                    beTag,
                    "blindfold"
                );
                BondageItemLoaderUtility.addItemToTooltip(
                    tooltip,
                    beTag,
                    "earplugs"
                );
                BondageItemLoaderUtility.addItemToTooltip(
                    tooltip,
                    beTag,
                    "collar"
                );
                BondageItemLoaderUtility.addItemToTooltip(
                    tooltip,
                    beTag,
                    "clothes"
                );
            } else {
                tooltip.add(
                    Component.translatable("block.tiedup.kidnap_bomb.empty").withStyle(ChatFormatting.GREEN)
                );
            }
        } else {
            tooltip.add(
                Component.translatable("block.tiedup.kidnap_bomb.empty").withStyle(ChatFormatting.GREEN)
            );
        }
    }
}
