<script lang="ts" context="module">
	export type Comment = {
		id: string;
		name: string;
		email: string;
		website: string;
		message: string;
		time: string;
		uuid: string;
	};
	export const ApiURL = mode == 'production' ? 'https://api.quenten.nl/api' : 'https://api.quenten.nl/api/testing';
</script>

<script lang="ts">
	import Errormodal from './errormodal.svelte';
	import { onMount } from 'svelte';
	import { sha256 } from 'js-sha256';
	import GuestbookEntry from './guestbook/guestbook-entry.svelte';
	import { mode } from '$app/env';
	
	//const ApiURL = dev ? 'https://api.quenten.nl/api/testing' : 'https://api.quenten.nl/api';
	//const ApiURL = import.meta.env.APIURL;
	let showError = false;
	let errorTitle = 'Error';
	let errorMessage = 'Error message';

	let name = '';
	let email = '';
	let website = '';
	let message = '';

	let DisplayComments: Comment[];
	let commentPage = 0;
	let pageSize = 10;

	const escapeHtml = (unsafe) => {
		return unsafe.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&#039;');
	}

	async function onSubmit(event: SubmitEvent) {
		// Validation
		if (name === '' || message === '') {
			errorMessage = 'You must enter a name and a message!';
			showError = true;
			return;
		}

		if (
			name.length >= 40 ||
			email.length >= 100 ||
			website.length >= 200 ||
			message.length >= 360
		) {
			errorMessage =
				'Your name must be < 40 characters. Email < 100, website < 200 and message < 360.';
			showError = true;
			return;
		}

		const data = {
			name,
			email,
			website,
			message
		};

		const jsonData = JSON.stringify(data);
		const res = await fetch(ApiURL + '/comment', {
			method: 'POST',
			body: jsonData
		});

		if (res.status >= 300) {
			errorMessage = await res.text();
			showError = true;
			return;
		}

		clear();
		getComments();
	}

	function clear() {
		name = '';
		email = '';
		website = '';
		message = '';
	}

	async function getComments() {
		// Check if in localstorage already
		let commentLS = localStorage.getItem('comments');
		let comments: Comment[];
		if (commentLS == null) {
			// Not yet in storage
			comments = await updateComments();
			DisplayComments = comments;
			return;
		}

		let newHash = await fetch(ApiURL + '/commenthash')
			.then((res) => res.text())
			.then((t) => {
				return t;
			});
		let oldHash = localStorage.getItem('commenthash');
		if (oldHash?.trim() !== newHash.trim()) {
			DisplayComments = await updateComments();
			return;
		}

		DisplayComments = JSON.parse(decodeURIComponent(window.atob(commentLS)));
	}

	async function fetchComments() {
		let comments: Comment[];
		comments = await fetch(ApiURL + '/comment')
			.then((res) => res.json())
			.then((data) => {
				return data;
			});
		return comments;
	}

	async function updateComments() {
		let comments = await fetchComments();
		localStorage.setItem('comments', window.btoa(encodeURIComponent(JSON.stringify(comments))));
		localStorage.setItem('commenthash', sha256(JSON.stringify(comments)));
		return comments;
	}

	onMount(() => {
		getComments();
	});
</script>

<Errormodal bind:show={showError} bind:title={errorTitle} bind:message={errorMessage} />
<div class="">
	<h2 class="font-semibold">Guestbook</h2>
	<p>You can leave any comment you want right here in this guestbook! No signing up necessary.</p>
	<form on:submit|preventDefault={onSubmit} class="mt-2 w-full grid gap-2">
		<input
			class="p-1 rounded bg- border-2 focus:border-pink-400 dark:focus:border-pink-700 outline-none"
			type="text"
			name="name"
			placeholder="Nickname (max. 40 chars)"
			bind:value={name}
		/>
		<input
			class="p-1 rounded bg- border-2 focus:border-pink-400 dark:focus:border-pink-700 outline-none"
			type="text"
			name="email"
			placeholder="Email (optional)"
			bind:value={email}
		/>
		<input
			class="p-1 rounded bg- border-2 focus:border-pink-400 dark:focus:border-pink-700 outline-none"
			type="text"
			name="website"
			placeholder="Website (optional)"
			bind:value={website}
		/>
		<textarea
			class="p-1 rounded bg- border-2 focus:border-pink-400 dark:focus:border-pink-700 outline-none"
			type="text"
			name="message"
			placeholder="Message (max. 360 chars)"
			bind:value={message}
		/>
		<button
			class="bg-blue-100 dark:bg-slate-700 border-slate-400 border-2 rounded-full py-2 w-fit px-10"
			type="submit">Submit</button
		>
	</form>
	<div>
		{#if DisplayComments != null}
			<div class="mt-4">
				<button class="px-5 py-2 bg-slate-400 dark:bg-slate-800 dark:ring-slate-400 dark:ring-2 rounded-xl mx-1" on:click={() => {if (commentPage > 0) commentPage -= 1}}>Previous</button>
				<button class="px-5 py-2 bg-slate-400 dark:bg-slate-800 dark:ring-slate-400 dark:ring-2 rounded-xl mx-1" on:click={() => commentPage += 1}>Next Page</button>
				<p class="ml-2 mt-1 w-full md:w-max">Current page: {commentPage + 1}</p>
			</div>
			{#each DisplayComments.slice(commentPage * pageSize, commentPage * pageSize + pageSize) as c}
				<GuestbookEntry comment={c} />
			{/each}
		{/if}
	</div>
</div>
