<script lang="ts">
	import { ndk } from '$lib/stores.svelte';
	import Icon from '@iconify/svelte';
	import MailboxFolderItems from '../components/MailboxFolderItems.svelte';
	import { createFolder, decryptSealedMessageIntoReadableType } from '$lib/utils.svelte';
	import { Letter } from '$lib/letter';
	import Dialog from '../components/Dialog.svelte';
	import { FolderLabel } from '$lib/folderLabel';
	import type { NDKEventId } from '@nostr-dev-kit/ndk';
	import { LetterToFolderMapping } from '$lib/letterToFolderMapping';

	let sidebarOpen = $state(false);

	let messages = $ndk.storeSubscribe([{
		kinds: [1059],
		'#p': [$ndk.activeUser.pubkey]
	}], {
		closeOnEose: false,
		groupable: false,
		groupableDelay: 0
	});

	let letters = $state<Letter[]>([]);
	let activeFolder = $state('inbox');

	let folders = $state([
		{ id: 'inbox', name: 'Inbox', icon: 'solar:inbox-bold-duotone' },
		{ id: 'sent', name: 'Sent', icon: 'fa:send' },
		{ id: 'trash', name: 'Trash', icon: 'eos-icons:trash' }
	]);

	async function decryptMessages(messages) {
		const currentMessages = messages;
		const decryptedFolders = [
			{ id: 'inbox', name: 'Inbox', icon: 'solar:inbox-bold-duotone' },
			{ id: 'sent', name: 'Sent', icon: 'fa:send' },
			{ id: 'trash', name: 'Trash', icon: 'formkit:trash' }
		];
		const allLetters = [];
		let allLettersInFolders: NDKEventId[] = [];
		const letterLabels = new Map<string, NDKEventId[]>();
		for (const message of currentMessages) {
			const msg = await decryptSealedMessageIntoReadableType(message);
			if ((msg instanceof Letter)) {
				allLetters.push(msg);
			} else if (msg instanceof FolderLabel) {
				decryptedFolders.push(msg);
			} else if (msg instanceof LetterToFolderMapping) {
				if (!letterLabels.has(msg.folder))
					letterLabels.set(msg.folder, []);
				for (const folderId of letterLabels.keys()) {
					// check if letter is in a folder, if so remove it and move it to the new folder
					if (letterLabels.get(folderId)!.includes(msg.message)) {
						letterLabels.get(folderId)!.splice(letterLabels.get(folderId)!.indexOf(msg.message), 1);
						break;
					}
				}
				allLettersInFolders.push(msg.message);
				letterLabels.set(msg.folder, letterLabels.get(msg.folder)!.concat(msg.message));
			}
		}

		letters = allLetters.filter(letter => {
			if (activeFolder === 'sent')
				return letter.from.pubkey === $ndk.activeUser.pubkey;
			if (activeFolder === 'inbox' && letter.from.pubkey !== $ndk.activeUser.pubkey)
				return !allLettersInFolders.includes(letter.id);
			if (!letterLabels.has(activeFolder))
				return false;
			return letterLabels.get(activeFolder).includes(letter.id);
		});
		folders = decryptedFolders;
	}

	messages.subscribe(m => decryptMessages(m));

	function changeFolder(newFolder) {
		letters = [];
		activeFolder = newFolder;
		decryptMessages($messages);
	}

	async function addNewFolderPressed() {
		const newFolder = await createFolder(newFolderName, '');
		if (!newFolder) return;
		await newFolder.publish();
		folders = [...folders, { id: newFolder.id, name: newFolderName, icon: 'eos-icons:plus' }];
		newFolderName = '';
		isAddingFolder = false;
	}

	function newFolderDialogClosed() {
		isAddingFolder = false;
		newFolderName = '';
	}

	let isAddingFolder = $state(false);
	let newFolderName = $state('');
</script>

<button class="sidebar-button" onclick={() => sidebarOpen = !sidebarOpen}>
	<Icon icon="mynaui:sidebar-solid" />
</button>

<Dialog
	bind:open={isAddingFolder}
	onClose={newFolderDialogClosed}
>
	<div class="title">
		<h3>Create Folder</h3>
	</div>
	<p class="text-secondary">Please enter a name for the new folder:</p>

	<form onsubmit={addNewFolderPressed}>
		<input
			autofocus
			bind:value={newFolderName}
			placeholder="Folder name"
			type="text"
		/>

		<div class="button-group">
			<button onclick={newFolderDialogClosed} type="button">Cancel</button>
			<button type="submit">OK</button>
		</div>
	</form>
</Dialog>

<div class="content">
	<div class="sidebar-container" class:open={sidebarOpen}>
		<div class="glass sidebar">
			{#each folders as folder}
				<button class="folder-item" onclick={() => changeFolder(folder.id)}>
					<Icon icon={folder.icon} />
					{folder.name}
				</button>
			{/each}
			<hr />
			<button class="folder-item" onclick={() => isAddingFolder = true}>
				<Icon icon="eos-icons:plus" />
				Add Folder
			</button>
		</div>
	</div>

	<div class="folder-view">
		{#if letters.length === 0}
			<Icon icon="eos-icons:loading" width="5em" />
			<br />
			<p>
				If you have letters, they will appear here, please wait...
			</p>
		{:else}
			<MailboxFolderItems foldersList={folders} folder={folders.find(f => f.id === activeFolder)} {letters} />
		{/if}
	</div>
</div>

<style>
  .folder-item {
    display: flex;
    align-items: center;
    gap: var(--spacing-sm);
  }

  .sidebar-button {
    position: absolute;
    top: 0;
    right: 0;
  }

  .content {
    display: flex;
    gap: var(--spacing-sm);
  }

  .sidebar-container {
    width: 0;
    overflow: hidden;
    transition: width 0.3s ease-in-out;

    &.open {
      width: clamp(16rem, 20vw, 20rem);
    }
  }

  .folder-view {
    flex-grow: 1;
  }

  .sidebar {
    display: flex;
    gap: var(--spacing-sm);
    flex-direction: column;
    height: 100%;
  }
</style>