<script lang="ts">
import { onMount } from "svelte";
import type { PageData } from './$types';
import type { Post } from '$lib/mastodon/response';
import { PUBLIC_REFRESH_INTERVAL, PUBLIC_MASTODON_INSTANCE_DISPLAY_NAME } from '$env/static/public';
import PostComponent from '$lib/components/PostComponent.svelte';
import LoadMoreComponent from '$lib/components/LoadMoreComponent.svelte';

export let data: PageData;

const refreshInterval = parseInt(PUBLIC_REFRESH_INTERVAL);
let interval: NodeJS.Timer | null = null;
let moreOlderPostsAvailable = true;
let loadingOlderPosts = false;

interface FetchOptions {
  since?: string,
  before?: string,
  count?: number
}

async function fetchPosts(options: FetchOptions): Promise<Post[]> {
  const params = new URLSearchParams();
  if (options?.since !== undefined) {
    params.set('since', options.since);
  }
  if (options?.before !== undefined) {
    params.set('before', options.before);
  }
  if (options?.count !== undefined) {
    params.set('count', options.count.toFixed(0));
  }

  const response = await fetch(`/api/posts?${params}`);
  return await response.json();
}

function filterDuplicates(posts: Post[]): Post[] {
  return posts.filter((obj, index, arr) => {
    return arr.map(mapObj => mapObj.url).indexOf(obj.url) === index;
  });
}

function refresh() {
  let filter: FetchOptions = {};
  if (data.posts.length > 0) {
    filter = { since: data.posts[0].created_at };
  }
  fetchPosts(filter).then(resp => {
    if (resp.length > 0) {
      // Prepend new posts, filter dupes
      // There shouldn't be any duplicates, but better be safe than sorry
      data.posts = filterDuplicates(resp.concat(data.posts));
    }
  })
  .catch(e => {
    // TODO: Show error in UI
    console.error('Error loading newest posts', e);
  });
}

onMount(async () => {
  interval = setInterval(refresh, refreshInterval);

  // - If the page is hidden, slow down refresh rate
  // - If the page is shown, bump up refresh rate
  document.addEventListener('visibilitychange', () => {
    const delay = document.hidden ? refreshInterval * 10 : refreshInterval;
    if (interval) {
      clearInterval(interval);
    }
    interval = setInterval(refresh, delay);
  });

  return () => {
    if (interval !== null) {
      clearInterval(interval)
    }
  }
});

function loadOlderPosts() {
  loadingOlderPosts = true;
  const filter: FetchOptions = { count: 20 };
  if (data.posts.length > 0) {
    filter.before = data.posts[data.posts.length - 1].created_at;
  }


  fetchPosts(filter).then(resp => {
    if (resp.length > 0) {
      // Append old posts, filter dupes
      // There shouldn't be any duplicates, but better be safe than sorry
      data.posts = filterDuplicates(data.posts.concat(resp));
      // If we got less than we expected, there are no older posts available
      moreOlderPostsAvailable = resp.length < (filter.count ?? 20);
    } else {
      moreOlderPostsAvailable = false;
    }
    loadingOlderPosts = false;
  })
  .catch(e => {
    loadingOlderPosts = false;
    // TODO: Show error in UI
    console.error('Error loading older posts', e);
  });

}

</script>
<svelte:head>
  <title>{PUBLIC_MASTODON_INSTANCE_DISPLAY_NAME} music list</title>
</svelte:head>
<h2>{PUBLIC_MASTODON_INSTANCE_DISPLAY_NAME} music list</h2>
<div class="wrapper">
  <div></div>
  <div class="posts">
  {#if data.posts.length === 0}
    Sorry, no posts recommending music aave been found yet
  {/if}
  {#each data.posts as post (post.url)}
      <div class="post"><PostComponent {post} /></div>
  {/each}
  <LoadMoreComponent
    on:loadOlderPosts={loadOlderPosts}
    moreAvailable={moreOlderPostsAvailable}
    isLoading={loadingOlderPosts}/>
  </div>
  <div></div>
  </div>
<style>
  .posts {
    display: flex;
    flex-direction: column;
    align-items: center;
  }
  .post {
    width: 100%;
    max-width: 600px;
    margin-bottom: 1em;
    border-bottom: 1px solid var(--color-border);
    padding: 1em;
  }
  .wrapper {
    display: flex;
    justify-content: space-between;
  }

  h2 {
    text-align: center;
  }
</style>