<script>
  import { page } from '$app/state';
  import { goto } from '$app/navigation';
  import { browser } from '$app/environment';
  import { getContext, onDestroy, onMount } from 'svelte';
  import TinyGesture from 'tinygesture';

  import { boot, subscribeToEvents } from '$lib/apiServer';
  import { channelsList, currentUser, logins, messages, onEvent } from '$lib/store';

  import ChannelList from '$lib/components/ChannelList.svelte';
  import CreateChannelForm from '$lib/components/CreateChannelForm.svelte';

  let events = null;
  let gesture = null;

  let pageContext = getContext('page');
  let { children } = $props();
  let loading = $state(true);
  let channel = $derived(page.params.channel);

  let rawChannels = $derived($channelsList.channels);
  let rawMessages = $derived($messages);

  let enrichedChannels = $derived.by(() => {
    const channels = rawChannels;
    const messages = rawMessages;
    const enrichedChannels = [];
    if (channels && messages) {
      for (let ch of channels) {
        let runs = messages.inChannel(ch.id);
        let lastRun = runs?.slice(-1)[0];
        let lastMessage = lastRun?.messages.slice(-1)[0];
        let lastMessageAt = lastMessage?.at;
        let hasUnreads = lastMessageAt > ch.lastReadAt;
        enrichedChannels.push({
          ...ch,
          hasUnreads
        });
      }
    }
    return enrichedChannels;
  });

  function onBooted(boot) {
    currentUser.set({
      id: boot.login.id,
      username: boot.login.name
    });
    logins.update((value) => value.setLogins(boot.logins));
    channelsList.update((value) => value.setChannels(boot.channels));
    messages.update((value) => value.setMessages(boot.messages));
  }

  function setUpGestures() {
    if (!browser) {
      // Meaningless if we're not in a browser, so...
      return;
    }
    gesture = new TinyGesture(window);
    gesture.on('swiperight', (event) => {
      pageContext.showMenu = true;
    });
    gesture.on('swipeleft', (event) => {
      pageContext.showMenu = false;
    });
  }

  onMount(async () => {
    let response = await boot();
    switch (response.status) {
      case 200:
        onBooted(response.data);
        events = subscribeToEvents(response.data.resume_point);
        events.onmessage = onEvent.fromMessage;
        break;
      case 401:
        currentUser.set(null);
        await goto('/login');
        break;
      case 503:
        currentUser.set(null);
        await goto('/setup');
        break;
      default:
        // TODO: display error.
        break;
    }
    setUpGestures();

    loading = false;
  });

  onDestroy(async () => {
    if (events !== null) {
      events.close();
    }
    if (gesture !== null) {
      gesture.destroy();
    }
  });

  function onbeforeunload(event) {
    event.preventDefault();
    if (events !== null) {
      events.close();
    }
    // For some compat reasons?
    event.returnValue = '';
    return '';
  }
</script>

<svelte:window {onbeforeunload} />

<svelte:head>
  <!-- TODO: unread count? -->
  <title>pilcrow</title>
</svelte:head>

{#if loading}
  <h2>Loading&hellip;</h2>
{:else}
  <div id="interface">
    <nav id="sidebar" data-expanded={pageContext.showMenu}>
      <ChannelList active={channel} channels={enrichedChannels} />
      <div class="create-channel">
        <CreateChannelForm />
      </div>
    </nav>
    <main>
      {@render children?.()}
    </main>
  </div>
{/if}
