package com.tiedup.remake.state.struggle;

import com.tiedup.remake.core.SystemMessageManager.MessageCategory;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.items.base.ItemCollar;
import com.tiedup.remake.state.PlayerBindState;
import com.tiedup.remake.v2.BodyRegionV2;
import com.tiedup.remake.v2.bondage.capability.V2EquipmentHelper;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;

/**
 *
 * Struggle mechanics specifically for locked collars.
 *
 * How it Works:
 * - Only locked collars can be struggled against
 * - Success: Collar becomes UNLOCKED (not removed)
 * - No items are dropped (unlike bind struggle)
 * - Uses collar-specific GameRules for probability and resistance
 *
 * Differences from StruggleBinds:
 * - Condition: hasLockedCollar() instead of isTiedUp()
 * - Success: unlock collar instead of untie + drop items
 * - Resistance source: collar NBT instead of bind NBT
 * - GameRules: STRUGGLE_COLLAR, PROBABILITY_STRUGGLE_COLLAR, etc.
 *
 * Usage:
 * - Slave wears locked collar
 * - Presses R (struggle key)
 * - Eventually unlocks collar (can then remove it)
 *
 * @see StruggleBinds
 * @see StruggleState
 */
public class StruggleCollar extends StruggleState {

    /**
     * Get the current resistance from the equipped collar.
     *
     * @param state The PlayerBindState
     * @return Current collar resistance, or 0 if no collar
     */
    @Override
    protected int getResistanceState(PlayerBindState state) {
        Player player = state.getPlayer();
        ItemStack collar = V2EquipmentHelper.getInRegion(
            player,
            BodyRegionV2.NECK
        );

        if (
            collar.isEmpty() ||
            !(collar.getItem() instanceof ItemCollar collarItem)
        ) {
            return 0;
        }

        return collarItem.getCurrentResistance(collar, player);
    }

    /**
     * Set the current resistance on the equipped collar.
     *
     * @param state The PlayerBindState
     * @param resistance The new resistance value
     */
    @Override
    protected void setResistanceState(PlayerBindState state, int resistance) {
        Player player = state.getPlayer();
        ItemStack collar = V2EquipmentHelper.getInRegion(
            player,
            BodyRegionV2.NECK
        );

        if (
            collar.isEmpty() ||
            !(collar.getItem() instanceof ItemCollar collarItem)
        ) {
            return;
        }

        collarItem.setCurrentResistance(collar, resistance);
    }

    /**
     * Check if the collar can be struggled against.
     *
     * Conditions:
     * - Must have collar equipped
     * - Collar must be LOCKED
     * - Collar must allow struggle (canBeStruggledOut)
     *
     * Note: Can struggle collar even if NOT tied up.
     *
     * @param state The PlayerBindState
     * @return true if can struggle collar
     */
    @Override
    protected boolean canStruggle(PlayerBindState state) {
        Player player = state.getPlayer();

        if (state.isTiedUp()) {
            return false;
        }

        ItemStack collar = V2EquipmentHelper.getInRegion(
            player,
            BodyRegionV2.NECK
        );

        if (
            collar.isEmpty() ||
            !(collar.getItem() instanceof ItemCollar collarItem)
        ) {
            TiedUpMod.LOGGER.debug("[StruggleCollar] No collar equipped");
            return false;
        }

        // Check if locked
        if (!collarItem.isLocked(collar)) {
            TiedUpMod.LOGGER.debug("[StruggleCollar] Collar is not locked");
            return false;
        }

        // Check if struggle is enabled
        if (!collarItem.canBeStruggledOut(collar)) {
            TiedUpMod.LOGGER.debug(
                "[StruggleCollar] Collar struggle is disabled"
            );
            return false;
        }

        return true;
    }

    /**
     * Action to perform when struggle is attempted.
     * Used for random shock chance on shock collars.
     */
    @Override
    protected boolean onAttempt(PlayerBindState state) {
        Player player = state.getPlayer();
        ItemStack collar = V2EquipmentHelper.getInRegion(
            player,
            BodyRegionV2.NECK
        );

        if (
            !collar.isEmpty() &&
            collar.getItem() instanceof
                com.tiedup.remake.items.ItemShockCollar shockCollar
        ) {
            return shockCollar.notifyStruggle(player, collar);
        }
        return true;
    }

    /**
     * Action to perform when struggle succeeds (resistance = 0).
     *
     * For collars: Unlock the collar.
     * The player can then manually remove it.
     *
     * @param state The PlayerBindState
     */
    @Override
    protected void successAction(PlayerBindState state) {
        Player player = state.getPlayer();
        ItemStack collar = V2EquipmentHelper.getInRegion(
            player,
            BodyRegionV2.NECK
        );

        if (
            collar.isEmpty() ||
            !(collar.getItem() instanceof ItemCollar collarItem)
        ) {
            TiedUpMod.LOGGER.warn(
                "[StruggleCollar] successAction called but no collar equipped"
            );
            return;
        }

        // Unlock the collar
        collarItem.setLocked(collar, false);

        TiedUpMod.LOGGER.info(
            "[StruggleCollar] {} unlocked their collar!",
            player.getName().getString()
        );

        // Note: Collar is NOT removed, just unlocked
        // Player can now manually remove it
    }

    @Override
    protected MessageCategory getSuccessCategory() {
        return MessageCategory.STRUGGLE_COLLAR_SUCCESS;
    }

    @Override
    protected MessageCategory getFailCategory() {
        return MessageCategory.STRUGGLE_COLLAR_FAIL;
    }

    /**
     * Tighten the collar (restore resistance to base value).
     * Called when a master tightens the slave's collar.
     *
     * Conditions:
     * - Collar must be locked
     * - Tightener must be different from wearer
     *
     * @param tightener The player tightening the collar
     * @param state The PlayerBindState of the collar wearer
     */
    public void tighten(Player tightener, PlayerBindState state) {
        Player target = state.getPlayer();

        if (tightener == null || target == null) {
            return;
        }

        // Can't tighten your own collar
        if (tightener.getUUID().equals(target.getUUID())) {
            TiedUpMod.LOGGER.debug(
                "[StruggleCollar] Cannot tighten own collar"
            );
            return;
        }

        ItemStack collar = V2EquipmentHelper.getInRegion(
            target,
            BodyRegionV2.NECK
        );

        if (
            collar.isEmpty() ||
            !(collar.getItem() instanceof ItemCollar collarItem)
        ) {
            TiedUpMod.LOGGER.debug("[StruggleCollar] No collar to tighten");
            return;
        }

        // Check if collar is locked
        if (!collarItem.isLocked(collar)) {
            TiedUpMod.LOGGER.debug(
                "[StruggleCollar] Collar must be locked to tighten"
            );
            return;
        }

        // Get base resistance from GameRules
        int baseResistance = collarItem.getBaseResistance(target);
        int currentResistance = collarItem.getCurrentResistance(collar, target);

        // Only tighten if current resistance is lower than base
        if (currentResistance >= baseResistance) {
            TiedUpMod.LOGGER.debug(
                "[StruggleCollar] Collar already at max resistance"
            );
            return;
        }

        // Restore to base resistance
        collarItem.setCurrentResistance(collar, baseResistance);

        TiedUpMod.LOGGER.info(
            "[StruggleCollar] {} tightened {}'s collar (resistance {} -> {})",
            tightener.getName().getString(),
            target.getName().getString(),
            currentResistance,
            baseResistance
        );
    }
}
