<script lang="ts">
	import { persisted } from '$lib/helpers/localStore';
	import { fade, slide } from 'svelte/transition';
	import TextSplit from './TextSplit.svelte';
	import ImageFrame from './ImageFrame.svelte';
	import Button from './button.svelte';
	import InputRange from './InputRange.svelte';
	import { goto } from '$app/navigation';
	import Loader from './Loader.svelte';

	let data = persisted<{
		name: string;
		showNameLengthError: boolean;
		nameAccepted?: boolean;

		provideAdelsTitel?: boolean;
		adelsTitel?: string;
		showAdelsTitelLengthError: boolean;
		adelsTitelAccepted?: boolean;
		adelsTitelSuggestions?: string[];

		providePortrait?: boolean;
		portraitUrl?: string;
		portraitHairType?: 'straight' | 'curly' | 'bald';
		portraitHairColor?: 'red' | 'brown' | 'blonde' | 'black' | 'grey' | 'white';
		portraitHairLength?: 'short' | 'medium' | 'long';
		portraitSkinColor?: 'very light' | 'light' | 'medium' | 'dark' | 'very dark';
		portraitAccepted?: boolean;
		portraitPublic?: boolean;

		confidence?: number;
		confidenceAccepted?: boolean;

		createPersonality?: boolean;
	}>('data', {
		name: '',
		showNameLengthError: false,
		nameAccepted: false,
		adelsTitel: undefined,
		showAdelsTitelLengthError: false,
		adelsTitelSuggestions: [],
		provideAdelsTitel: undefined,
		portraitPublic: true,
		confidence: undefined,
		confidenceAccepted: false,
		createPersonality: undefined
	});

	$: if ($data.name.length > 99) {
		$data.showNameLengthError = true;
	}

	$: if ($data?.adelsTitel?.length > 99) {
		$data.showAdelsTitelLengthError = true;
	}

	let loadingAdelsTitel = false;
	async function fetchAdelsTitel() {
		if (loadingAdelsTitel) return;
		loadingAdelsTitel = true;

		const res = await fetch('/api/ai/name/' + $data.name);
		const json = await res.json();
		$data.adelsTitelSuggestions = json;
		loadingAdelsTitel = false;
	}

	let loadingPortrait = false;
	async function fetchPortrait() {
		if (loadingPortrait) return;
		loadingPortrait = true;

		const res = await fetch(`/api/ai/image/${$data.adelsTitel || $data.name}`, {
			method: 'POST',
			body: JSON.stringify({
				hairType: $data.portraitHairType,
				hairColor: $data.portraitHairColor,
				hairLength: $data.portraitHairLength,
				skinColor: $data.portraitSkinColor,
				name: $data.name
			})
		});

		const json = await res.json();

		$data.portraitUrl = json.url;
		loadingPortrait = false;
	}

	let isSubmitting = false;
	async function submit() {
		if (isSubmitting) return;
		isSubmitting = true;
		await fetch(`/api/invites`, {
			method: 'POST',
			body: JSON.stringify($data)
		});
		localStorage.clear();
		localStorage.setItem('last-name', $data?.adelsTitel || '');
		isSubmitting = false;
		goto('/gallery');
	}
</script>

