package com.tiedup.remake.entities.kidnapper.components;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.KidnapperItemSelector;
import java.util.ArrayList;
import java.util.List;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.Tag;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.item.ItemStack;

/**
 * KidnapperLootManager - Manages stolen items, collar keys, and death drops.
 *
 * Handles:
 * 1. **Stolen Items** - Items taken from players via KidnapperThiefGoal (100% drop on death)
 * 2. **Collar Keys** - Keys generated when collaring captives (20% drop on death)
 * 3. **Equipment Drops** - Taser removal, token drop (5%), themed item drops (15%)
 *
 * <p><b>Low complexity</b> - List management with NBT persistence.</p>
 */
public class KidnapperLootManager {

    // CONSTANTS

    /** Token drop chance (5%) */
    private static final float TOKEN_DROP_CHANCE = 0.05f;

    /** Themed item drop chance (15%) */
    private static final float THEMED_ITEM_DROP_CHANCE = 0.15f;

    /** Collar key drop chance (20%) */
    private static final float COLLAR_KEY_DROP_CHANCE = 0.20f;

    // FIELDS

    /** Host callbacks */
    private final ILootHost host;

    /** Items stolen from players via KidnapperThiefGoal. Dropped at 100% on death. */
    private final List<ItemStack> stolenItems = new ArrayList<>();

    /** Collar keys generated when collaring captives. Dropped at 20% on death. */
    private final List<ItemStack> collarKeys = new ArrayList<>();

    // CONSTRUCTOR

    public KidnapperLootManager(ILootHost host) {
        this.host = host;
    }

    // STOLEN ITEMS

    /**
     * Add an item to the stolen items list.
     * Called by KidnapperThiefGoal when stealing from a player.
     */
    public void addStolenItem(ItemStack stack) {
        if (!stack.isEmpty()) {
            this.stolenItems.add(stack.copy());
        }
    }

    // COLLAR KEYS

    /**
     * Add a collar key to be stored on this kidnapper.
     * Called by KidnapperCaptureGoal when collaring a captive.
     */
    public void addCollarKey(ItemStack keyStack) {
        if (!keyStack.isEmpty()) {
            this.collarKeys.add(keyStack.copy());
        }
    }

    // EQUIPMENT DROP LOGIC

    /**
     * Pre-super drop: removes taser from hand to prevent vanilla drop.
     * Must be called BEFORE super.dropEquipment().
     * @see #dropPostEquipment() for the actual item drops
     */
    public void dropEquipment() {
        // Check main hand for taser - don't drop it
        ItemStack mainHand = host.getItemBySlot(EquipmentSlot.MAINHAND);
        if (
            !mainHand.isEmpty() &&
            mainHand.getItem() instanceof com.tiedup.remake.items.ItemTaser
        ) {
            host.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
        }

        // Check off hand too
        ItemStack offHand = host.getItemBySlot(EquipmentSlot.OFFHAND);
        if (
            !offHand.isEmpty() &&
            offHand.getItem() instanceof com.tiedup.remake.items.ItemTaser
        ) {
            host.setItemSlot(EquipmentSlot.OFFHAND, ItemStack.EMPTY);
        }

        // Note: super.dropEquipment() is called by EntityKidnapper between
        // taser removal and the rest of the drops.
    }

