package ru.dbotthepony.mc.otm.shapes;

import net.minecraft.MethodsReturnNonnullByDefault;
import net.minecraft.world.phys.shapes.Shapes;
import net.minecraft.world.phys.shapes.VoxelShape;

import javax.annotation.ParametersAreNonnullByDefault;

@MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault
public record SimpleCuboid(double min_x, double min_y, double min_z, double max_x, double max_y, double max_z) {
	public SimpleCuboid normalized() {
		if (min_x <= max_x && min_y <= max_y && min_z <= max_z)
			return this;

		double min_x;
		double min_y;
		double min_z;
		double max_x;
		double max_y;
		double max_z;

		if (this.min_x <= this.max_x) {
			min_x = this.min_x;
			max_x = this.max_x;
		} else {
			min_x = this.max_x;
			max_x = this.min_x;
		}

		if (this.min_y <= this.max_y) {
			min_y = this.min_y;
			max_y = this.max_y;
		} else {
			min_y = this.max_y;
			max_y = this.min_y;
		}

		if (this.min_z <= this.max_z) {
			min_z = this.min_z;
			max_z = this.max_z;
		} else {
			min_z = this.max_z;
			max_z = this.min_z;
		}

		return new SimpleCuboid(min_x, min_y, min_z, max_x, max_y, max_z);
	}

	public VoxelShape getShape() {
		var normalize = normalized();

		return Shapes.box(normalize.min_x, normalize.min_y, normalize.min_z, normalize.max_x, normalize.max_y, normalize.max_z);
	}

	public SimpleCuboid rotateAroundY(final double rad) {
		final var rect = new Rectangle(
			new Point(min_x, min_z),
			new Point(max_x, min_z),
			new Point(max_x, max_z),
			new Point(min_x, max_z)
		).translate(-0.5, -0.5).rotate(rad).translate(0.5, 0.5);

		final double min_x = MathHelper.min(rect.a().x(), rect.b().x(), rect.c().x(), rect.d().x());
		final double max_x = MathHelper.max(rect.a().x(), rect.b().x(), rect.c().x(), rect.d().x());

		final double min_z = MathHelper.min(rect.a().y(), rect.b().y(), rect.c().y(), rect.d().y());
		final double max_z = MathHelper.max(rect.a().y(), rect.b().y(), rect.c().y(), rect.d().y());

		return new SimpleCuboid(min_x, min_y, min_z, max_x, max_y, max_z);
	}

	public SimpleCuboid rotateAroundX(final double rad) {
		final var rect = new Rectangle(
			new Point(min_z, min_y),
			new Point(max_z, min_y),
			new Point(max_z, max_y),
			new Point(min_z, max_y)
		).translate(-0.5, -0.5).rotate(rad).translate(0.5, 0.5);

		final double min_z = MathHelper.min(rect.a().x(), rect.b().x(), rect.c().x(), rect.d().x());
		final double max_z = MathHelper.max(rect.a().x(), rect.b().x(), rect.c().x(), rect.d().x());

		final double min_y = MathHelper.min(rect.a().y(), rect.b().y(), rect.c().y(), rect.d().y());
		final double max_y = MathHelper.max(rect.a().y(), rect.b().y(), rect.c().y(), rect.d().y());

		return new SimpleCuboid(min_x, min_y, min_z, max_x, max_y, max_z);
	}

	public SimpleCuboid rotateAroundZ(final double rad) {
		final var rect = new Rectangle(
			new Point(min_x, min_y),
			new Point(max_x, min_y),
			new Point(max_x, max_y),
			new Point(min_x, max_y)
		).translate(-0.5, -0.5).rotate(rad).translate(0.5, 0.5);

		final double min_x = MathHelper.min(rect.a().x(), rect.b().x(), rect.c().x(), rect.d().x());
		final double max_x = MathHelper.max(rect.a().x(), rect.b().x(), rect.c().x(), rect.d().x());

		final double min_y = MathHelper.min(rect.a().y(), rect.b().y(), rect.c().y(), rect.d().y());
		final double max_y = MathHelper.max(rect.a().y(), rect.b().y(), rect.c().y(), rect.d().y());

		return new SimpleCuboid(min_x, min_y, min_z, max_x, max_y, max_z);
	}

	public SimpleCuboid moveY(final double value) {
		return new SimpleCuboid(
			min_x,
			min_y + value,
			min_z,
			max_x,
			max_y + value,
			max_z
		);
	}
}
