package net.mattias.oceancritteria.entity.custom;

import net.mattias.oceancritteria.entity.ModEntities;
import net.mattias.oceancritteria.entity.goals.*;
import net.minecraft.core.BlockPos;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.*;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.ai.control.SmoothSwimmingLookControl;
import net.minecraft.world.entity.ai.control.SmoothSwimmingMoveControl;
import net.minecraft.world.entity.ai.goal.*;
import net.minecraft.world.entity.ai.navigation.AmphibiousPathNavigation;
import net.minecraft.world.entity.ai.navigation.PathNavigation;
import net.minecraft.world.entity.animal.Animal;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.crafting.Ingredient;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.Nullable;

public class PenguinEntity extends Animal {
    public PenguinEntity(EntityType<? extends Animal> pEntityType, Level pLevel) {
        super(pEntityType, pLevel);
        // Using SmoothSwimmingMoveControl, which should ideally handle amphibious movement
        // if the navigation system guides it correctly.
        this.moveControl = new SmoothSwimmingMoveControl(this, 85, 10, 0.02F, 0.1F, true);
        this.lookControl = new SmoothSwimmingLookControl(this, 10);
        this.setMaxUpStep(1.0F);
    }

    public final AnimationState idleAnimationState = new AnimationState();
    public final AnimationState swimAnimationState = new AnimationState();
    private int idleAnimationTimeout = 0;

    @Override
    public void tick() {
        super.tick();

        if (this.level().isClientSide()) {
            setupAnimationStates();
        }

        if (!this.level().isClientSide()) {
            // Check if entity is in water or fluid
            if (this.isInWater() || this.isInFluidType()) {
                // Reduce air supply if underwater and not surfacing
                if (!this.isUnderWater() && this.getAirSupply() < this.getMaxAirSupply()) {
                    this.setAirSupply(this.getMaxAirSupply()); // Replenish if just entered water surface
                } else if (this.isUnderWater() && this.getAirSupply() < 60) {
                    Vec3 upward = new Vec3(0, 0.3, 0);
                    this.setDeltaMovement(this.getDeltaMovement().add(upward));
                }
            } else {
                this.setAirSupply(this.getMaxAirSupply());
            }
        }
    }

    private void setupAnimationStates() {
        if (this.isInWater() || this.isInFluidType()) { // Check for any fluid
            this.swimAnimationState.startIfStopped(this.tickCount);
            this.idleAnimationState.stop();
        } else {
            this.swimAnimationState.stop();
            if (this.idleAnimationTimeout <= 0) {
                this.idleAnimationTimeout = this.random.nextInt(40) + 80;
                this.idleAnimationState.start(this.tickCount);
            } else {
                --this.idleAnimationTimeout;
            }
        }
    }

    @Override
    protected PathNavigation createNavigation(Level level) {
        return new AmphibiousPathNavigation(this, level);
    }


    @Override
    protected void registerGoals() {
        this.goalSelector.addGoal(0, new PanicGoal(this, 1.5D));
        this.goalSelector.addGoal(1, new BreedGoal(this, 1.15D));
        this.goalSelector.addGoal(2, new TemptGoal(this, 1.2D,
                Ingredient.of(Items.COD, Items.SALMON, Items.COOKED_SALMON, Items.COOKED_COD), false));
        this.goalSelector.addGoal(3, new FollowParentGoal(this, 1.1D));
        this.goalSelector.addGoal(4, new PenguinGoToWaterGoal(this, 1.0D));
        this.goalSelector.addGoal(5, new PenguinGoToLandGoal(this, 1.0D));
        this.goalSelector.addGoal(6, new PenguinSwimGoal(this, 1.2D));
        this.goalSelector.addGoal(7, new PenguinLandStrollGoal(this));
        this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 3f));
        this.goalSelector.addGoal(9, new RandomLookAroundGoal(this));
    }

    public static AttributeSupplier.Builder createAttributes() {
        return Animal.createLivingAttributes()
                .add(Attributes.MAX_HEALTH, 10D)
                .add(Attributes.MOVEMENT_SPEED, 0.15D) // Base movement speed
                .add(Attributes.FOLLOW_RANGE, 24D);
    }

    @Override
    public void travel(Vec3 pTravelVector) {
        // Use the navigation system which integrates with the MoveControl
        if (this.getNavigation().moveTo(pTravelVector.x, pTravelVector.y, pTravelVector.z, this.getSpeed())) {
            this.navigation.tick(); // Ensure navigation ticks allow movement updates
            this.setDeltaMovement(this.navigation.getGaitSpeed() * pTravelVector.x, this.navigation.getGaitSpeed() * pTravelVector.y, this.navigation.getGaitSpeed() * pTravelVector.z);
        } else {
            super.travel(pTravelVector); // Fallback if navigation fails
        }

        // Existing travel logic - keep this for fine-tuning water physics if needed
        if (this.isEffectiveAi() && (this.isInWater() || this.isInFluidType())) {
            // Handle air supply and upward force when underwater
            if (!this.isUnderWater()) {
                this.setAirSupply(this.getMaxAirSupply());
            } else if (this.getAirSupply() < 60) {
                Vec3 upwardMovement = new Vec3(0, 0.3, 0); // Gentle push upwards
                this.setDeltaMovement(this.getDeltaMovement().add(upwardMovement));
            }

            // Apply swimming movement modifications
            this.moveRelative(0.02F, pTravelVector); // This applies player-like input, might need adjustment
            this.move(MoverType.SELF, this.getDeltaMovement()); // Apply movement
            this.setDeltaMovement(this.getDeltaMovement().scale(0.8D)); // Dampen velocity slightly for swimming feel

            // Reset air if not underwater anymore
            if (!this.isUnderWater()) {
                this.setAirSupply(this.getMaxAirSupply());
            }
        } else {
            super.travel(pTravelVector); // Use default travel for land
        }
    }

    // Helper method to check if the entity is on solid ground below it
    private boolean isTouchingGround() {
        BlockPos posBelow = this.blockPosition().below();
        return this.level().getBlockState(posBelow).isSolid();
    }

    @Override
    public int getMaxAirSupply() {
        return 600; // Standard value
    }

    @Nullable
    @Override
    public AgeableMob getBreedOffspring(ServerLevel pLevel, AgeableMob pOtherParent) {
        return ModEntities.PENGUIN.get().create(pLevel);
    }

    @Override
    public boolean isFood(ItemStack pStack) {
        return pStack.is(Items.COD) || pStack.is(Items.SALMON) ||
                pStack.is(Items.COOKED_COD) || pStack.is(Items.COOKED_SALMON);
    }

    @Nullable
    @Override
    protected SoundEvent getAmbientSound() {
        return SoundEvents.DOLPHIN_AMBIENT;
    }

    @Nullable
    @Override
    protected SoundEvent getHurtSound(DamageSource pDamageSource) {
        return SoundEvents.DOLPHIN_HURT;
    }

    @Nullable
    @Override
    protected SoundEvent getDeathSound() {
        return SoundEvents.DOLPHIN_DEATH;
    }
}
Cannot resolve method 'getGaitSpeed' in 'PathNavigation' Cannot resolve method 'getGaitSpeed' in 'PathNavigation'Cannot resolve method 'getGaitSpeed' in 'PathNavigation'