package com.leisuretimedock.blasttravelreborn.client.entity;

import com.leisuretimedock.blasttravelreborn.BlastTravelReborn;
import com.leisuretimedock.blasttravelreborn.content.entity.CannonEntity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRenderer;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.jetbrains.annotations.NotNull;

@OnlyIn(Dist.CLIENT)
public class CannonEntityRenderer extends EntityRenderer<CannonEntity> {
	public static final ModelLayerLocation MODEL = new ModelLayerLocation(BlastTravelReborn.id("cannon"), "main");

	private static final ResourceLocation[] FIRE_TEXTURES = {
			BlastTravelReborn.id("textures/entity/cannon_fire/frame_0.png"),
			BlastTravelReborn.id("textures/entity/cannon_fire/frame_1.png"),
			BlastTravelReborn.id("textures/entity/cannon_fire/frame_2.png"),
			BlastTravelReborn.id("textures/entity/cannon_fire/frame_3.png"),
			BlastTravelReborn.id("textures/entity/cannon_fire/frame_4.png")
	};

	private static final ResourceLocation[] DYED_FIRE_TEXTURES = {
			BlastTravelReborn.id("textures/entity/cannon_fire/dyed_frame_0.png"),
			BlastTravelReborn.id("textures/entity/cannon_fire/dyed_frame_1.png"),
			BlastTravelReborn.id("textures/entity/cannon_fire/dyed_frame_2.png"),
			BlastTravelReborn.id("textures/entity/cannon_fire/dyed_frame_3.png"),
			BlastTravelReborn.id("textures/entity/cannon_fire/dyed_frame_4.png")
	};

	private static final ResourceLocation[] SMOKE_TEXTURES = {
			BlastTravelReborn.id("textures/entity/cannon_smoke/frame_0.png"),
			BlastTravelReborn.id("textures/entity/cannon_smoke/frame_1.png"),
			BlastTravelReborn.id("textures/entity/cannon_smoke/frame_2.png"),
			BlastTravelReborn.id("textures/entity/cannon_smoke/frame_3.png"),
			BlastTravelReborn.id("textures/entity/cannon_smoke/frame_4.png")
	};

	private final ModelPart root;
	private final ModelPart leftWheel;
	private final ModelPart rightWheel;
	private final ModelPart cannon;
	private final ModelPart chains;
	private final ModelPart fuse;
	private final ModelPart playerHead;
	private final ModelPart fire;

	public CannonEntityRenderer(EntityRendererProvider.Context context) {
		super(context);
		ModelPart modelPart = context.bakeLayer(MODEL);
		this.root = modelPart.getChild("main");
		this.leftWheel = this.root.getChild("left_wheel");
		this.rightWheel = this.root.getChild("right_wheel");
		this.cannon = this.root.getChild("cannon");
		this.playerHead = this.root.getChild("player_head");
		this.fire = this.root.getChild("fire");

		this.chains = this.cannon.getChild("chains");
		this.fuse = this.cannon.getChild("fuse");

		this.resetModel();
	}

	private void resetModel() {
		this.leftWheel.xRot = this.rightWheel.xRot = 0;
		this.cannon.xRot = 0;

		this.cannon.visible = true;
		this.playerHead.visible = false;
		this.fuse.visible = true;
		this.chains.visible = false;
		this.fire.visible = false;
	}

	@Override
	public @NotNull ResourceLocation getTextureLocation(CannonEntity entity) {
		return entity.getBehavior().texture(entity.getBehaviorStack());
	}

	@Override
	public void render(@NotNull CannonEntity entity, float yaw, float tickDelta, @NotNull PoseStack matrices, @NotNull MultiBufferSource vertexConsumers, int light) {
		super.render(entity, yaw, tickDelta, matrices, vertexConsumers, light);
		matrices.pushPose();
		var behavior = entity.getBehavior();

		yaw = (180 + yaw) * Mth.DEG_TO_RAD;

		// 1.2 is the ratio of the circumference of the wheelbase to the circumference of the wheel (probably)
		float wheelAngle = yaw * 1.2f;

		this.leftWheel.xRot = wheelAngle;
		this.rightWheel.xRot = -wheelAngle;
		this.cannon.xRot = (entity.getViewXRot(tickDelta) + 90) * Mth.DEG_TO_RAD;

		boolean renderCannon = (entity.getFirstPassenger() != Minecraft.getInstance().player) ||
				Minecraft.getInstance().gameRenderer.getMainCamera().isDetached();

		this.cannon.visible = renderCannon;
		this.chains.visible = entity.hasChains();
		this.fuse.visible = entity.hasFuse();

		matrices.mulPose(Axis.ZP.rotationDegrees(180));
		matrices.mulPose(Axis.YP.rotation(yaw));

		float anim = entity.getAnimation(tickDelta);
		matrices.mulPose(Axis.XP.rotationDegrees(
				-5 * (-2 * (anim*anim*anim*anim*anim*anim*anim*anim) + 2 * (anim*anim)))); // pow() goes the cannon

		this.root.render(matrices, vertexConsumers.getBuffer(RenderType.entityCutout(this.getTextureLocation(entity))), light, OverlayTexture.NO_OVERLAY);

		var color = behavior.fireColor(entity);
		int tick = Math.max(0, (CannonEntity.MAX_ANIMATION - entity.getAnimationTick()) - 3);
		if (tick <= 7) {
			this.fire.visible = true;
			this.fire.xRot = this.cannon.xRot;
		}
		if (tick <= 4) {
			if (color != null) {
				this.fire.render(matrices, vertexConsumers.getBuffer(RenderType.eyes(DYED_FIRE_TEXTURES[tick])),
						light, OverlayTexture.NO_OVERLAY, color.x, color.y, color.z, 1);
			} else {
				this.fire.render(matrices, vertexConsumers.getBuffer(RenderType.eyes(FIRE_TEXTURES[tick])), light, OverlayTexture.NO_OVERLAY);
			}
		}
		tick -= 3;
		if (tick >= 0 && tick <= 4) {
			this.fire.render(matrices, vertexConsumers.getBuffer(RenderType.entityTranslucent(SMOKE_TEXTURES[tick])), light, OverlayTexture.NO_OVERLAY,
					1, 1, 1, 0.9f - (0.07f * tick));
		}

		if (renderCannon && behavior.displayHead(entity)) {
			this.playerHead.visible = true;
			this.playerHead.xRot = this.cannon.xRot;

			color = behavior.headColor(entity);
			this.playerHead.render(matrices,
					vertexConsumers.getBuffer(RenderType.entityCutoutNoCull(behavior.headTexture(entity))),
					light, OverlayTexture.NO_OVERLAY, color.x, color.y, color.z, 1);
		}

		this.resetModel();
		matrices.popPose();
	}
}
