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

import com.tiedup.remake.core.SystemMessageManager;
import com.tiedup.remake.core.TiedUpMod;
import com.tiedup.remake.dialogue.EntityDialogueManager.DialogueCategory;
import com.tiedup.remake.entities.EntityKidnapper;
import com.tiedup.remake.items.ModItems;
import com.tiedup.remake.prison.PrisonerManager;
import com.tiedup.remake.state.IBondageState;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;

/**
 * AI Goal for EntityKidnapper to flee while carrying a captive.
 *
 *
 * This goal activates when:
 * - Kidnapper has a captive
 * - getOutState is true (triggered after job completion or sale failure)
 *
 * Behavior:
 * 1. Walk fast in random direction away from current position
 * 2. After timeout, release captive and drop a knife for them
 * 3. Transition to KidnapperFleeSafeGoal (flee without captive)
 *
 * Based on original EntityAIWanderFastGettingAway from 1.12.2
 */
public class KidnapperFleeWithCaptiveGoal extends AbstractKidnapperFleeGoal {

    /** Speed when fleeing (faster than normal) */
    private static final double FLEE_SPEED = 1.3D;

    /** How long to flee before releasing captive (ticks) */
    private static final int FLEE_DURATION = 200; // 10 seconds

    /** How far to flee before releasing captive (blocks) */
    private static final double FLEE_DISTANCE = 30.0D;

    /** Search range for flee targets */
    private static final int SEARCH_RANGE = 10;

    /** Dialogue radius */
    private static final int DIALOGUE_RADIUS = 15;

    /**
     * Create a new flee with captive goal.
     *
     * @param kidnapper The kidnapper entity
     */
    public KidnapperFleeWithCaptiveGoal(EntityKidnapper kidnapper) {
        super(kidnapper);
    }

    // ==================== CONFIGURATION ====================

    @Override
    protected double getFleeSpeed() {
        return FLEE_SPEED;
    }

    @Override
    protected int getMaxFleeDuration() {
        return FLEE_DURATION;
    }

    @Override
    protected double getMaxFleeDistance() {
        return FLEE_DISTANCE;
    }

    @Override
    protected int getSearchRangeRadius() {
        return SEARCH_RANGE;
    }

    // ==================== LOGIC HOOKS ====================

    @Override
    protected boolean checkCaptiveCondition() {
        // Must have a captive
        return this.kidnapper.hasCaptives();
    }

    @Override
    protected void onStart() {
        // Announce fleeing
        IBondageState captive = this.kidnapper.getCaptive();
        if (captive != null) {
            // Talk to nearby players
            this.kidnapper.talkToPlayersInRadius(
                DialogueCategory.GET_OUT,
                DIALOGUE_RADIUS
            );

            // Direct message to captive
            if (captive.asLivingEntity() instanceof Player player) {
                this.kidnapper.talkTo(player, DialogueCategory.GET_OUT);
            }
        }

        TiedUpMod.LOGGER.info(
            "[KidnapperFleeWithCaptiveGoal] {} starting to flee with captive",
            this.kidnapper.getNpcName()
        );
    }

    @Override
    protected void onFleeComplete() {
        releaseCaptiveAndFlee();
    }

    // ==================== CAPTIVE RELEASE ====================

    /**
     * Release the captive and drop a knife for them.
     */
    private void releaseCaptiveAndFlee() {
        IBondageState captive = this.kidnapper.getCaptive();
        if (captive == null) return;

        // Talk to captive about being released
        if (captive.asLivingEntity() instanceof Player player) {
            // Kidnapper dialogue
            this.kidnapper.talkTo(player, DialogueCategory.FREED);

            // System message
            SystemMessageManager.sendFreed(player);
        }

        // Drop an iron knife for the captive to escape
        ItemStack knife = new ItemStack(
            ModItems.getKnife(com.tiedup.remake.items.base.KnifeVariant.IRON)
        );
        captive.asLivingEntity().spawnAtLocation(knife);

        TiedUpMod.LOGGER.info(
            "[KidnapperFleeWithCaptiveGoal] {} released {} and dropped knife",
            this.kidnapper.getNpcName(),
            captive.getKidnappedName()
        );

        // Free the captive (but keep them tied - they have the knife to escape)
        captive.free(true);

        // Clear captive reference to prevent escape spam
        this.kidnapper.removeCaptive(captive, true);

        // Release from central PrisonerManager
        if (
            this.kidnapper.level() instanceof
                net.minecraft.server.level.ServerLevel serverLevel
        ) {
            PrisonerManager manager = PrisonerManager.get(serverLevel);
            manager.release(
                captive.asLivingEntity().getUUID(),
                serverLevel.getGameTime()
            );
        }

        // Continue in get out state (will trigger KidnapperFleeSafeGoal)
        // getOutState stays true, but now without captive
    }
}