    /**
     * Handle post-super drops: token, themed items, stolen items, collar keys.
     * Called from EntityKidnapper.dropEquipment() AFTER super.dropEquipment().
     */
    public void dropPostEquipment() {
        if (host.level().isClientSide) return;

        // Token drop: 5% chance when killed
        if (host.getRandom().nextFloat() < TOKEN_DROP_CHANCE) {
            ItemStack token = new ItemStack(
                com.tiedup.remake.items.ModItems.TOKEN.get()
            );
            host.spawnAtLocation(token);
            TiedUpMod.LOGGER.info(
                "[KidnapperLootManager] {} dropped a token on death!",
                host.getNpcName()
            );
        }

        // Themed item drops (15% per item)
        KidnapperItemSelector.SelectionResult selection =
            host.getItemSelection();
        if (selection != null) {
            if (
                !selection.bind.isEmpty() &&
                host.getRandom().nextFloat() < THEMED_ITEM_DROP_CHANCE
            ) {
                host.spawnAtLocation(selection.bind.copy());
            }
            if (
                selection.hasGag() &&
                host.getRandom().nextFloat() < THEMED_ITEM_DROP_CHANCE
            ) {
                host.spawnAtLocation(selection.gag.copy());
            }
            if (
                selection.hasMittens() &&
                host.getRandom().nextFloat() < THEMED_ITEM_DROP_CHANCE
            ) {
                host.spawnAtLocation(selection.mittens.copy());
            }
            if (
                selection.hasEarplugs() &&
                host.getRandom().nextFloat() < THEMED_ITEM_DROP_CHANCE
            ) {
                host.spawnAtLocation(selection.earplugs.copy());
            }
            if (
                selection.hasBlindfold() &&
                host.getRandom().nextFloat() < THEMED_ITEM_DROP_CHANCE
            ) {
                host.spawnAtLocation(selection.blindfold.copy());
            }
        }

        // Drop stolen items at 100% rate (player's property)
        for (ItemStack stolen : this.stolenItems) {
            if (!stolen.isEmpty()) {
                host.spawnAtLocation(stolen);
            }
        }
        if (!this.stolenItems.isEmpty()) {
            TiedUpMod.LOGGER.info(
                "[KidnapperLootManager] {} dropped {} stolen item(s) on death",
                host.getNpcName(),
                this.stolenItems.size()
            );
        }
        this.stolenItems.clear();

        // Drop collar keys at 20% rate
        for (ItemStack key : this.collarKeys) {
            if (!key.isEmpty() && host.getRandom().nextFloat() < COLLAR_KEY_DROP_CHANCE) {
                host.spawnAtLocation(key);
                TiedUpMod.LOGGER.info(
                    "[KidnapperLootManager] {} dropped a collar key on death",
                    host.getNpcName()
                );
            }
        }
        this.collarKeys.clear();
    }

    // NBT SERIALIZATION

    /**
     * Save loot data to NBT.
     */
    public void saveToNBT(CompoundTag tag) {
        // Save stolen items
        if (!this.stolenItems.isEmpty()) {
            ListTag stolenTag = new ListTag();
            for (ItemStack stack : this.stolenItems) {
                if (!stack.isEmpty()) {
                    stolenTag.add(stack.save(new CompoundTag()));
                }
            }
            tag.put("StolenItems", stolenTag);
        }

        // Save collar keys
        if (!this.collarKeys.isEmpty()) {
            ListTag keysTag = new ListTag();
            for (ItemStack key : this.collarKeys) {
                if (!key.isEmpty()) {
                    keysTag.add(key.save(new CompoundTag()));
                }
            }
            tag.put("CollarKeys", keysTag);
        }
    }

    /**
     * Load loot data from NBT.
     */
    public void loadFromNBT(CompoundTag tag) {
        // Load stolen items
        this.stolenItems.clear();
        if (tag.contains("StolenItems", Tag.TAG_LIST)) {
            ListTag stolenTag = tag.getList("StolenItems", Tag.TAG_COMPOUND);
            for (int i = 0; i < stolenTag.size(); i++) {
                ItemStack stack = ItemStack.of(stolenTag.getCompound(i));
                if (!stack.isEmpty()) {
                    this.stolenItems.add(stack);
                }
            }
        }

        // Load collar keys
        this.collarKeys.clear();
        if (tag.contains("CollarKeys", Tag.TAG_LIST)) {
            ListTag keysTag = tag.getList("CollarKeys", Tag.TAG_COMPOUND);
            for (int i = 0; i < keysTag.size(); i++) {
                ItemStack key = ItemStack.of(keysTag.getCompound(i));
                if (!key.isEmpty()) {
                    this.collarKeys.add(key);
                }
            }
        }
    }
}
