/* eslint no-param-reassign: "off" */

let styleBuffer = '';
const fullTextStorage = {};

export function writeTerminal(el, char) {
	let fullText = fullTextStorage[el.id];
	if (!fullText) {
		fullText = el.innerHTML;
		fullTextStorage[el.id] = el.innerHTML;
	}

	fullText = handleTerminalChar(fullText, char);

	// But we still write to the DOM every iteration, which can be pretty slow.
	el.innerHTML = fullText;
	fullTextStorage[el.id] = fullText;
}

export function handleTerminalChar(fullText, char) {
	if (char === '\n') {
		// have not finger out '\n' not working in <pre /> when ignore animation, replace to <br/> can bypass it
		return fullText + '<br/><span class="terminal-user">Jinseyun$ </span>';
	}
	return fullText + char;
}

export default function writeChar(el, char, style) {
	// Grab text. We buffer it in storage so we don't have to read from the DOM every iteration.
	let fullText = fullTextStorage[el.id];
	if (!fullText) {
		fullText = el.innerHTML;
		fullTextStorage[el.id] = el.innerHTML;
	}

	fullText = handleChar(fullText, char);
	// But we still write to the DOM every iteration, which can be pretty slow.
	el.innerHTML = fullText;
	fullTextStorage[el.id] = fullText;

	// Buffer writes to the <style> element so we don't have to paint quite so much.
	styleBuffer += char;
	if (char === ';') {
		style.textContent += styleBuffer;
		styleBuffer = '';
	}
}

export function writeSimpleChar(el, char) {
	el.innerHTML += char;
}

let openComment = false;
const commentRegex = /(\/\*(?:[^](?!\/\*))*\*)$/;
const keyRegex = /([a-zA-Z- ^\n]*)$/;
const valueRegex = /([^:]*)$/;
const selectorRegex = /(.*)$/;
const pxRegex = /\dp/;
const pxRegex2 = /p$/;

export function handleChar(fullText, char) {
	if (openComment && char !== '/') {
		// Short-circuit during a comment so we don't highlight inside it.
		fullText += char;
	} else if (char === '/' && openComment === false) {
		openComment = true;
		fullText += char;
	} else if (char === '/' && fullText.slice(-1) === '*' && openComment === true) {
		openComment = false;
		// Unfortunately we can't just open a span and close it, because the browser will helpfully
		// 'fix' it for us, and we'll end up with a single-character span and an empty closing tag.
		fullText = fullText.replace(commentRegex, '<span class="comment">$1/</span>');
	} else if (char === ':') {
		fullText = fullText.replace(keyRegex, '<span class="key">$1</span>:');
	} else if (char === ';') {
		fullText = fullText.replace(valueRegex, '<span class="value">$1</span>;');
	} else if (char === '{') {
		fullText = fullText.replace(selectorRegex, '<span class="selector">$1</span>{');
	} else if (char === 'x' && pxRegex.test(fullText.slice(-2))) {
		fullText = fullText.replace(pxRegex2, '<span class="value px">px</span>');
	} else {
		fullText += char;
	}
	return fullText;
}
