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

import com.tiedup.remake.entities.EntityMaid;
import com.tiedup.remake.entities.EntitySlaveTrader;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.ai.goal.target.TargetGoal;
import net.minecraft.world.entity.ai.targeting.TargetingConditions;

/**
 * AI Goal for EntityMaid to defend their master trader when attacked.
 *
 * Behavior:
 * - Monitors trader's lastAttacker
 * - Sets maid state to DEFENDING
 * - Attacks anyone who hurts the trader
 * - Timeout after 30 seconds of no combat
 */
public class MaidDefendTraderGoal extends TargetGoal {

    private final EntityMaid maid;

    /** How long to stay in defending mode after trader is no longer attacked */
    private static final int DEFEND_TIMEOUT_TICKS = 600; // 30 seconds

    /** Ticks since trader was last attacked */
    private int ticksSinceTraderAttacked = 0;

    /** Current target being attacked */
    private LivingEntity targetAttacker;

    private static final TargetingConditions DEFEND_TARGETING =
        TargetingConditions.forCombat().range(32.0D).ignoreLineOfSight();

    public MaidDefendTraderGoal(EntityMaid maid) {
        super(maid, false);
        this.maid = maid;
    }

    @Override
    public boolean canUse() {
        // Must have a master trader
        if (maid.getMasterTraderUUID() == null) {
            return false;
        }

        // Must not be freed
        if (maid.isFreed()) {
            return false;
        }

        // Must not be tied up
        if (maid.isTiedUp()) {
            return false;
        }

        // Cannot defend while busy with a task
        if (maid.getMaidState().isBusy()) {
            return false;
        }

        // Get trader and check for attacker
        EntitySlaveTrader trader = maid.getMasterTrader();
        if (trader == null || !trader.isAlive()) {
            return false;
        }

        LivingEntity traderAttacker = trader.getLastAttacker();
        if (traderAttacker == null || !traderAttacker.isAlive()) {
            return false;
        }

        // Don't attack other maids or traders
        if (
            traderAttacker instanceof EntityMaid ||
            traderAttacker instanceof EntitySlaveTrader
        ) {
            return false;
        }

        // Valid target found
        this.targetAttacker = traderAttacker;
        return true;
    }

    @Override
    public boolean canContinueToUse() {
        // Stop if freed or tied up
        if (maid.isFreed() || maid.isTiedUp()) {
            return false;
        }

        // Stop if trader is dead
        EntitySlaveTrader trader = maid.getMasterTrader();
        if (trader == null || !trader.isAlive()) {
            return false;
        }

        // Check if target is still valid
        if (targetAttacker == null || !targetAttacker.isAlive()) {
            ticksSinceTraderAttacked++;
            return ticksSinceTraderAttacked < DEFEND_TIMEOUT_TICKS;
        }

        // Check if we're still in range
        double distSq = maid.distanceToSqr(targetAttacker);
        if (distSq > 32 * 32) {
            ticksSinceTraderAttacked++;
            return ticksSinceTraderAttacked < DEFEND_TIMEOUT_TICKS;
        }

        // Reset timer if trader is being attacked
        LivingEntity currentAttacker = trader.getLastAttacker();
        if (currentAttacker != null && currentAttacker.isAlive()) {
            ticksSinceTraderAttacked = 0;
            this.targetAttacker = currentAttacker;
        } else {
            ticksSinceTraderAttacked++;
        }

        return ticksSinceTraderAttacked < DEFEND_TIMEOUT_TICKS;
    }

    @Override
    public void start() {
        maid.setTarget(targetAttacker);
        maid.setMaidState(MaidState.DEFENDING);
        ticksSinceTraderAttacked = 0;
    }

    @Override
    public void stop() {
        maid.setTarget(null);
        targetAttacker = null;
        ticksSinceTraderAttacked = 0;

        // Return to IDLE if we were DEFENDING
        if (maid.getMaidState() == MaidState.DEFENDING) {
            maid.setMaidState(MaidState.IDLE);
        }
    }

    @Override
    public void tick() {
        // Update target if trader's attacker changed
        EntitySlaveTrader trader = maid.getMasterTrader();
        if (trader != null) {
            LivingEntity currentAttacker = trader.getLastAttacker();
            if (
                currentAttacker != null &&
                currentAttacker.isAlive() &&
                currentAttacker != targetAttacker
            ) {
                this.targetAttacker = currentAttacker;
                maid.setTarget(targetAttacker);
            }
        }

        // Look at target
        if (targetAttacker != null && targetAttacker.isAlive()) {
            maid.getLookControl().setLookAt(targetAttacker, 30.0F, 30.0F);
        }
    }
}
