<!-- This Source Code Form is subject to the terms of the Mozilla Public
   - License, v. 2.0. If a copy of the MPL was not distributed with this
   - file, You can obtain one at https://mozilla.org/MPL/2.0/. -->

<script lang="ts">
	import { createForm } from 'felte';
	import EntryKind from '../../dashboard/utils/EntryKind.svelte';
	import {
		FEELINGS,
		TITLED_ENTRIES,
		type AlbumEntry,
		type IdlessEntry,
		type KnownFeeling,
		type SongEntry
	} from '$lib/entry';
	import { FontAwesomeIcon } from '@fortawesome/svelte-fontawesome';
	import { faSpotify, faYoutube } from '@fortawesome/free-brands-svg-icons';
	import { faChevronDown, faLink, faPlus, faXmark } from '@fortawesome/free-solid-svg-icons';
	import FeelingPill from '../../dashboard/utils/FeelingPill.svelte';
	import { addEntry, uploadAsset } from '$lib/api';
	import { credentials, session_key } from '$lib/stores';
	import FeelingsChooser from '$lib/components/FeelingsChooser.svelte';

	credentials.subscribe(
		(v) => v == null && setTimeout(() => (window.location.pathname = '/auth/login'), 200)
	);

	let kind: EntryKind | null;
	const { form, errors } = createForm({
		onSubmit: async (values) => {
			let feelings = Object.keys(values)
				.filter((v) => v.startsWith('feeling__'))
				.map((v) => v.replaceAll('feeling__', '')) as KnownFeeling[];

			let base;
			if (values.kind === 'song' || values.kind === 'album') {
				base = {
					kind: values.kind,
					artist: values.artist,
					title: values.musicTitle,
					link: [values.spotify, values.yt, values.otherProvider].filter(
						(v) => v != null && v.length > 0
					),
					// FIXME: Infer Universal IDs (Spotify URL, etc)
					id: []
				};
			} else if (values.kind === 'environment') {
				base = {
					kind: values.kind,
					location:
						values.location != null && values.location.length > 0 ? values.location : undefined
				};
			} else if (values.kind === 'date') {
				base = {
					kind: values.kind,
					referencedDate: values.date
				};
			} else {
				base = {
					kind: values.kind
				};
			}

			let asset_id;
			if (values.asset != null && typeof values.asset === 'object') {
				asset_id = await uploadAsset($session_key!, values.asset);
			}

			let entry: IdlessEntry = {
				base,
				creationDate: new Date().toISOString(),
				assets: [asset_id].filter((v) => v != null) as string[],
				feelings,
				title: TITLED_ENTRIES.includes(values.kind) ? values.title : undefined,
				description: values.description
			};

			await addEntry($credentials!, entry);
			window.location.pathname = '/dashboard';
		},
		validate: (values) => {
			let errors = {};

			if (values.kind == null || values.kind.length === 0) {
				errors['kind'] = 'Must choose an entry kind';
				return errors;
			}

			if (values.kind === 'song' || values.kind === 'album') {
				if (values.artist == null || values.artist.length === 0) {
					errors['artist'] = 'Must not be empty';
				}

				if (values.musicTitle == null || values.musicTitle.length === 0) {
					errors['musicTitle'] = 'Must not be empty';
				}

				if (
					values.spotify.length === 0 &&
					values.yt.length === 0 &&
					values.otherProvider.length === 0 &&
					(values.asset == null || typeof values.asset !== 'object')
				) {
					errors['links'] = 'You must add at least one link or upload an audio asset';
				}
			} else if (values.kind === 'date') {
				if (values.date == null || values.date.length === 0) {
					errors['date'] = 'Must choose a date';
				}
			} else if (values.kind === 'feeling') {
				if (Object.keys(values).filter((v) => v.startsWith('feeling__')).length === 0) {
					errors['feelings'] = 'Must choose at least one feeling';
				}
			} else {
				if (values.title == null || values.title.length === 0) {
					errors['title'] = 'Must not be empty';
				}
			}

			return errors;
		}
	});
