<script lang="ts">
  import { onMount } from "svelte";

  let slot: HTMLDivElement;
  let images: HTMLImageElement[];

  export let title: string;

  let altText: string;
  let height: number;
  let loaded = false;

  function hide(img: HTMLImageElement) {
    img.classList.remove("active");
  }

  function show(img: HTMLImageElement) {
    img.classList.add("active");
    if (img?.alt) altText = img.alt;
    else altText = "";
    height = img.getBoundingClientRect().height;
    setTimeout(() => {
      height = img.getBoundingClientRect().height;
    }, 100);
  }

  let index = 0;
  function setIndex(i: number) {
    if (i < 0) i = images.length - 1;
    if (i >= images.length) i = 0;
    hide(images[index]);
    index = i;
    show(images[index]);
  }

  $: if (slot) {
    images = Array.from(slot.querySelectorAll("img"));
    if (images?.length) {
      images.forEach(hide);
      show(images[index]);
      images[index].onload = () => {
        loaded = true;
        height = images[index].getBoundingClientRect().height;
      };
    }
    setTimeout(() => {
      loaded = true;
    }, 100);
  }
</script>

<div
  class="wrapper grid overflow-hidden rounded-xl border border-light"
  class:title
  class:loaded
  style={`--height:${height}px`}
>
  {#if title}
    <div class="flex items-center p-x-4 bg">
      <h3>{title}</h3>
    </div>
  {/if}

  <div class="images" bind:this={slot}>
    <slot />
  </div>
  <div class="p-2 flex place-content-between bg">
    <p>{index + 1}/{images?.length}</p>
    {#if altText}
      <p class="text-right">{altText}</p>
    {/if}
    <div class="overflow-hidden rounded-md bg-light gap-2 flex p-1">
      <button
        class="flex-1 i-tabler-arrow-left"
        aria-label="previous image"
        on:click={() => setIndex(index - 1)}
      />
      <button
        class="flex-1 i-tabler-arrow-right"
        aria-label="next image"
        on:click={() => setIndex(index + 1)}
      />
    </div>
  </div>
</div>

<style>
  .wrapper {
    grid-template-rows: 1fr 40px;
    transition: height 0.3s;
  }

  .wrapper :global(.image-wrapper) {
    margin: 0 !important;
  }

  .wrapper.title {
    grid-template-rows: 40px 1fr 40px;
  }

  .loaded {
    height: calc(var(--height) + 40px);
  }

  .wrapper.title.loaded {
    height: calc(var(--height) + 80px);
  }

  .images :global(img) {
    border-radius: 0px;
    display: none;
  }

  .images :global(.active) {
    position: relative;
    display: block !important;
    opacity: 1;
    transition:
      opacity 0.3s ease,
      display 0.3s 0.3s;
  }
</style>
