<script lang="ts">
	import { Terminal, type PrintData } from '$lib/stores/terminal/terminal';
	import { onMount } from 'svelte';
	import Input from './terminal/Input.svelte';
	import { initTerminal, isInitializing } from '$lib/stores/terminal/init.svelte';
	import { clear, print } from '$lib/stores/terminal/stdio/io';
	import type { User } from '$lib/stores/bash/etc/userData';

	const clearTerminal = (): void => clear();

	const printOutput = (e: HTMLElement, d: PrintData): void => print(e, d);

	function updateTerminal() {
		username = terminal!.getUser().username;
		cwd = terminal!.getCwd();
	}

	function getWidth() {
		const e = document.getElementById('cout');
		if(!e){
			throw new Error('cant get width of the teminal element. Its null');
		}
		//gets an int from padding property value (which is a string) by cutting last 2 letters "px" and parsing to int
		const padding: number = parseInt(window.getComputedStyle(e, null).getPropertyValue('padding').slice(0, -2));
		return e.clientWidth - (padding * 2);
	}

	function getFontSize() {
		const e = document.getElementById('cout');
		if(!e) {
			throw new Error('cant get font size of the terminal element. its null');
		}

		const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d')!;
        ctx.font = `${window.getComputedStyle(e, null).getPropertyValue('font-size')} 'JetBrains Mono', monospace;`;
		return ctx.measureText('M').width;
	}

	function inputHandler(event: KeyboardEvent) {
		switch (event.key) {
			case 'Enter': {
				terminal.executeCommand(inputValue);
				updateTerminal();
				break;
			}
			case 'ArrowRight': {
				//TODO: Move cursor visually
			}
			case 'ArrowLeft': {
				//TODO: Move cursor visually
			}
			case 'ArrowUp': {
				//TODO: Make a traverse history function with up/down args
			}
			case 'ArrowDown': {
				//TODO: Make a traverse history function with up/down args
			}
		}

		const elem = document.getElementById('cout');
		if(!elem){
			throw new Error('cant scroll to bottom, element is null');
		}

		elem.scrollTop = elem.scrollHeight;
	}

	//Callback initializer
	const callbackInit = {
		print: (data: any) => {
			const e = document.getElementById('outputWrapper');
			if (!e) return;
			printOutput(e, data);
		},
		clear: clearTerminal,
		getWidth: getWidth,
		getFontSize: getFontSize
	};

	//Test user with basic data so the bash can run
	let testUser: User = {
		username: 'kamil',
		passwd: '123',
		uid: 0,
		gid: 0,
		home: '/home/kamil',
		history: []
	};

	//Empty terminal variable where the terminal class instance will be stored
	let terminal: Terminal;
	let username: string = $state(testUser.username);
	let cwd: string = $state(testUser.home);

	let inputValue = $state<string>('');

	onMount(async () => {
		try {
			terminal = await initTerminal({ username: 'root', password: '123'}, callbackInit, 'en_US');
			updateTerminal();
		} catch (error) {
			console.error('onMount trycatch failed', error);
		}
	});
</script>

<label for="input" onkeydowncapture={(event) => inputHandler(event)} class="w-11/12">
	<div id="terminal" class="terminal-window shadow-() h-full w-full rounded-md shadow-bg">
		<div
			class="terminal-bar flex h-9 w-full flex-row items-center rounded-t-md bg-bg-dark text-center font-terminal text-sm font-bold text-primary-dark light:bg-bg-dark-light light:text-primary-light"
		>
			<div class="dots-wrapper mx-2.5 flex h-full flex-row items-center justify-center gap-2.5">
				<button class="size-2.5 cursor-pointer rounded-full p-0" title=""></button>
				<button class="size-2.5 cursor-pointer rounded-full p-0" title=""></button>
				<button class="size-2.5 cursor-pointer rounded-full p-0" title=""></button>
			</div>
			<div class=" flex mr-2 grow">
				<h5>{username}</h5>
				<!-- prettier-ignore -->
				<h5 class=" mr-2">@terminal: </h5>
				<h5>{cwd}</h5>
			</div>
		</div>
		<div
			class="inner-content scroll-hidden h-7/8 origin-top overflow-y-auto rounded-b-md bg-bg-light-dark p-4 text-text-dark shadow-subtle light:bg-bg-lighter-light light:text-text-light"
			id="cout"
		>
			<div id="outputWrapper"></div>
			<Input {cwd} bind:inputValue />
		</div>
	</div>
</label>

<style>
	* {
		transition: var(--transition-standard);
	}
	.dots-wrapper {
		& > button {
			border: none;
			&:hover {
				transform: translateY(-0.1rem);
			}
			&:active {
				transform: translate(0);
			}
			&:nth-child(1) {
				background-color: rgb(255, 0, 0);
				&:active {
					background-color: rgb(255, 100, 100);
				}
			}
			&:nth-child(2) {
				background-color: rgb(255, 165, 0);
				&:active {
					background-color: rgb(255, 215, 50);
				}
			}
			&:nth-child(3) {
				background-color: rgb(50, 205, 50);
				&:active {
					background-color: rgb(100, 255, 100);
				}
			}
		}
	}
</style>
