package com.tiedup.remake.events.restriction;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityMaster;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.v2.bondage.CollarHelper;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.blocks.PetBedManager;
import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod;

/**
 * Event handler for pet play restrictions.
 *
 * When a player has a pet play collar (from EntityMaster):
 * - Cannot eat food from hand (must use Bowl block)
 * - Cannot sleep in normal beds (must use Pet Bed block)
 *
 * Placeholder blocks:
 * - Bowl: Cauldron (shift+right-click with food to eat)
 * - Pet Bed: White carpet (shift+right-click to sleep)
 */
@Mod.EventBusSubscriber(
    modid = TiedUpMod.MOD_ID,
    bus = Mod.EventBusSubscriber.Bus.FORGE
)
public class PetPlayRestrictionHandler {

    /** Message cooldown in milliseconds */
    private static final long MESSAGE_COOLDOWN_MS = 3000;

    /** Last message time per player */
    private static final java.util.Map<java.util.UUID, Long> lastMessageTime =
        new java.util.HashMap<>();

    // EATING RESTRICTION

    /**
     * Prevent pet play players from eating food from hand.
     * They must use a Bowl block (cauldron placeholder).
     */
    @SubscribeEvent(priority = EventPriority.HIGH)
    public static void onRightClickItem(
        PlayerInteractEvent.RightClickItem event
    ) {
        Player player = event.getEntity();
        if (player.level().isClientSide) return;

        // Check for pet play collar
        if (!EntityMaster.hasPetCollar(player)) return;

        ItemStack heldItem = event.getItemStack();

        // Check if trying to eat food
        if (heldItem.isEdible()) {
            event.setCanceled(true);
            event.setCancellationResult(
                net.minecraft.world.InteractionResult.FAIL
            );

            sendThrottledMessage(
                player,
                "msg.tiedup.petplay.cannot_eat_hand"
            );

            TiedUpMod.LOGGER.debug(
                "[PetPlayRestrictionHandler] Blocked {} from eating food directly",
                player.getName().getString()
            );
        }
    }

    /**
     * Allow eating from Bowl block (cauldron placeholder).
     * Shift+right-click with food on cauldron to eat.
     */
    @SubscribeEvent(priority = EventPriority.HIGH)
    public static void onRightClickBlock(
        PlayerInteractEvent.RightClickBlock event
    ) {
        Player player = event.getEntity();
        if (player.level().isClientSide) return;

        // Check for pet play collar
        if (!EntityMaster.hasPetCollar(player)) return;

        BlockPos pos = event.getPos();
        BlockState state = player.level().getBlockState(pos);
        ItemStack heldItem = event.getItemStack();

        // Bowl interaction (cauldron placeholder)
        if (
            state.getBlock() == Blocks.CAULDRON &&
            player.isShiftKeyDown() &&
            heldItem.isEdible()
        ) {
            // Allow eating from bowl
            // Consume the food
            if (player instanceof ServerPlayer serverPlayer) {
                net.minecraft.world.food.FoodProperties food = heldItem
                    .getItem()
                    .getFoodProperties();
                if (food != null) {
                    serverPlayer
                        .getFoodData()
                        .eat(food.getNutrition(), food.getSaturationModifier());

                    // Shrink the item
                    heldItem.shrink(1);

                    // Play eating sound
                    player
                        .level()
                        .playSound(
                            null,
                            pos,
                            net.minecraft.sounds.SoundEvents.GENERIC_EAT,
                            net.minecraft.sounds.SoundSource.PLAYERS,
                            1.0f,
                            1.0f
                        );

                    TiedUpMod.LOGGER.debug(
                        "[PetPlayRestrictionHandler] {} ate from bowl",
                        player.getName().getString()
                    );

                    // Cancel to prevent normal cauldron interaction
                    event.setCanceled(true);
                    event.setCancellationResult(
                        net.minecraft.world.InteractionResult.SUCCESS
                    );
                }
            }
        }

        // Pet bed interaction (carpet placeholder) - handled in sleep event
    }

    // SLEEPING RESTRICTION

    /**
     * Prevent pet play players from sleeping in normal beds.
     * They must use a Pet Bed block (carpet placeholder).
     */
    @SubscribeEvent(priority = EventPriority.HIGH)
    public static void onSleepInBed(PlayerSleepInBedEvent event) {
        Player player = event.getEntity();
        if (player.level().isClientSide) return;

        // Check for pet play collar
        if (!EntityMaster.hasPetCollar(player)) return;

        // Block sleeping in beds
        BlockState state = player.level().getBlockState(event.getPos());
        if (state.getBlock() instanceof BedBlock) {
            event.setResult(Player.BedSleepingProblem.OTHER_PROBLEM);

            sendThrottledMessage(
                player,
                "msg.tiedup.petplay.cannot_sleep_bed"
            );

            TiedUpMod.LOGGER.debug(
                "[PetPlayRestrictionHandler] Blocked {} from sleeping in bed",
                player.getName().getString()
            );
        }
    }

