<script lang="ts">
	import { groupByStamps, sortBy } from '$lib/stores.svelte';
	import Icon from '@iconify/svelte';
	import NostrIdentifier from './NostrIdentifier.svelte';
	import { getReadableDate, getReadableTime, moveMessageToFolder } from '$lib/utils.svelte.js';
	import Dialog from './Dialog.svelte';
	import Select from './Select.svelte';
	import type { Letter } from '$lib/letter';
	import { slide } from 'svelte/transition';
	import IconButton from './IconButton.svelte';

	let {
		letters,
		foldersList = $bindable<{ id: string; name: string; icon: string }[]>(),
		folder = $bindable<{ id: string; name: string; icon: string }>()
	} = $props();

	function formatRange(start, end) {
		if (start === 0) return '0';
		if (end === Infinity) return `${start}+`;
		return `${start}-${end}`;
	}

	let sortedInbox = $derived(
		letters.toSorted((a, b) => {
			switch ($sortBy) {
				case 'stamps':
					return b.stamps - a.stamps;
				case 'sender':
					return a.from.localeCompare(b.from);
				case 'subject':
					return a.subject.localeCompare(b.subject);
				case 'date':
					return b.date - a.date;
			}
			return 0;
		})
	);

	let groupedInbox = $derived.by(() => {
		const maxStamps = Math.max(...sortedInbox.map(letter => letter.stamps));
		const ranges = [
			10000,
			1000,
			210,
			100,
			42,
			21,
			10,
			0
		];

		if (!ranges.includes(maxStamps)) {
			ranges.push(maxStamps);
			ranges.sort((a, b) => b - a);
		}

		const groups = {};

		for (let i = 0; i < ranges.length; i++) {
			const start = ranges[i];
			const end = ranges[i + 1] || Infinity;
			const rangeKey = formatRange(start, end);
			groups[rangeKey] = [];
		}

		sortedInbox.forEach(letter => {
			for (let i = 0; i < ranges.length; i++) {
				const start = ranges[i];
				const end = ranges[i + 1] || Infinity;

				if (letter.stamps >= start && letter.stamps < end) {
					const rangeKey = formatRange(start, end);
					groups[rangeKey].push(letter);
					break;
				}
			}
		});

		return Object.entries(groups)
			.filter(([_, letters]) => letters.length > 0)
			.reverse();
	});

	let selectedLetters = $state<string[]>([]);
	let moveFolderDialogOpen = $state(false);
	let moveFolderName = $state('');

	function clickedLetter(letter: Letter) {
		if (selectedLetters.includes(letter.id))
			selectedLetters = selectedLetters.filter(id => id !== letter.id);
		else
			selectedLetters = [...selectedLetters, letter.id];
	}

	async function doMove() {
		if (!moveFolderName) return alert('Please select a folder');
		if (selectedLetters.length === 0) return alert('Please select at least one letter');
		const events = [];
		for (let letter of selectedLetters)
			events.push(await moveMessageToFolder(
				letter,
				moveFolderName
			));
		for (let event of events)
			await event.publish();
		selectedLetters = [];
		moveFolderName = '';
		moveFolderDialogOpen = false;
		window.location.reload();
	}
</script>

