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

import com.tiedup.remake.entities.EntityDamsel;
import com.tiedup.remake.personality.NpcCommand;
import java.util.EnumSet;
import javax.annotation.Nullable;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.goal.Goal;
import net.minecraft.world.entity.player.Player;

/**
 * AI Goal: NPC comes to their master when COME command is given.
 *
 * Personality System Phase D: AI Goals
 *
 * <p><b>Behavior:</b></p>
 * <ul>
 *   <li>Only active when NPC has COME command</li>
 *   <li>NPC walks to master's position</li>
 *   <li>Completes (awards XP) when within 2 blocks</li>
 *   <li>Instant command - auto-cancels on completion</li>
 * </ul>
 */
public class NpcComeCommandGoal extends Goal {

    private final EntityDamsel npc;
    private final double speedModifier;

    /** Distance at which command is considered complete */
    private static final double COMPLETION_DISTANCE = 2.0;

    /** Maximum time to reach master before giving up (10 seconds) */
    private static final int MAX_TICKS = 200;

    /** Ticks between path recalculations */
    private static final int PATH_RECALC_INTERVAL = 10;

    @Nullable
    private LivingEntity master;

    private int ticksRunning;
    private int pathRecalcTimer;

    public NpcComeCommandGoal(EntityDamsel npc, double speedModifier) {
        this.npc = npc;
        this.speedModifier = speedModifier;
        this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.LOOK));
    }

    @Override
    public boolean canUse() {
        // Must have COME command active
        if (npc.getActiveCommand() != NpcCommand.COME) {
            return false;
        }

        // Must have collar
        if (!npc.hasCollar()) {
            return false;
        }

        // Find the commanding player
        this.master = NpcGoalHelper.findCommandingPlayer(npc);
        return this.master != null;
    }

    @Override
    public boolean canContinueToUse() {
        // Stop if command changed
        if (npc.getActiveCommand() != NpcCommand.COME) {
            return false;
        }

        // Stop if no collar
        if (!npc.hasCollar()) {
            return false;
        }

        // Stop if master is gone
        if (this.master == null || !this.master.isAlive()) {
            return false;
        }

        // Stop if master is in different dimension
        if (this.master.level() != this.npc.level()) {
            return false;
        }

        // Stop if took too long
        if (this.ticksRunning >= MAX_TICKS) {
            return false;
        }

        // Stop if reached master (success!)
        double distance = this.npc.distanceTo(this.master);
        if (distance <= COMPLETION_DISTANCE) {
            return false;
        }

        return true;
    }

    @Override
    public void start() {
        this.ticksRunning = 0;
        this.pathRecalcTimer = 0;
    }

    @Override
    public void stop() {
        // Check if completed successfully
        if (this.master != null) {
            double distance = this.npc.distanceTo(this.master);
            if (distance <= COMPLETION_DISTANCE) {
                // Success! Award XP
                if (this.master instanceof Player player) {
                    // Command completed
                }
            }
        }

        // Cancel command (instant command completes)
        this.npc.cancelCommand();
        this.master = null;
        this.npc.getNavigation().stop();
    }

    @Override
    public void tick() {
        if (this.master == null) return;

        this.ticksRunning++;

        // Look at master
        this.npc.getLookControl().setLookAt(
            this.master,
            10.0F,
            (float) this.npc.getMaxHeadXRot()
        );

        // Move towards master
        if (--this.pathRecalcTimer <= 0) {
            this.pathRecalcTimer = PATH_RECALC_INTERVAL;
            this.npc.getNavigation().moveTo(this.master, this.speedModifier);
        }
    }
}