    /**
     * Allow sleeping on Pet Bed block (carpet placeholder).
     * Shift+right-click on white carpet to sleep.
     */
    @SubscribeEvent(priority = EventPriority.NORMAL)
    public static void onInteractForSleep(
        PlayerInteractEvent.RightClickBlock event
    ) {
        Player player = event.getEntity();
        if (player.level().isClientSide) return;

        // Check for pet play collar
        if (!EntityMaster.hasPetCollar(player)) return;

        BlockPos pos = event.getPos();
        BlockState state = player.level().getBlockState(pos);

        // Pet bed interaction (white carpet placeholder)
        if (
            state.getBlock() == Blocks.WHITE_CARPET && player.isShiftKeyDown()
        ) {
            if (player instanceof ServerPlayer serverPlayer) {
                // Try to sleep
                Player.BedSleepingProblem problem = canSleepNow(serverPlayer);

                if (problem == null) {
                    // Set spawn point to pet bed location
                    serverPlayer.setRespawnPosition(
                        serverPlayer.level().dimension(),
                        pos,
                        serverPlayer.getYRot(),
                        false,
                        true
                    );

                    // Start sleeping (simplified - real implementation would need proper sleep mechanics)
                    serverPlayer.sendSystemMessage(
                        Component.translatable(
                            "msg.tiedup.petplay.curl_up_bed"
                        ).withStyle(Style.EMPTY.withColor(0x888888))
                    );

                    // Apply sleep effects (heal, skip night handled elsewhere)
                    serverPlayer.heal(2.0f);

                    TiedUpMod.LOGGER.debug(
                        "[PetPlayRestrictionHandler] {} slept in pet bed",
                        player.getName().getString()
                    );

                    event.setCanceled(true);
                    event.setCancellationResult(
                        net.minecraft.world.InteractionResult.SUCCESS
                    );
                } else {
                    sendThrottledMessage(
                        player,
                        "msg.tiedup.petplay.sleep_time_only"
                    );
                }
            }
        }
    }

    /**
     * Check if player can sleep now (time/weather check).
     */
    private static Player.BedSleepingProblem canSleepNow(ServerPlayer player) {
        // Check time of day
        if (player.level().isDay() && !player.level().isThundering()) {
            return Player.BedSleepingProblem.NOT_POSSIBLE_NOW;
        }
        return null;
    }

    // CHOKE COLLAR EFFECT

    /**
     * Apply choke collar effect on player tick.
     * When choking is active, rapidly reduces air supply to cause drowning damage.
     */
    @SubscribeEvent
    public static void onPlayerTick(TickEvent.PlayerTickEvent event) {
        // Only process on server side, at END phase
        if (event.phase != TickEvent.Phase.END) return;
        if (event.player.level().isClientSide) return;
        if (!(event.player instanceof ServerPlayer player)) return;

        // Check pet bed sit cancellation (movement detection)
        PetBedManager.tickPlayer(player);

        // Check pet cage validity
        com.tiedup.remake.v2.blocks.PetCageManager.tickPlayer(player);

        // Get player's collar
        PlayerBindState bindState = PlayerBindState.getInstance(player);
        if (bindState == null || !bindState.hasCollar()) return;

        ItemStack collar = bindState.getEquipment(BodyRegionV2.NECK);
        if (CollarHelper.isChokeCollar(collar)) {
            if (CollarHelper.isChoking(collar)) {
                // Apply ChokeEffect (short duration, re-applied each active tick)
                if (
                    !player.hasEffect(
                        com.tiedup.remake.core.ModEffects.CHOKE.get()
                    )
                ) {
                    player.addEffect(
                        new MobEffectInstance(
                            com.tiedup.remake.core.ModEffects.CHOKE.get(),
                            40,
                            0,
                            false,
                            false,
                            false
                        )
                    );
                }
            } else {
                // Remove effect if choke is deactivated
                player.removeEffect(
                    com.tiedup.remake.core.ModEffects.CHOKE.get()
                );
            }
        }
    }

    // UTILITY

    /**
     * BUG FIX: Clean up player data to prevent memory leak.
     * Called on player logout.
     */
    public static void clearPlayer(java.util.UUID playerId) {
        lastMessageTime.remove(playerId);
    }

    /**
     * Send a message with cooldown to prevent spam.
     */
    private static void sendThrottledMessage(Player player, String translationKey) {
        long now = System.currentTimeMillis();
        Long lastTime = lastMessageTime.get(player.getUUID());

        if (lastTime == null || now - lastTime > MESSAGE_COOLDOWN_MS) {
            lastMessageTime.put(player.getUUID(), now);
            player.sendSystemMessage(
                Component.translatable(translationKey).withStyle(
                    Style.EMPTY.withColor(EntityMaster.MASTER_NAME_COLOR)
                )
            );
        }
    }
}
