package com.thebrokenrail.twine.entity;

import com.thebrokenrail.twine.Twine;
import com.thebrokenrail.twine.component.StageDataComponent;
import com.thebrokenrail.twine.util.StageUtil;
import net.minecraft.block.BlockState;
import net.minecraft.entity.ai.goal.MoveToTargetPosGoal;
import net.minecraft.entity.mob.CreeperEntity;
import net.minecraft.entity.mob.MobEntityWithAi;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.WorldView;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.ChunkStatus;

public class ExplodeArtificialBlockGoal extends MoveToTargetPosGoal {
    public ExplodeArtificialBlockGoal(MobEntityWithAi mob) {
        super(mob, 1d, Twine.AI_RANGE, Twine.AI_MAX_Y_DIFFERENCE);
    }

    @Override
    protected boolean isTargetPos(WorldView world, BlockPos pos) {
        Chunk chunk = world.getChunk(pos.getX() >> 4, pos.getZ() >> 4, ChunkStatus.FULL, false);
        if (chunk == null) {
            return false;
        } else {
            return chunk.getBlockState(pos).isOpaqueFullCube(world, pos) && chunk.getBlockState(pos.up()).isAir() && chunk.getBlockState(pos.up(2)).isAir() && (isArtificial(world, chunk, pos) || isArtificial(world, chunk, pos.up().north()) || isArtificial(world, chunk, pos.up().south()) || isArtificial(world, chunk, pos.up().east()) || isArtificial(world, chunk, pos.up().west()));
        }
    }

    private boolean isArtificial(WorldView world, Chunk chunk, BlockPos pos) {
        ChunkPos newPos = new ChunkPos(pos.getX() >> 4, pos.getZ() >> 4);
        if (!chunk.getPos().equals(newPos)) {
            chunk = world.getChunk(newPos.x, newPos.z, ChunkStatus.FULL, false);
            if (chunk == null) {
                return false;
            }
        }
        BlockState state = chunk.getBlockState(pos);
        return state != null && (state.isIn(Twine.ARTIFICIAL_BLOCKS_TAG) || state.getLuminance() > 12);
    }

    @Override
    public double getDesiredSquaredDistanceToTarget() {
        return 2d;
    }

    @Override
    public void tick() {
        super.tick();
        if (this.hasReached() && mob instanceof CreeperEntity) {
            ((CreeperEntity) mob).setIgnited();
        }
    }

    @Override
    public boolean canStart() {
        StageDataComponent component = StageDataComponent.getFromWorld((ServerWorld) mob.getEntityWorld());
        BlockPos pos = mob.getBlockPos();
        int stage = component.findEffectiveStageOfChunk((ServerWorld) mob.getEntityWorld(), pos);

        return stage >= StageUtil.CREEPERS_TARGET_ARTIFICIAL_BLOCKS && super.canStart();
    }

    @Override
    protected boolean findTargetPos() {
        if (targetPos != null && isTargetPos(mob.world, targetPos)) {
            return true;
        } else {
            return super.findTargetPos();
        }
    }
}
