package net.geforcemods.securitycraft.blocks;

import java.util.Random;

import net.geforcemods.securitycraft.api.IOwnable;
import net.geforcemods.securitycraft.api.LinkableBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.DoorBlock;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.LevelEvent;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
import net.minecraft.world.level.material.PushReaction;
import net.minecraft.world.phys.HitResult;

public abstract class SpecialDoorBlock extends DoorBlock implements EntityBlock {
	public SpecialDoorBlock(Block.Properties properties) {
		super(properties);
	}

	@Override
	public void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, BlockPos neighbor, boolean flag) {
		Block neighborBlock = level.getBlockState(neighbor).getBlock();

		if (state.getValue(HALF) == DoubleBlockHalf.UPPER) {
			BlockPos posBelow = pos.below();
			BlockState stateBelow = level.getBlockState(posBelow);

			if (stateBelow.getBlock() != this)
				level.destroyBlock(pos, false);
			else if (neighborBlock != this)
				neighborChanged(stateBelow, level, posBelow, block, pos, flag);
		}
		else {
			boolean drop = false;
			BlockPos blockBelow = pos.above();
			BlockState stateBelow = level.getBlockState(blockBelow);

			if (stateBelow.getBlock() != this) {
				level.destroyBlock(pos, false);
				drop = true;
			}

			if (!level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP)) {
				level.destroyBlock(pos, false);
				drop = true;

				if (stateBelow.getBlock() == this)
					level.destroyBlock(blockBelow, false);
			}

			if (drop) {
				if (!level.isClientSide) {
					level.destroyBlock(pos, false);
					Block.popResource(level, pos, new ItemStack(getDoorItem()));
				}
			}
		}
	}

	@Override
	public void setPlacedBy(Level level, BlockPos pos, BlockState state, LivingEntity placer, ItemStack stack) {
		super.setPlacedBy(level, pos, state, placer, stack);

		if (level.getBlockEntity(pos) instanceof IOwnable lowerBe && level.getBlockEntity(pos.above()) instanceof IOwnable upperBe) {
			if (placer instanceof Player player) {
				lowerBe.setOwner(player.getGameProfile().getId().toString(), player.getName().getString());
				upperBe.setOwner(player.getGameProfile().getId().toString(), player.getName().getString());
			}

			if (lowerBe instanceof LinkableBlockEntity linkable1 && upperBe instanceof LinkableBlockEntity linkable2)
				LinkableBlockEntity.link(linkable1, linkable2);
		}
	}

	@Override
	public void tick(BlockState state, ServerLevel level, BlockPos pos, Random rand) {
		BlockState upperState = level.getBlockState(pos);

		if (!upperState.getValue(DoorBlock.OPEN))
			return;

		BlockState lowerState;

		if (upperState.getValue(DoorBlock.HALF) == DoubleBlockHalf.LOWER) {
			lowerState = upperState;
			pos = pos.above();
			upperState = level.getBlockState(pos);
		}
		else
			lowerState = level.getBlockState(pos.below());

		level.setBlock(pos, upperState.setValue(DoorBlock.OPEN, false), 3);
		level.setBlock(pos.below(), lowerState.setValue(DoorBlock.OPEN, false), 3);
		level.levelEvent(null, LevelEvent.SOUND_CLOSE_IRON_DOOR, pos, 0);
	}

	@Override
	public void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean isMoving) {
		super.onRemove(state, level, pos, newState, isMoving);

		if (state.getBlock() != newState.getBlock())
			level.removeBlockEntity(pos);
	}

	@Override
	public boolean triggerEvent(BlockState state, Level level, BlockPos pos, int id, int param) {
		super.triggerEvent(state, level, pos, id, param);

		BlockEntity blockEntity = level.getBlockEntity(pos);

		return blockEntity == null ? false : blockEntity.triggerEvent(id, param);
	}

	@Override
	public ItemStack getCloneItemStack(BlockState state, HitResult target, BlockGetter level, BlockPos pos, Player player) {
		return new ItemStack(getDoorItem());
	}

	@Override
	public PushReaction getPistonPushReaction(BlockState state) {
		return PushReaction.BLOCK;
	}

	public abstract Item getDoorItem();
}

@@ -219,45 +219,8 @@
 os;%0A
-import net.minecraft.core.Direction;%0A
 impo
@@ -1181,1173 +1181,8 @@
 %09%7D%0A%0A
-%09@Override%0A%09public void neighborChanged(BlockState state, Level level, BlockPos pos, Block block, BlockPos neighbor, boolean flag) %7B%0A%09%09Block neighborBlock = level.getBlockState(neighbor).getBlock();%0A%0A%09%09if (state.getValue(HALF) == DoubleBlockHalf.UPPER) %7B%0A%09%09%09BlockPos posBelow = pos.below();%0A%09%09%09BlockState stateBelow = level.getBlockState(posBelow);%0A%0A%09%09%09if (stateBelow.getBlock() != this)%0A%09%09%09%09level.destroyBlock(pos, false);%0A%09%09%09else if (neighborBlock != this)%0A%09%09%09%09neighborChanged(stateBelow, level, posBelow, block, pos, flag);%0A%09%09%7D%0A%09%09else %7B%0A%09%09%09boolean drop = false;%0A%09%09%09BlockPos blockBelow = pos.above();%0A%09%09%09BlockState stateBelow = level.getBlockState(blockBelow);%0A%0A%09%09%09if (stateBelow.getBlock() != this) %7B%0A%09%09%09%09level.destroyBlock(pos, false);%0A%09%09%09%09drop = true;%0A%09%09%09%7D%0A%0A%09%09%09if (!level.getBlockState(pos.below()).isFaceSturdy(level, pos.below(), Direction.UP)) %7B%0A%09%09%09%09level.destroyBlock(pos, false);%0A%09%09%09%09drop = true;%0A%0A%09%09%09%09if (stateBelow.getBlock() == this)%0A%09%09%09%09%09level.destroyBlock(blockBelow, false);%0A%09%09%09%7D%0A%0A%09%09%09if (drop) %7B%0A%09%09%09%09if (!level.isClientSide) %7B%0A%09%09%09%09%09level.destroyBlock(pos, false);%0A%09%09%09%09%09Block.popResource(level, pos, new ItemStack(getDoorItem()));%0A%09%09%09%09%7D%0A%09%09%09%7D%0A%09%09%7D%0A%09%7D%0A%0A
 %09@Ov

remove unnecessary method from SpecialDoorBlock