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

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

/**
 * AI Goal: NPC kneels when KNEEL command is given.
 *
 * Personality System Phase D: AI Goals
 *
 * <p><b>Behavior:</b></p>
 * <ul>
 *   <li>Only active when NPC has KNEEL command</li>
 *   <li>NPC enters kneeling pose (stops movement)</li>
 *   <li>Awards XP on command start</li>
 *   <li>Stays kneeling until command is cancelled</li>
 * </ul>
 */
public class NpcKneelCommandGoal extends Goal {

    private final EntityDamsel npc;

    /** Has XP been awarded for this kneel session? */
    private boolean xpAwarded;

    public NpcKneelCommandGoal(EntityDamsel npc) {
        this.npc = npc;
        // Block movement and jumping while kneeling
        this.setFlags(EnumSet.of(Goal.Flag.MOVE, Goal.Flag.JUMP));
    }

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

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

        return true;
    }

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

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

        return true;
    }

    @Override
    public void start() {
        this.xpAwarded = false;

        // Stop all movement
        this.npc.getNavigation().stop();

        // Set kneeling pose
        this.npc.setKneeling(true);

        // Award XP for obeying
        awardXP();
    }

    @Override
    public void stop() {
        // Clear kneeling pose
        this.npc.setKneeling(false);
    }

    @Override
    public void tick() {
        // Ensure we stay still
        if (this.npc.getNavigation().isInProgress()) {
            this.npc.getNavigation().stop();
        }

        // Award XP if not already done
        if (!this.xpAwarded) {
            awardXP();
        }
    }

    @Override
    public boolean requiresUpdateEveryTick() {
        return true;
    }

    /**
     * Award XP to the commanding player.
     */
    private void awardXP() {
        if (this.xpAwarded) return;

        var state = this.npc.getPersonalityState();
        if (state == null) return;

        UUID commanderUUID = state.getCommandingPlayer();
        if (commanderUUID == null) return;

        for (Player player : this.npc.level().players()) {
            if (player.getUUID().equals(commanderUUID)) {
                this.xpAwarded = true;
                break;
            }
        }
    }
}