{#snippet letterGroup(letters)}
	<div class="letter-group">
		{#each letters as letter}
			{#key letter.id}
				<a in:slide out:slide class="letter-item" href="/letters/{letter.id}">
					<div class="subject-line">
						<div class="letter-subject">
							{#if !letter.emailAddress}
								<img src="/nostr-lock.svg" width="32" />
							{/if}
							{letter.subject}
						</div>
						{#if letter.stamps}
							<div class="stamps-count">
								<Icon icon="emojione-v1:stamped-envelope" />
								{letter.stamps} sats
							</div>
						{/if}
					</div>
					<div class="letter-from">
						{#if folder.id === 'sent'}
							{#each letter.recipients as recipient}
								<NostrIdentifier user={recipient.npub} />
							{/each}
						{:else}
							<NostrIdentifier user={letter.from.npub} emailAddress={letter.emailAddress} />
						{/if}
					</div>
					<div class="letter-meta">
						<Icon icon="mdi:calendar" />
						{getReadableDate(letter.date)}
						&nbsp;
						<Icon icon="mdi:clock-outline" />
						{getReadableTime(letter.date)}
					</div>
					<div class="letter-preview">{letter.preview}</div>
				</a>
			{/key}
		{/each}
	</div>
{/snippet}

<Dialog
	bind:open={moveFolderDialogOpen}
>
	<div class="title">
		<h3>Move Letters to Folder</h3>
	</div>
	<p class="text-secondary">Select a folder to move the selected letters to:</p>

	<Select bind:value={moveFolderName} label="Select folder" options={
		foldersList.filter(cf => cf.id !== folder.id && cf.id != 'sent').map(folder => ({ value: folder.id, label: folder.name }))
	} />

	<h4>Letters ({selectedLetters.length} selected)</h4>

	<div class="letter-list">
		<div class="letter-group">
			{#each letters as letter}
				{#key letter.id}
					<div class="letter-item"
							 onclick={() => clickedLetter(letter)}
							 class:selected={selectedLetters.includes(letter.id)}
					>
						<div class="subject-line">
							<div class="letter-subject">
								<Icon icon="mdi:letter-outline" /> {letter.subject}
							</div>
							{#if letter.stamps}
								<div class="stamps-count">
									<Icon icon="emojione-v1:stamped-envelope" />
									{letter.stamps} sats
								</div>
							{/if}
						</div>
						<div class="letter-from">
							<NostrIdentifier user={letter.from.npub} emailAddress={letter.emailAddress} />
						</div>
					</div>
				{/key}
			{/each}
		</div>
	</div>

	<div class="button-group">
		<button onclick={() => moveFolderDialogOpen = false} type="button">Cancel</button>
		<button onclick={doMove} type="submit">OK</button>
	</div>
</Dialog>

<h2 id="page-title">
	{folder.name}
</h2>

<div class="actions">
	<IconButton icon="mdi:folder-move-outline" onclick={() => moveFolderDialogOpen = true} text="Move Letters" />
</div>

<main class="letter-list">
	{#if $groupByStamps}
		{#each groupedInbox as [range, letters]}
			<div class="stamp-group">
				{#if range == 0}
					<h3>No stamps</h3>
				{:else}
					<h3>{range} sats stamp</h3>
				{/if}
				<div class="letter-group">
					{@render letterGroup(letters)}
				</div>
			</div>
		{/each}
	{:else}
		{@render letterGroup(sortedInbox)}
	{/if}
</main>

<style>
  @layer layout {
    .letter-list {
      display: grid;
      gap: var(--spacing-sm);
      overflow: hidden;

      .stamp-group {
        display: grid;
        gap: var(--spacing-md);
      }

      .letter-group {
        display: grid;
        gap: var(--spacing-sm);
      }

      .letter-meta {
        color: var(--text-secondary);
        font-size: 0.85rem;
        margin-bottom: var(--spacing-xs);
        display: flex;
        align-items: center;
        gap: var(--spacing-xs);
      }

      & .letter-item {
        text-decoration: none;
        color: var(--text-primary);
        position: relative;
        overflow: hidden;
        padding: var(--spacing-md);
        border-radius: 12px;
        background: color-mix(in srgb, var(--glass-bg) 80%, transparent);
        border: 1px solid var(--glass-border);
        transition: all 0.3s ease;
        cursor: pointer;

        &::before {
          content: '';
          position: absolute;
          inset: 0;
          background: var(--gradient-shine);
          background-size: 200% 200%;
          opacity: 0;
          transition: opacity 0.3s ease;
        }

        &:hover, &.selected {
          transform: translateY(-2px) scale(1.01);
          background: color-mix(in srgb, var(--glass-bg) 90%, var(--accent));
          box-shadow: 0 4px 16px var(--glass-shadow);

          &::before {
            opacity: 1;
            animation: shine 2s linear infinite;
          }
        }

        & .subject-line {
          display: flex;
          justify-content: space-between;
          align-items: center;
          margin-bottom: var(--spacing-xs);
        }

        & .letter-subject, .letter-from {
          display: flex;
          flex-wrap: wrap;
          flex-direction: row;
          align-content: center;
          align-items: center;
          font-weight: 600;
        }

        & .stamps-count {
          color: var(--text-secondary);
          font-size: 0.85rem;
          display: flex;
          align-items: center;
          gap: var(--spacing-xs);
        }

        & .letter-preview {
          color: var(--text-secondary);
          font-size: 0.9rem;
        }
      }
    }

    .actions {
      display: flex;
      align-items: center;
      gap: var(--spacing-sm);
      margin-bottom: var(--spacing-sm);
    }
  }
</style>
