package com.seibel.distanthorizons.common.commonMixins;

import com.seibel.distanthorizons.common.wrappers.chunk.ChunkWrapper;
import com.seibel.distanthorizons.common.wrappers.world.ServerLevelWrapper;
import com.seibel.distanthorizons.core.api.internal.ServerApi;
import com.seibel.distanthorizons.core.api.internal.SharedApi;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ProtoChunk;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

public class MixinChunkMapCommon
{
	
	public static void onChunkSave(ServerLevel level, ChunkAccess chunk, CallbackInfoReturnable<Boolean> ci)
	{
		IServerLevelWrapper levelWrapper = ServerLevelWrapper.getWrapper(level);
		
		int chunkPosX;
		int chunkPosZ;
		#if MC_VER <= MC_1_21_11
		chunkPosX = chunk.getPos().x;
		chunkPosZ = chunk.getPos().z;
		#else
		chunkPosX = chunk.getPos().x();
		chunkPosZ = chunk.getPos().z();
		#endif
		
		// is this position already being updated?
		if (SharedApi.isChunkAtChunkPosAlreadyUpdating(levelWrapper, chunkPosX, chunkPosZ))
		{
			return;
		}
		
		
		
		// is this chunk being saved to disk?
		boolean savingChunkToDisk = ci.getReturnValue();
		// true means a chunk was saved to disk
		if (!savingChunkToDisk)
		{
			return;
		}
		
		
		
		// corrupt/incomplete chunk validation //
		
		// MC has a tendency to try saving incomplete or corrupted chunks (which show up as empty or black chunks)
		// this logic should prevent that from happening
		#if MC_VER <= MC_1_17_1
		if (chunk.isUnsaved() || chunk.getUpgradeData() != null || !chunk.isLightCorrect())
		{
			return;
		}
		#else
		if (chunk.isUnsaved() || chunk.isUpgrading() || !chunk.isLightCorrect() || chunk instanceof ProtoChunk)
		{
			return;
		}
		#endif
		
		
		
		// biome validation //
		
		// some chunks may be missing their biomes, which cause issues when attempting to save them
		#if MC_VER <= MC_1_17_1
		if (chunk.getBiomes() == null)
		{
			return;
		}
		#else
		try
		{
			// this will throw an exception if the biomes aren't set up
			chunk.getNoiseBiome(0,0,0);
		}
		catch (Exception e)
		{
			return;
		}
		#endif
		
		
		
		// submit the update event
		ServerApi.INSTANCE.serverChunkSaveEvent(
			new ChunkWrapper(chunk, levelWrapper),
			levelWrapper
		);
	}
	
}
