import { ce } from 'morphux';
import { delay } from './utils';
import { Main } from './main';
import { AnsiUp } from 'ansi_up';

export class LogsHandler {
	private _Main: Main;

	ansiUp = new AnsiUp();

	cameraLogsContainer: HTMLDivElement = document.querySelector(
		'.ntsh_tab[tabid="cameralogs"] .ntsh_logs'
	);
	unityLogsContainer: HTMLDivElement = document.querySelector(
		'.ntsh_tab[tabid="unitylogs"] .ntsh_logs'
	);

	constructor(Main: Main) {
		this._Main = Main;

		this.registerListeners();
	}

	setCameraLogs(logs: string[]) {
		this.applyLogs(this.cameraLogsContainer, logs);
	}

	setUnityLogs(logs: string[]) {
		this.applyLogs(this.unityLogsContainer, logs);
	}

	private firstTime: Set<HTMLDivElement> = new Set();

	private async applyLogs(container: HTMLDivElement, logs: string[]) {
		let logCount = container.querySelectorAll(
			'.ntsh_log.ntsh_log-normal'
		).length;
		if (logCount === logs.length) return;
		if (logCount > logs.length) logCount = 0;

		const isAtBottom =
			!this.firstTime.has(container) ||
			container.scrollTop + container.clientHeight >=
				container.scrollHeight;

		container.innerHTML = '';

		logs.forEach((log, i) => {
			const element = ce(
				'div',
				['ntsh_log', 'ntsh_log-normal'],
				null,
				null,
				this.ansiUp.ansi_to_html(log)
			);

			if (this.firstTime.has(container) && i > logCount - 1) {
				element.style.display = 'none';
				const spawnDelay = (i - logCount) * 10;
				setTimeout(() => {
					element.style.display = 'block';
					if (isAtBottom)
						container.scrollTop = container.scrollHeight;
				}, spawnDelay);
			}

			container.appendChild(element);
			if (isAtBottom) container.scrollTop = container.scrollHeight;
		});

		if (!this.firstTime.has(container)) {
			container.scrollTop = container.scrollHeight;
			this.firstTime.add(container);
		}
	}

	private registerListeners() {
		this._Main.TabController.registerListener('cameralogs', (visible) => {
			if (!visible) return;

			setTimeout(() => {
				this.cameraLogsContainer.scrollTop =
					this.cameraLogsContainer.scrollHeight;
			}, 10);
		});

		this._Main.TabController.registerListener('unitylogs', (visible) => {
			if (!visible) return;

			setTimeout(() => {
				this.unityLogsContainer.scrollTop =
					this.unityLogsContainer.scrollHeight;
			}, 10);
		});
	}
}
