package com.tiedup.remake.entities.ai.master;

import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.entities.EntityMaster;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.Style;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.tags.TagKey;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;

/**
 * AI Goal for EntityMaster to inspect pet's inventory for contraband.
 *
 * Contraband items:
 * - Lockpicks, knives, shears
 * - Weapons (swords, axes)
 * - Items tagged with tiedup:escape_tool or tiedup:weapon
 *
 * Behavior:
 * 1. Periodically checks inventory (random chance)
 * 2. Confiscates contraband items
 * 3. Punishes if contraband found
 */
public class MasterInventoryInspectGoal extends Goal {

    private final EntityMaster master;

    /** Chance to start inspection when following (per tick) */
    private static final float INSPECT_CHANCE = 0.002f; // ~4% per 10 seconds

    /** Minimum time between inspections (ticks) - 2.5 minutes */
    private static final int INSPECT_COOLDOWN = 3000;

    /** Distance to inspect */
    private static final double INSPECT_DISTANCE = 2.0;

    /** Inspection duration (ticks) */
    private static final int INSPECT_DURATION = 40; // 2 seconds

    private int inspectTimer = 0;
    private long lastInspectTime = 0;
    private List<ItemStack> confiscatedItems = new ArrayList<>();

    /** Tag for escape tools */
    private static final TagKey<Item> ESCAPE_TOOL_TAG = TagKey.create(
        Registries.ITEM,
        ResourceLocation.fromNamespaceAndPath("tiedup", "escape_tool")
    );

    /** Tag for weapons */
    private static final TagKey<Item> WEAPON_TAG = TagKey.create(
        Registries.ITEM,
        ResourceLocation.fromNamespaceAndPath("tiedup", "weapon")
    );

    public MasterInventoryInspectGoal(EntityMaster master) {
        this.master = master;
        this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK));
    }

    @Override
    public boolean canUse() {
        if (!master.hasPet()) return false;

        MasterState state = master.getStateManager().getCurrentState();

        // Already inspecting
        if (state == MasterState.INSPECT) return true;

        // Can start new inspection
        if (state != MasterState.FOLLOWING && state != MasterState.OBSERVING) {
            return false;
        }

        // Check cooldown
        long currentTime = master.level().getGameTime();
        if (currentTime - lastInspectTime < INSPECT_COOLDOWN) {
            return false;
        }

        // Random chance to inspect (modulated by engagement cadence)
        float multiplier = master.getEngagementMultiplier();
        return (
            multiplier > 0 &&
            master.getRandom().nextFloat() < INSPECT_CHANCE * multiplier
        );
    }

    @Override
    public boolean canContinueToUse() {
        return (
            master.hasPet() &&
            master.getStateManager().getCurrentState() == MasterState.INSPECT &&
            inspectTimer < INSPECT_DURATION
        );
    }

    @Override
    public void start() {
        this.inspectTimer = 0;
        this.confiscatedItems.clear();
        master.setMasterState(MasterState.INSPECT);
        master.markEngagement();

        TiedUpMod.LOGGER.debug(
            "[MasterInventoryInspectGoal] {} starting inspection",
            master.getNpcName()
        );
    }

    @Override
    public void stop() {
        lastInspectTime = master.level().getGameTime();

        // Announce results
        ServerPlayer pet = master.getPetPlayer();
        if (pet != null && !confiscatedItems.isEmpty()) {
            pet.sendSystemMessage(
                Component.translatable(
                    "goal.tiedup.master_inspect.confiscated",
                    master.getNpcName(),
                    confiscatedItems.size()
                ).withStyle(
                    Style.EMPTY.withColor(EntityMaster.MASTER_NAME_COLOR)
                )
            );

            // Transition to punish state
            master.setMasterState(MasterState.PUNISH);
        } else if (master.hasPet()) {
            // Clean inspection
            master.setMasterState(MasterState.FOLLOWING);
        }

        this.inspectTimer = 0;
        this.confiscatedItems.clear();

        TiedUpMod.LOGGER.debug(
            "[MasterInventoryInspectGoal] {} inspection complete",
            master.getNpcName()
        );
    }

    @Override
    public void tick() {
        ServerPlayer pet = master.getPetPlayer();
        if (pet == null) return;

        // Look at pet
        master.getLookControl().setLookAt(pet, 30.0F, 30.0F);

        double distSq = master.distanceToSqr(pet);

        if (distSq > INSPECT_DISTANCE * INSPECT_DISTANCE) {
            // Move close
            master.getNavigation().moveTo(pet, 1.0);
        } else {
            master.getNavigation().stop();

            // Perform inspection on first tick when close
            if (inspectTimer == 0) {
                performInspection(pet);
            }
        }

        inspectTimer++;
    }

    /**
     * Inspect pet's inventory and confiscate contraband.
     */
    private void performInspection(ServerPlayer pet) {
        pet.sendSystemMessage(
            Component.translatable(
                "goal.tiedup.master_inspect.inspecting", master.getNpcName()
            ).withStyle(Style.EMPTY.withColor(0xFFFF00))
        );

        // Check all inventory slots
        for (int i = 0; i < pet.getInventory().getContainerSize(); i++) {
            ItemStack stack = pet.getInventory().getItem(i);
            if (stack.isEmpty()) continue;

            if (isContraband(stack)) {
                // Confiscate
                confiscatedItems.add(stack.copy());
                pet.getInventory().setItem(i, ItemStack.EMPTY);

                TiedUpMod.LOGGER.debug(
                    "[MasterInventoryInspectGoal] {} confiscated {} from {}",
                    master.getNpcName(),
                    stack.getDisplayName().getString(),
                    pet.getName().getString()
                );
            }
        }
    }

    /**
     * Check if an item is contraband.
     */
    private boolean isContraband(ItemStack stack) {
        Item item = stack.getItem();

        // Check tags
        if (stack.is(ESCAPE_TOOL_TAG) || stack.is(WEAPON_TAG)) {
            return true;
        }

        // Check specific vanilla items
        if (
            item == Items.SHEARS ||
            item == Items.IRON_SWORD ||
            item == Items.DIAMOND_SWORD ||
            item == Items.NETHERITE_SWORD ||
            item == Items.IRON_AXE ||
            item == Items.DIAMOND_AXE ||
            item == Items.NETHERITE_AXE ||
            item == Items.BOW ||
            item == Items.CROSSBOW
        ) {
            return true;
        }

        // Check for mod items by registry name
        ResourceLocation registryName =
            net.minecraftforge.registries.ForgeRegistries.ITEMS.getKey(item);
        if (
            registryName != null && registryName.getNamespace().equals("tiedup")
        ) {
            String path = registryName.getPath();
            // Lockpicks and knives are contraband
            if (path.contains("lockpick") || path.contains("knife")) {
                return true;
            }
        }

        return false;
    }
}
