import { Vector2, WebGLRenderer } from 'three';

class SelectionHelper {
	element: HTMLDivElement;
	renderer: WebGLRenderer;
	startPoint: Vector2;
	pointTopLeft: Vector2;
	pointBottomRight: Vector2;
	isDown: boolean;
	enabled: boolean;

	constructor(renderer: WebGLRenderer) {
		this.element = document.createElement('div');
		this.element.style.position = 'fixed';
		this.element.style.border = '1px solid #55aaff';
		this.element.style.backgroundColor = 'rgba(75, 160, 255, 0.3)';
		this.element.style.pointerEvents = 'none';
		this.element.style.display = 'none';

		this.renderer = renderer;

		this.startPoint = new Vector2();
		this.pointTopLeft = new Vector2();
		this.pointBottomRight = new Vector2();

		this.isDown = false;
		this.enabled = true;

		this.onPointerDown = this.onPointerDown.bind(this);
		this.onPointerMove = this.onPointerMove.bind(this);
		this.onPointerUp = this.onPointerUp.bind(this);

		this.renderer.domElement.addEventListener('pointerdown', this.onPointerDown);
		this.renderer.domElement.addEventListener('pointermove', this.onPointerMove);
		this.renderer.domElement.addEventListener('pointerup', this.onPointerUp);
		window.addEventListener("blur", this.cleanup.bind(this));
	}

	dispose() {
		this.enabled = false;
		this.isDown = false;
		this.cleanup();

		this.renderer.domElement.removeEventListener("pointerdown", this.onPointerDown);
		this.renderer.domElement.removeEventListener("pointermove", this.onPointerMove);
		this.renderer.domElement.removeEventListener("pointerup", this.onPointerUp);
		window.removeEventListener("blur", this.cleanup);
	}

	private cleanup() {
		this.isDown = false;
		this.element.style.display = 'none';
		if (this.element.parentElement) {
			this.element.parentElement.removeChild(this.element);
		}
	}

	onPointerDown(event: PointerEvent) {
		if (!this.enabled || !event.ctrlKey || event.button !== 0) return;

		this.isDown = true;
		this.onSelectStart(event);
	}

	onPointerMove(event: PointerEvent) {
		if (!this.enabled || !this.isDown || !event.ctrlKey) return;

		this.onSelectMove(event);
	}

	onPointerUp() {
		if (!this.enabled) return;

		this.isDown = false;
		this.onSelectOver();
	}

	onSelectStart(event: PointerEvent) {
		this.element.style.display = 'none';
		this.renderer.domElement.parentElement?.appendChild(this.element);

		this.element.style.left = `${event.clientX}px`;
		this.element.style.top = `${event.clientY}px`;
		this.element.style.width = '0px';
		this.element.style.height = '0px';

		this.startPoint.x = event.clientX;
		this.startPoint.y = event.clientY;
	}

	onSelectMove(event: PointerEvent) {
		if (!this.isDown) return;

		this.element.style.display = 'block';

		this.pointBottomRight.x = Math.max(this.startPoint.x, event.clientX);
		this.pointBottomRight.y = Math.max(this.startPoint.y, event.clientY);
		this.pointTopLeft.x = Math.min(this.startPoint.x, event.clientX);
		this.pointTopLeft.y = Math.min(this.startPoint.y, event.clientY);

		this.element.style.left = `${this.pointTopLeft.x}px`;
		this.element.style.top = `${this.pointTopLeft.y}px`;
		this.element.style.width = `${this.pointBottomRight.x - this.pointTopLeft.x}px`;
		this.element.style.height = `${this.pointBottomRight.y - this.pointTopLeft.y}px`;
	}

	onSelectOver() {
		this.element.style.display = 'none';
		if (this.element.parentElement) {
			this.element.parentElement.removeChild(this.element);
		}
	}
}

export { SelectionHelper };