package com.tiedup.remake.items;

import com.tiedup.remake.core.SettingsAccessor;
import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.state.IRestrainable;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.util.KidnappedHelper;
import java.util.List;
import net.minecraft.ChatFormatting;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.Nullable;

/**
 * Rag - Can be soaked in chloroform to knock out targets
 * Has wet/dry state managed via NBT.
 *
 *
 * Usage:
 * 1. Hold chloroform bottle, rag in offhand, right-click → rag becomes wet
 * 2. Hold wet rag, right-click target → apply chloroform effect
 * 3. Wet rag evaporates over time (configurable)
 *
 * Effects on target:
 * - Slowness 127 (cannot move)
 * - Blindness
 * - Nausea
 * - UNCONSCIOUS pose
 */
public class ItemRag extends Item {

    private static final String NBT_WET = "wet";
    private static final String NBT_WET_TIME = "wetTime"; // Ticks remaining

    public ItemRag() {
        super(new Item.Properties().stacksTo(16));
    }

    @Override
    public void appendHoverText(
        ItemStack stack,
        @Nullable Level level,
        List<Component> tooltip,
        TooltipFlag flag
    ) {
        if (isWet(stack)) {
            int ticksRemaining = getWetTime(stack);
            int secondsRemaining = ticksRemaining / 20;
            tooltip.add(
                Component.translatable("item.tiedup.rag.soaked")
                    .withStyle(ChatFormatting.GREEN)
            );
            tooltip.add(
                Component.translatable("item.tiedup.rag.evaporates", secondsRemaining)
                    .withStyle(ChatFormatting.GRAY)
            );
        } else {
            tooltip.add(
                Component.translatable("item.tiedup.rag.dry")
                    .withStyle(ChatFormatting.GRAY)
            );
        }
    }

    /**
     * Called when player right-clicks another entity with the rag.
     * If wet, applies chloroform effect to the target.
     */
    @Override
    public InteractionResult interactLivingEntity(
        ItemStack stack,
        Player player,
        LivingEntity target,
        InteractionHand hand
    ) {
        // Only run on server side
        if (player.level().isClientSide) {
            return InteractionResult.SUCCESS;
        }

        // Must be wet to apply chloroform
        if (!isWet(stack)) {
            SystemMessageManager.sendToPlayer(
                player,
                SystemMessageManager.MessageCategory.RAG_DRY
            );
            return InteractionResult.PASS;
        }

        // Apply chloroform to target
        applyChloroformToTarget(target, player);

        // The rag stays wet (can be used multiple times until it evaporates)

        TiedUpMod.LOGGER.info(
            "[ItemRag] {} applied chloroform to {}",
            player.getName().getString(),
            target.getName().getString()
        );

        return InteractionResult.SUCCESS;
    }

    /**
     * Tick the rag to handle evaporation of wet state.
     */
    @Override
    public void inventoryTick(
        ItemStack stack,
        Level level,
        Entity entity,
        int slot,
        boolean selected
    ) {
        if (level.isClientSide) return;

        if (isWet(stack)) {
            int wetTime = getWetTime(stack);
            if (wetTime > 0) {
                setWetTime(stack, wetTime - 1);
            } else {
                // Evaporated
                setWet(stack, false);
                if (entity instanceof Player player) {
                    SystemMessageManager.sendToPlayer(
                        player,
                        SystemMessageManager.MessageCategory.RAG_EVAPORATED
                    );
                }
                TiedUpMod.LOGGER.debug("[ItemRag] Chloroform evaporated");
            }
        }
    }

    /**
     * Apply chloroform effect to a target.
     * Effects: Slowness 127, Blindness, Nausea for configured duration.
     *
     * @param target The target entity
     * @param player The player applying chloroform
     */
    private void applyChloroformToTarget(LivingEntity target, Player player) {
        // Get duration from config via SettingsAccessor (single source of truth)
        int duration = SettingsAccessor.getChloroformDuration();

        // Apply effects
        // Slowness 127 = cannot move at all
        target.addEffect(
            new MobEffectInstance(
                MobEffects.MOVEMENT_SLOWDOWN,
                duration,
                127,
                false,
                false
            )
        );
        // Blindness
        target.addEffect(
            new MobEffectInstance(
                MobEffects.BLINDNESS,
                duration,
                0,
                false,
                false
            )
        );
        // Nausea (confusion)
        target.addEffect(
            new MobEffectInstance(
                MobEffects.CONFUSION,
                duration,
                0,
                false,
                false
            )
        );
        // Weakness (cannot fight back)
        target.addEffect(
            new MobEffectInstance(
                MobEffects.WEAKNESS,
                duration,
                127,
                false,
                false
            )
        );

        // If target is IRestrainable, call applyChloroform to apply effects
        IRestrainable kidnapped = KidnappedHelper.getKidnappedState(target);
        if (kidnapped != null) {
            kidnapped.applyChloroform(duration);
        }

        TiedUpMod.LOGGER.debug(
            "[ItemRag] Applied chloroform to target for {} seconds",
            duration
        );
    }

    // ========== Wet/Dry State Management ==========

    /**
     * Check if this rag is soaked with chloroform.
     * @param stack The item stack
     * @return true if wet with chloroform
     */
    public static boolean isWet(ItemStack stack) {
        if (stack.isEmpty()) return false;
        CompoundTag tag = stack.getTag();
        return tag != null && tag.getBoolean(NBT_WET);
    }

    /**
     * Set the wet state of this rag.
     * @param stack The item stack
     * @param wet true to make wet, false for dry
     */
    public static void setWet(ItemStack stack, boolean wet) {
        if (stack.isEmpty()) return;
        stack.getOrCreateTag().putBoolean(NBT_WET, wet);
        if (!wet) {
            // Clear wet time when drying
            stack.getOrCreateTag().remove(NBT_WET_TIME);
        }
    }

    /**
     * Get the remaining wet time in ticks.
     * @param stack The item stack
     * @return Ticks remaining, or 0 if not wet
     */
    public static int getWetTime(ItemStack stack) {
        if (stack.isEmpty()) return 0;
        CompoundTag tag = stack.getTag();
        return tag != null ? tag.getInt(NBT_WET_TIME) : 0;
    }

    /**
     * Set the remaining wet time in ticks.
     * @param stack The item stack
     * @param ticks Ticks remaining
     */
    public static void setWetTime(ItemStack stack, int ticks) {
        if (stack.isEmpty()) return;
        stack.getOrCreateTag().putInt(NBT_WET_TIME, ticks);
    }

    /**
     * Soak this rag with chloroform.
     * Sets wet = true and initializes the evaporation timer.
     *
     * @param stack The item stack
     * @param wetTime Time in ticks before evaporation
     */
    public static void soak(ItemStack stack, int wetTime) {
        if (stack.isEmpty()) return;
        setWet(stack, true);
        setWetTime(stack, wetTime);
        TiedUpMod.LOGGER.debug(
            "[ItemRag] Soaked with chloroform ({} ticks)",
            wetTime
        );
    }

    /**
     * Get the default wet time for soaking.
     * @return Default wet time in ticks
     */
    public static int getDefaultWetTime() {
        return SettingsAccessor.getRagWetTime();
    }
}
