<script lang="ts">
	import { post, postFormData, showMessage } from 'src/lib/requests.svelte';
	import type { Model } from './+page.svelte';
	import FileUpload from 'src/lib/FileUpload.svelte';
	import MessageSimple from 'src/lib/MessageSimple.svelte';
	import { createEventDispatcher, onDestroy } from 'svelte';
	import Spinner from 'src/lib/Spinner.svelte';
	import type { Task } from './tasks/TasksTable.svelte';
	import Tabs from 'src/lib/Tabs.svelte';
	import hljs from 'highlight.js';
	import { notificationStore } from 'src/lib/NotificationsStore.svelte';

	let { model } = $props<{ model: Model }>();

	let file: File | undefined = $state();

	const dispatch = createEventDispatcher<{ upload: void; taskReload: void }>();

	let _result: Promise<Task> = $state(new Promise(() => {}));
	let run = $state(false);

	let last_task: string | undefined = $state();
	let last_task_timeout: number | null = null;

	async function reloadLastTimeout() {
		if (!last_task) {
			return;
		}
		last_task_timeout = null;

		try {
			const r = await post('tasks/task', { id: last_task });
			if ([0, 1, 2, 3].includes(r.status)) {
				setTimeout(reloadLastTimeout, 500);
				setTimeout(() => dispatch('taskReload'), 500);
			} else {
				_result = Promise.resolve(r);
			}
		} catch (e) {
			console.error('Failed to get data');
		}
	}

	async function submit() {
		if (!file) return;

		let form = new FormData();
		form.append('json_data', JSON.stringify({ id: model.id }));
		form.append('file', file, 'file');

		run = true;

		try {
			const r = await postFormData('tasks/start/image', form);
			last_task = r.id;
			file = undefined;
			last_task_timeout = setTimeout(() => reloadLastTimeout());
		} catch (e) {
			showMessage(e, notificationStore, 'Could not run the model');
		}

		dispatch('upload');
	}

	onDestroy(() => {
		if (last_task_timeout) {
			clearTimeout(last_task_timeout);
		}
	});
</script>

<Tabs active="upload" let:isActive>
	<div class="buttons" slot="buttons" let:setActive let:isActive>
		<button class="tab" class:selected={isActive('upload')} on:click={setActive('upload')}>
			Upload
		</button>
		<button class="tab" class:selected={isActive('api')} on:click={setActive('api')}> Api </button>
	</div>
	<div class="content" class:selected={isActive('api')}>
		<div class="codeinfo">
			To perform an image classfication please follow the example bellow:
			<pre style="font-family: Fira Code;">{@html hljs.highlight(
					`let form = new FormData();
form.append('json_data', JSON.stringify({ id: '${model.id}' }));
form.append('file', file, 'file');

const headers = new Headers();
headers.append('response-type', 'application/json');
headers.append('token', token);

const r = await fetch('${window.location.protocol}//${window.location.hostname}/api/tasks/start/image', {
	method: 'POST',
	headers: headers,
	body: form
});`,
					{ language: 'javascript' }
				).value}</pre>
			On Success the request will return a json with this format:
			<pre style="font-family: Fira Code;">{@html hljs.highlight(
					`{ id	"00000000-0000-0000-0000-000000000000" }`,
					{ language: 'json' }
				).value}</pre>
			This id can be used to query the API for the result of the task:
			<pre style="font-family: Fira Code;">{@html hljs.highlight(
					`const headers = new Headers();
headers.append('content-type', 'application/json');
headers.append('token', token);

const r = await fetch('${window.location.protocol}//${window.location.hostname}/api/tasks/task', {
	method: 'POST',
	headers: headers,
	body: JSON.stringify({ id: '00000000-0000-0000-0000-000000000000' })
});`,
					{ language: 'javascript' }
				).value}</pre>
			Once the task shows the status as 4 then the data can be obatined in the result field: The successful
			return value has this type:
			<pre style="font-family: Fira Code;">{@html hljs.highlight(
					`{
    "id": string,
    "user_id": string,
    "model_id": string,
    "status": number,
    "status_message": string,
    "user_confirmed": number,
    "compacted": number,
    "type": number,
    "extra_task_info": string,
    "result": string,
    "created": string
}`,
					{ language: 'javascript' }
				).value}</pre>
		</div>
	</div>
	<div class="content" class:selected={isActive('upload')}>
		<form on:submit|preventDefault={submit} style="box-shadow: none;">
			<fieldset class="file-upload">
				<label for="file">Image</label>
				<div class="form-msg">Run image through them model and get the result</div>

				<FileUpload replace_slot bind:file accept="image/*">
					<img src="/imgs/upload-icon.png" alt="" />
					<span> Upload image </span>
					<div slot="replaced-name">
						<span> Image selected </span>
					</div>
				</FileUpload>
			</fieldset>
			<button> Run </button>
			{#if run}
				{#await _result}
					<h1>
						Processing Image! <Spinner />
					</h1>
				{:then result}
					{#if result.status == 4}
						{@const res = JSON.parse(result.result)}
						<div>
							<h1>Result</h1>
							The image was classified as {res.class} with confidence: {res.confidence}
						</div>
					{:else}
						<div class="result">
							<h1>There was a problem running the task:</h1>
							{result?.status_message}
						</div>
					{/if}
				{/await}
			{/if}
		</form>
	</div>
</Tabs>

<style lang="scss">
	.codeinfo {
		padding: 20px;
	}
</style>
