<script>
	import { onMount, tick } from 'svelte';

	let { percent, unzipping, installed } = $props();

	let element;
	let emptyChar = '·';
	let filledChar = '■';
	let endChar = '';
	let startChar = '|';
	let spinnerChars = ['⣾', '⣽', '⣻', '⢿', '⡿', '⣟', '⣯', '⣷'];
	let spinnerAlt = ['⠁', '⠂', '⠄', '⡀', '⢀', '⠠', '⠐', '⠈'];
	let spinner = '';
	let barWidth = $state(0);

	let bar = $state('');

	onMount(async () => {
		requestAnimationFrame(updateBar);
		//const resizeObserver = new ResizeObserver(updateBar);
		//resizeObserver.observe(element);
	});

	async function updateBar(timestamp) {
		if (!element) return;
		spinner = spinnerChars[Math.floor(timestamp / 150) % spinnerChars.length];
		const style = window.getComputedStyle(element);
		const fontSize = parseFloat(style.fontSize);
		// Estimate character width as roughly 60% of font size (monospace approximation)
		const charWidth = fontSize * 0.57;
		barWidth = Math.floor(element.clientWidth / charWidth) - 2;
		bar =
			startChar +
			filledChar.repeat(Math.ceil((percent / 100) * barWidth)) +
			'|' +
			emptyChar.repeat(barWidth - Math.ceil((percent / 100) * barWidth)) +
			endChar;
		if (unzipping) {
			const installText = '|  |';
			const barLength = barWidth;
			const installStart = Math.floor((timestamp / 10) % (barLength + installText.length));
			const barArray = bar.split('');
			for (let i = 0; i < installText.length; i++) {
				const pos = installStart + i;
				if (pos >= barLength) {
					barArray[pos - barLength] = installText[i];
				} else {
					barArray[pos] = installText[i];
				}
			}
			bar = barArray.join('');
		}
		requestAnimationFrame(updateBar);
	}
</script>

<div bind:this={element} id="progress">
	{#each bar as char, index (index)}
		<span class="fixed-char" class:installed>{char}</span>
	{/each}
</div>

<style>
	#progress {
		box-sizing: border-box;
		width: 100%;
	}
	.fixed-char {
		display: inline-block;
		font-family: var(--font);
		width: 1ch;
		max-width: 1ch;
		min-width: 1ch;
		text-align: center;
		overflow: visible;
		color: var(--accent);
		transition: 0.2s ease-in-out;
	}
	.fixed-char.installed {
		color: var(--black);
	}
</style>
