<script lang="ts">
  import { fade } from 'svelte/transition';
  import { cubicInOut } from 'svelte/easing';
  import { fetchEntries, formatter } from '../util';

  let entriesPromise = $state(fetchEntries());

  let interval: Parameters<typeof clearInterval>[0] = undefined;

  let y = $state(0);
  let scrolled = $derived(y > 32);

  $effect(() => {
    clearInterval(interval);

    // Pooling interval to fetch entries every 31 seconds
    let fetching = false;
    interval = setInterval(async () => {
      if (fetching) return;
      fetching = true;
      try {
        const promise = fetchEntries();
        // wait for the promise to resolve before assigning to prevent flash
        await promise;
        entriesPromise = promise;
      } catch (error) {
        console.error('Error fetching entries:', error);
      } finally {
        fetching = false;
      }
    }, 1000 * 31);

    return () => clearInterval(interval);
  });
</script>

<svelte:window bind:scrollY={y} />

<div class="relative col-[content] pr-0.5">
  {#await entriesPromise}
    <p class="text-center">Loading entries...</p>
  {:then entries}
    {#if entries.length === 0}
      <p class="text-center">No entries.</p>
    {:else}
      {@render table(entries)}
    {/if}
  {:catch error}
    <p class="mx-auto max-w-md text-center">
      Something went wrong fetching entries: {error.message}
    </p>
  {/await}
</div>

{#snippet table(entries: Awaited<ReturnType<typeof fetchEntries>>)}
  <div
    class="@container grid w-full grid-cols-[auto,1fr,auto,auto,auto] gap-1 font-light @lg:gap-3"
  >
    <div
      class="sticky top-(--header-height) col-span-5 grid grid-cols-[subgrid] gap-1 bg-gray-950 py-2 text-gray-400 capitalize"
    >
      <div>id</div>
      <div class="px-1">name</div>
      <div class="hidden px-1 @3xl:block">done</div>
      <div class="hidden px-1 @5xl:block">created</div>
      <div class="hidden px-1 @xl:block">updated</div>

      {#if scrolled}
        <div
          transition:fade={{ duration: 250, easing: cubicInOut }}
          class="absolute inset-x-0 top-full h-16 bg-gradient-to-b from-gray-950 to-transparent"
        ></div>
      {/if}
    </div>
    {#each entries as entry (entry.id)}
      <div class="col-span-5 grid grid-cols-[subgrid] gap-1">
        <div class="py-2 text-xs text-gray-400/50">{entry.id}</div>
        <a
          href={entry.href}
          class="line-clamp-1 block px-2 py-1 text-nowrap text-ellipsis text-gray-200 capitalize transition-colors hover:text-pink-600 hover:underline"
          target="_blank"
          title={entry.name}
          referrerpolicy="no-referrer">{entry.name}</a
        >
        {@render done(entry.finished)}
        <div class="hidden max-w-24 px-1 py-1 text-xs text-gray-200 @5xl:block">
          {formatter.format(entry.created_at)}
        </div>
        <div class="hidden max-w-24 px-1 py-1 text-xs text-gray-200 @xl:block">
          {formatter.format(entry.updated_at)}
        </div>
      </div>
    {/each}
  </div>
  <div class="sticky inset-x-0 bottom-0 h-16 bg-gradient-to-t from-gray-950 to-transparent"></div>
{/snippet}

{#snippet done(finished: boolean)}
  {#if finished}
    <svg
      class="hidden text-green-500 @3xl:block"
      xmlns="http://www.w3.org/2000/svg"
      width="24"
      height="24"
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      stroke-width="2"
      stroke-linecap="round"
      stroke-linejoin="round"><path d="M20 6 9 17l-5-5" /></svg
    >
  {:else}
    <svg
      class="hidden text-red-500 @3xl:block"
      xmlns="http://www.w3.org/2000/svg"
      width="24"
      height="24"
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      stroke-width="2"
      stroke-linecap="round"
      stroke-linejoin="round"><path d="M18 6 6 18" /><path d="m6 6 12 12" /></svg
    >
  {/if}
{/snippet}
