package net.minecraft.world.entity.ai.behavior.warden;

import com.google.common.collect.ImmutableMap;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.util.Unit;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Pose;
import net.minecraft.world.entity.ai.Brain;
import net.minecraft.world.entity.ai.behavior.Behavior;
import net.minecraft.world.entity.ai.behavior.BehaviorUtils;
import net.minecraft.world.entity.ai.memory.MemoryModuleType;
import net.minecraft.world.entity.ai.memory.MemoryStatus;
import net.minecraft.world.entity.monster.warden.Warden;
import net.minecraft.world.entity.monster.warden.WardenAi;

public class Roar extends Behavior<Warden> {
    private static final int TICKS_BEFORE_PLAYING_ROAR_SOUND = 25;
    private static final int ROAR_ANGER_INCREASE = 20;

    public Roar() {
        super(
            ImmutableMap.of(
                MemoryModuleType.ROAR_TARGET,
                MemoryStatus.VALUE_PRESENT,
                MemoryModuleType.ATTACK_TARGET,
                MemoryStatus.VALUE_ABSENT,
                MemoryModuleType.ROAR_SOUND_COOLDOWN,
                MemoryStatus.REGISTERED,
                MemoryModuleType.ROAR_SOUND_DELAY,
                MemoryStatus.REGISTERED
            ),
            WardenAi.ROAR_DURATION
        );
    }

    @Override
    protected void start(ServerLevel level, Warden entity, long gameTime) {
        Brain<Warden> brain = entity.getBrain();
        brain.setMemoryWithExpiry(MemoryModuleType.ROAR_SOUND_DELAY, Unit.INSTANCE, 25L);
        brain.eraseMemory(MemoryModuleType.WALK_TARGET);
        LivingEntity livingEntity = entity.getBrain().getMemory(MemoryModuleType.ROAR_TARGET).get();
        BehaviorUtils.lookAtEntity(entity, livingEntity);
        entity.setPose(Pose.ROARING);
        entity.increaseAngerAt(livingEntity, 20, false);
    }

    @Override
    protected boolean canStillUse(ServerLevel level, Warden entity, long gameTime) {
        return true;
    }

    @Override
    protected void tick(ServerLevel level, Warden owner, long gameTime) {
        if (!owner.getBrain().hasMemoryValue(MemoryModuleType.ROAR_SOUND_DELAY) && !owner.getBrain().hasMemoryValue(MemoryModuleType.ROAR_SOUND_COOLDOWN)) {
            owner.getBrain().setMemoryWithExpiry(MemoryModuleType.ROAR_SOUND_COOLDOWN, Unit.INSTANCE, WardenAi.ROAR_DURATION - 25);
            owner.playSound(SoundEvents.WARDEN_ROAR, 3.0F, 1.0F);
        }
    }

    @Override
    protected void stop(ServerLevel level, Warden entity, long gameTime) {
        if (entity.hasPose(Pose.ROARING)) {
            entity.setPose(Pose.STANDING);
        }

        entity.getBrain().getMemory(MemoryModuleType.ROAR_TARGET).ifPresent(entity::setAttackTarget);
        entity.getBrain().eraseMemory(MemoryModuleType.ROAR_TARGET);
    }
}