<div class="wrapper">
	<section in:slide={{ delay: 500 }}>
		<TextSplit content="Wie lauten Euer Vor- und Nachname, edler Gast?" />
		<input placeholder="Name" type="text" bind:value={$data.name} />

		{#if $data.name.length > 99}
			<p class="error">
				Wir bitten um Entschuldigung, aber dieser Name ist zu lang. (maximal 100 Zeichen)
			</p>
		{:else if $data.showNameLengthError}
			<p class="hint">{$data.name.length}/100 Zeichen</p>
		{/if}
		{#if !$data.nameAccepted}
			<button
				disabled={$data.name.length > 99}
				on:click={() => {
					$data.nameAccepted = true;
				}}>Name speichern</button
			>
		{/if}
	</section>

	{#if ($data.name && $data.nameAccepted) || $data.confidence !== undefined}
		<section in:slide={{ delay: 0, duration: 500 }}>
			<TextSplit
				content="Wie sicher dürfen wir mit Eurem glanzvollen Erscheinen rechnen?"
				delay={0}
			/>
			<div in:fade={{ delay: 1200 }}>
				<InputRange bind:value={$data.confidence} />
			</div>
			{#if !$data.confidenceAccepted}
				<button
					on:click={() => {
						$data.confidenceAccepted = true;
					}}>ok</button
				>
			{/if}
		</section>
	{/if}

	{#if $data.confidence !== undefined && $data.confidenceAccepted && $data.createPersonality === undefined}
		<section in:slide out:slide>
			<TextSplit
				content="Möchtet Ihr, dass wir eine alternative Persönlichkeit für Euch erschaffen?"
			/>
			<div>
				<button
					on:click={() => {
						$data.createPersonality = true;
					}}>Ja</button
				>
				<button
					on:click={() => {
						$data.createPersonality = false;
					}}>Nein</button
				>
			</div>
			{#if $data.adelsTitel}
				{$data.adelsTitel}
			{/if}
		</section>
	{/if}

	{#if $data.createPersonality === true}
		<section in:fade out:slide>
			{#if $data.provideAdelsTitel === undefined}
				<TextSplit content="Möchtet Ihr einen würdigen Adelsnamen für Euch in Erwägung ziehen?" />
				<div>
					<button
						on:click={() => {
							fetchAdelsTitel();
							$data.provideAdelsTitel = true;
						}}
					>
						ja</button
					>
					<button
						on:click={() => {
							$data.adelsTitel = '';
							$data.provideAdelsTitel = true;
						}}
					>
						ich habe bereits einen
					</button>
					<button
						on:click={() => {
							$data.adelsTitel = '';
							$data.provideAdelsTitel = false;
						}}
					>
						nein</button
					>
				</div>
			{/if}

			{#if loadingAdelsTitel}
				<div style="display: flex; gap: 20px; align-items: center;">
					<Loader />
					<p>Adelsnamen werden geschrieben</p>
				</div>
			{:else if typeof $data.adelsTitel === 'string'}
				<TextSplit content="Euer Adelsname" />
				<input placeholder="Name" type="text" bind:value={$data.adelsTitel} />
				{#if $data.adelsTitel.length > 98}
					<p class="error">
						Wir bitten um Entschuldigung, aber dieser Titel ist zu lang. (maximal 100 Zeichen)
					</p>
				{:else if $data.showAdelsTitelLengthError}
					<p class="hint">{$data.adelsTitel.length}/100 Zeichen</p>
				{/if}
				{#if !$data.adelsTitelAccepted}
					<button
						disabled={$data.adelsTitel.length > 99}
						on:click={() => {
							$data.adelsTitelAccepted = true;
						}}>akzeptieren</button
					>
					<button
						on:click={() => {
							$data.adelsTitel = undefined;
							fetchAdelsTitel();
						}}>neue vorschläge</button
					>
				{/if}
			{:else if $data.adelsTitelSuggestions?.length}
				<p>Adelsname Vorschläge</p>
				<hr />
				{#each $data.adelsTitelSuggestions as suggestion}
					<button
						on:click={() => {
							$data.adelsTitel = suggestion;
						}}>{suggestion}</button
					>
				{/each}
				<hr />
				<button
					on:click={() => {
						fetchAdelsTitel();
					}}>neue vorschläge</button
				>
			{/if}
		</section>
	{/if}

	{#if $data.adelsTitel && $data.adelsTitelAccepted && $data.providePortrait !== false}
		<section transition:slide class="portrait-frame" class:loaded={!!$data.portraitUrl}>
			{#if $data.providePortrait === undefined}
				<TextSplit
					content="Sollten unsere begabten Künstler ein majestätisches Porträt von Euch anfertigen?"
				/>
				<div>
					<button
						on:click={() => {
							$data.providePortrait = true;
						}}>ja</button
					>
					<button
						on:click={() => {
							$data.providePortrait = true;
						}}>false</button
					>
				</div>
			{/if}

			{#if $data.providePortrait && !loadingPortrait && !$data.portraitUrl}
				<p>
					Wir werden {$data.adelsTitel || $data.name} mit
					<select placeholder="Typ" bind:value={$data.portraitSkinColor}>
						<option value="very light">sehr heller</option>
						<option value="light">heller</option>
						<option value="medium">medium</option>
						<option value="dark">dunkler</option>
						<option value="very dark">sehr dunkler</option>
					</select>
					Haut und
					<select placeholder="Typ" bind:value={$data.portraitHairType}>
						<option value="straight">glatten</option>
						<option value="curly">lockigen</option>
						<option value="wavy">welligen</option>
					</select>
					<select placeholder="Länge" bind:value={$data.portraitHairLength}>
						<option value="long">langen</option>
						<option value="medium">medium-langen</option>
						<option value="short">kurzen</option>
					</select>,
					<select placeholder="Farbe" bind:value={$data.portraitHairColor}>
						<option value="red">roten</option>
						<option value="black">schwarzen</option>
						<option value="blond">blonden</option>
						<option value="brown">braunen</option>
					</select> Haaren zeichnen
				</p>
				<button on:click={() => fetchPortrait()}> porträt malen (~15 Sekunden)</button>
			{:else if loadingPortrait}
				<div style="display: flex; gap: 20px; align-items: center;">
					<Loader />
					<p>Euer edles Antlitz wird gemalt</p>
				</div>
			{:else if $data.portraitUrl}
				<div in:slide={{ duration: 2000 }} class="portrait">
					<ImageFrame src={$data.portraitUrl} alt="portrait" />

					{#if !$data.portraitAccepted}
						<button
							on:click={() => {
								$data.portraitAccepted = true;
							}}>Porträt annehmen</button
						>
						<button
							on:click={() => {
								$data.portraitUrl = undefined;
							}}>Neues Porträt anfordern</button
						>
					{/if}
				</div>
			{/if}
		</section>
	{/if}

	{#if $data.portraitAccepted}
		{#if isSubmitting}
			<section in:slide style="border: none;">
				<div style="display: flex; gap: 20px; align-items: center;">
					<Loader />
					<p>Einladung wird abgeschickt</p>
				</div>
			</section>
		{:else}
			<div class="button-wrapper">
				<Button on:click={() => submit()}>Einladung versenden</Button>
			</div>
		{/if}
	{/if}
</div>

<style>
	.button-wrapper {
		display: flex;
		justify-content: center;
		padding-block: 20px;
		margin: 0 auto;
		width: 99%;
		max-width: 500px;
		padding-block: 50px;
		font-size: 2em;
		margin-bottom: 200px;
	}

	p.error {
		background: red;
		color: white;
		padding: 9px;
		border-radius: 5px;
		font-size: 0.5em;
		font-weight: 200;
		font-family: sans-serif;
	}

	p.hint {
		font-size: 0.6em;
		font-family: sans-serif;
		font-weight: 200;
		opacity: 0.6;
	}

	.portrait-frame.loaded {
		margin-top: 100px;
		border: none;
	}

	button {
		border: none;
		border-radius: 2px;
		padding: 5px 9px;
		margin-right: 10px;
		background: #866831;
		color: black;
		cursor: pointer;
	}

	button:disabled {
		opacity: 0.4;
		pointer-events: none;
		user-select: none;
	}

	.wrapper {
		display: flex;
		flex-direction: column;
		gap: 50px;
		padding-bottom: 200px;
	}
	.portrait {
		width: 100%;
	}
	input[type='text'] {
		font-family: 'Parisienne', cursive;
		background: transparent;
		border: none;
		color: white;
		width: 100%;
		font-size: 1em;
		margin: 0 auto;
		border-bottom: 1px solid white;
		box-sizing: border-box;
	}
	input[type='text']::after {
		content: '';
		background: white;
		height: 1px;
		width: 100%;
	}

	select {
		background: transparent;
		color: white;
		border: none;
		padding: 5px;
		border-bottom: 1px solid white;
	}

	select > option {
		color: black;
	}
	section {
		color: white;
		font-family: 'Parisienne', cursive;
		max-width: 500px;
		padding: 20px;
		margin: 0 auto;
		font-size: 2em;
		width: 70%;
		border-width: 30px;
		border-style: solid;
		border-image: url(/border_b.svg);
		border-image-repeat: stretch;
		border-image-slice: 100%;
		border-image-slice: 24% 23%;
	}
</style>
