let socket = new ReconnectingWebSocket('ws://' + location.host + '/ws');

let map_container = document.getElementById('map-container');
let title = document.getElementById('title');
let diff = document.getElementById('diff');
let artist = document.getElementById('artist');
let replay = document.getElementById('replay');
let stage = document.getElementById('stage');
let stage_container = document.getElementById('stage-container');

let stage_data, mappool, stage_updated = false;
(async () => {
	$.ajaxSetup({ cache: false });
	stage_data = await $.getJSON('../_data/current_round.json');
	mappool = await $.getJSON('../_data/beatmaps.json');
})();

socket.onopen = () => { console.log('Successfully Connected'); };

socket.onclose = event => {
	console.log('Socket Closed Connection: ', event);
	socket.send('Client Closed!');
};

socket.onerror = error => { console.log('Socket Error: ', error); };

let image, title_, diff_, artist_, replay_, id;
let ar, od, cs, sr, bpm, md5, len;

socket.onmessage = async event => {
	let data = JSON.parse(event.data);

	// update stage/mod info bar
	if (stage && mappool && stage_data && (id !== data.menu.bm.id || !stage_updated)) {
		id = data.menu.bm.id;
		let map = mappool.find(m => m.beatmap_id == id);
		let text = `${stage_data.long_name.toUpperCase()} MAPPOOL SHOWCASE${map ? ` / ${map.identifier}` : ''}`;

		let width = Math.round(getTextWidth(text, '16px Fax-Sans') + (text.length - 1) * 2) + 18;
		stage_container.style.clipPath = `polygon(calc(100% - ${width + 30}px) 0, 100% 0, 100% 100%, calc(100% - ${width}px) 100%)`;

		stage.innerHTML = text;
		stage_updated = true;
	}

	// update background image
	if (image !== data.menu.bm.path.full) {
		image = data.menu.bm.path.full;
		data.menu.bm.path.full = data.menu.bm.path.full.replace(/#/g, '%23').replace(/%/g, '%25').replace(/\\/g, '/');
		map_container.style.backgroundImage = `url('http://${location.host}/Songs/${data.menu.bm.path.full}')`;
	}

	// update title
	if (title_ !== data.menu.bm.metadata.title) {
		title_ = data.menu.bm.metadata.title;
		title.innerHTML = title_;
	}

	// update diff/mapper
	if (diff_ !== `<b>[${data.menu.bm.metadata.difficulty}]</b> by ${data.menu.bm.metadata.mapper}`) {
		diff_ = `<b>[${data.menu.bm.metadata.difficulty}]</b> by ${data.menu.bm.metadata.mapper}`;
		diff.innerHTML = diff_;
	}

	// update artist
	if (artist_ !== data.menu.bm.metadata.artist) {
		artist_ = data.menu.bm.metadata.artist;
		artist.innerHTML = artist_;
	}

	// update replayer
	if ((!data.resultsScreen.name && replay_ !== data.gameplay.name) || (data.resultsScreen.name && replay_ !== data.resultsScreen.name)) {
		replay_ = data.resultsScreen.name || data.gameplay.name;
		replay.innerHTML = replay_ ? `REPLAY BY <b>${replay_.toUpperCase()}</b>` : ' ';
	}

	// update map stats
	if (ar !== data.menu.bm.stats.AR || cs !== data.menu.bm.stats.CS || sr !== data.menu.bm.stats.fullSR || len !== (data.menu.bm.time.full - data.menu.bm.time.firstObj)) {
		
		md5 = data.menu.bm.md5;
		ar = data.menu.bm.stats.AR;
		cs = data.menu.bm.stats.CS;
		od = data.menu.bm.stats.OD;
		sr = data.menu.bm.stats.fullSR;
		bpm = data.menu.bm.stats.BPM.max;

		let length_modifier = data.resultsScreen.mods.str.includes('DT') || data.menu.mods.str.includes('DT') ? 1.5 : 1;
		len = data.menu.bm.time.full - data.menu.bm.time.firstObj;
		let mins = Math.trunc((len / length_modifier) / 1000 / 60);
		let secs = Math.trunc((len / length_modifier) / 1000 % 60);
		let songlength = `${mins}:${secs.toString().padStart(2, '0')}`;

		document.getElementById('stats-1').innerHTML = `CS <b>${cs}</b> <i>/</i> AR <b>${ar}</b> <i>/</i> OD <b>${od}</b>`;
		document.getElementById('stats-2').innerHTML = `BPM <b>${bpm}</b> <i>/</i> LENGTH <b>${songlength}</b> <i>/</i> SR <b>${sr}★</b>`;
	}
}

function getTextWidth(text, font) {
	const canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement('canvas'));
	const context = canvas.getContext('2d');
	context.font = font;
	const metrics = context.measureText(text);
	return metrics.width;
}