</script>

<div class="mt-3.5 flex justify-center">
	<div class="flex w-[60%] flex-col">
		<h1 class="pb-3.5 text-2xl">Add an entry</h1>
		<form use:form>
			<div class="mb-5">
				<label for="add-entry__kind" class="mb-2 block text-sm font-medium text-gray-900">
					Entry kind
				</label>
				<select
					bind:value={kind}
					id="add-entry__kind"
					name="kind"
					class="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-violet-500 focus:ring-violet-500"
				>
					<option value="" selected>Choose an entry kind</option>
					<option value="song">Song</option>
					<option value="album">Album</option>
					<option value="event">Event</option>
					<option value="memory">Memory</option>
					<option value="feeling">Feeling</option>
					<option value="environment">Environment</option>
					<option value="date">Date</option>
				</select>
				{#if $errors.kind != null}
					<p class="mt-2 text-sm text-red-600">
						<span class="font-medium">{$errors.kind[0]}</span>
					</p>
				{/if}
			</div>
			{#if TITLED_ENTRIES.includes(kind)}
				<div class="mb-5">
					<label for="add-entry__title" class="mb-2 block text-sm font-medium text-gray-900">
						Title
					</label>
					<input
						id="add-entry__title"
						type="text"
						name="title"
						placeholder="At the sunflower field with my friends"
						class="text-greay-900 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm focus:border-violet-500 focus:ring-violet-500"
					/>
					{#if $errors.title != null}
						<p class="mt-2 text-sm text-red-600">
							<span class="font-medium">{$errors.title[0]}</span>
						</p>
					{/if}
				</div>
			{/if}

			{#if ['song', 'album'].includes(kind)}
				<div class="mb-5 flex flex-col gap-5 md:flex-row">
					<div class="w-full">
						<label for="add-entry__artist" class="mb-2 block text-sm font-medium text-gray-900">
							Artist name
						</label>
						<input
							id="add-entry__artist"
							type="text"
							name="artist"
							placeholder="Claude Debussy"
							class="text-greay-900 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm focus:border-violet-500 focus:ring-violet-500"
						/>
						{#if $errors.artist != null}
							<p class="mt-2 text-sm text-red-600">
								<span class="font-medium">{$errors.artist[0]}</span>
							</p>
						{/if}
					</div>
					<div class="w-full">
						<label
							for="add-entry__music-title"
							class="mb-2 block text-sm font-medium text-gray-900"
						>
							<span class="capitalize">{kind}</span>
							title
						</label>
						<input
							id="add-entry__music-title"
							type="text"
							name="musicTitle"
							placeholder="Clair de Lune"
							class="text-greay-900 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm focus:border-violet-500 focus:ring-violet-500"
						/>
						{#if $errors.musicTitle != null}
							<p class="mt-2 text-sm text-red-600">
								<span class="font-medium">{$errors.musicTitle[0]}</span>
							</p>
						{/if}
					</div>
				</div>
				<div class="mb-5">
					<label for="add-entry__spotify" class="mb-2 block text-sm font-medium text-gray-900">
						Spotify link
					</label>
					<div class="flex">
						<span
							class="rounded-e-0 inline-flex items-center rounded-s-md border border-e-0 border-gray-300 bg-gray-200 px-2.5 text-sm text-gray-900"
						>
							<FontAwesomeIcon size="lg" icon={faSpotify} />
						</span>
						<input
							type="text"
							id="add-entry__spotify"
							name="spotify"
							class="block w-full min-w-0 flex-1 rounded-none rounded-e-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-violet-500 focus:ring-violet-500"
							placeholder={kind === 'song'
								? 'https://open.spotify.com/track/...'
								: 'https://open.spotify.com/album/...'}
						/>
					</div>
				</div>
				<div class="mb-5">
					<label for="add-entry__yt" class="mb-2 block text-sm font-medium text-gray-900">
						YouTube link
					</label>
					<div class="flex">
						<span
							class="rounded-e-0 inline-flex items-center rounded-s-md border border-e-0 border-gray-300 bg-gray-200 px-2.5 text-sm text-gray-900"
						>
							<FontAwesomeIcon size="lg" icon={faYoutube} />
						</span>
						<input
							type="text"
							id="add-entry__yt"
							name="yt"
							class="block w-full min-w-0 flex-1 rounded-none rounded-e-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-violet-500 focus:ring-violet-500"
							placeholder="https://www.youtube.com/watch..."
						/>
					</div>
				</div>
				<div class="mb-5">
					<label for="add-entry__other" class="mb-2 block text-sm font-medium text-gray-900">
						Link to other provider
					</label>
					<div class="flex">
						<span
							class="rounded-e-0 inline-flex items-center rounded-s-md border border-e-0 border-gray-300 bg-gray-200 px-2.5 text-sm text-gray-900"
						>
							<FontAwesomeIcon size="lg" icon={faLink} />
						</span>
						<input
							type="text"
							name="otherProvider"
							id="add-entry__other"
							class="block w-full min-w-0 flex-1 rounded-none rounded-e-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-violet-500 focus:ring-violet-500"
							placeholder="https://www.music.tld/play/..."
						/>
					</div>
				</div>
				{#if $errors.links != null}
					<p class="mb-3.5 mt-2.5 text-sm text-red-600">
						<span class="font-medium">{$errors.links[0]}</span>
					</p>
				{/if}
			{:else if kind === 'environment'}
				<div class="mb-5 w-full">
					<label for="add-entry__location" class="mb-2 block text-sm font-medium text-gray-900">
						Location
					</label>
					<input
						id="add-entry__location"
						type="text"
						name="location"
						placeholder="South of Almond Park"
						class="text-greay-900 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm focus:border-violet-500 focus:ring-violet-500"
					/>
				</div>
			{:else if kind === 'date'}
				<div class="mb-5 w-full">
					<label for="add-entry__date" class="mb-2 block text-sm font-medium text-gray-900">
						Referenced date
					</label>
					<input
						id="add-entry__date"
						type="date"
						name="date"
						class="text-greay-900 block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm focus:border-violet-500 focus:ring-violet-500"
					/>
					{#if $errors.date != null}
						<p class="mt-2 text-sm text-red-600">
							<span class="font-medium">{$errors.date[0]}</span>
						</p>
					{/if}
				</div>
			{/if}

			{#if kind != null && kind.length > 0}
				<div class="mb-5">
					<label for="add-entry__description" class="mb-2 block text-sm font-medium text-gray-900">
						Description
					</label>
					<textarea
						name="description"
						id="add-entry__description"
						rows="7"
						class="block w-full rounded-lg border border-gray-300 bg-gray-50 p-2.5 text-sm text-gray-900 focus:border-violet-500 focus:ring-violet-500"
						placeholder="Write your thoughts here..."
					></textarea>
				</div>

				<div class="mb-5">
					<label for="add-entry__assets" class="mb-2 block text-sm font-medium text-gray-900">
						Linked assets (max 5MB)
					</label>
					<input
						name="asset"
						id="add-entry__assets"
						class="block w-full rounded-lg border border-gray-300 bg-gray-50 text-sm text-gray-900 file:me-4 file:border-0 file:border-gray-300 file:bg-gray-200 file:px-4 file:py-2.5 hover:cursor-pointer hover:file:bg-gray-300 focus:border-violet-500 focus:ring-violet-500"
						type="file"
					/>
				</div>

				<div class="mb-5">
					<FeelingsChooser required={kind === 'feeling'} />
					{#if $errors.feelings != null}
						<p class="mt-1.5 text-sm text-red-600">
							<span class="font-medium">{$errors.feelings[0]}</span>
						</p>
					{/if}
				</div>

				<button
					class="focust:outline-none mt-2 rounded-lg bg-violet-700 px-5 py-2.5 text-center font-medium text-white hover:bg-violet-800 focus:ring-4 focus:ring-violet-300"
					type="submit"
				>
					Add new entry
				</button>
			{/if}
		</form>
	</div>
</div>
