---
import { Image } from "astro:assets";
import type { ImageMetadata } from "astro";

import { shuffleArray } from "@lib/utils";

interface Props {
  images: Array<ImageMetadata>;
  class: string;
  altText?: string | ((index: number) => string);
  interval?: number;
  backgroundColour?: string;
  backgroundOpacity?: string;
  transitionStyle?: string;
  transitionDuration?: string;
  foreground?: boolean;
  foregroundColour?: string;
  foregroundOpacity?: string;
  quality?: number;
  height?: number;
  shuffle?: boolean;
}

const {
  images,
  class: className,
  altText = null,
  interval = 5000,
  backgroundColour = "bg-black",
  backgroundOpacity = "opacity-100",
  transitionStyle = "ease-in-out",
  transitionDuration = "duration-2000",
  foreground = false,
  foregroundColour = "bg-black",
  foregroundOpacity = "opacity-50",
  quality = "80",
  height,
  shuffle = false
} = Astro.props as Props;

const IDs: string[] = [];

const imagesArray = shuffle ? shuffleArray(images) : images;
---

<div class:list={[className, "relative overflow-hidden"]}>
  <div>
    <div class:list={[backgroundColour, backgroundOpacity, "absolute inset-0"]}>
    </div>

    {
      imagesArray.map((image, index) => {
        const ID = `image-carousel-${Math.random().toString(36)}`;
        IDs.push(ID);

        return (
          <Image
            data-id={`${ID}`}
            class:list={[
              "absolute !h-full w-full object-cover object-center transition-opacity",
              transitionStyle,
              transitionDuration,
              index > 0 ? "opacity-0" : "",
              index < 2 ? "" : "hidden"
            ]}
            src={image}
            alt={
              typeof altText === "function" ? altText(index) : (altText ?? "")
            }
            loading={index < 2 ? "eager" : "lazy"}
            aria-hidden={index === 0 ? "false" : "true"}
            layout="full-width"
            fit="cover"
            quality={quality}
            height={height === undefined ? undefined : height}
          />
        );
      })
    }

    {
      foreground && (
        <div
          class:list={[foregroundColour, foregroundOpacity, "absolute inset-0"]}
        />
      )
    }
  </div>
  <slot />
</div>

<script define:vars={{ imagesArray, interval, IDs }}>
  let currentIndex = 0;

  setInterval(() => {
    const total = imagesArray.length;
    const current = document.querySelectorAll(
      `[data-id="${IDs[currentIndex]}"]`
    )[0];
    const nextIndex = (currentIndex + 1) % total;
    const next = document.querySelectorAll(`[data-id="${IDs[nextIndex]}"]`)[0];

    if (!current || !next) return;

    // Fade out current, fade in next
    current.classList.add("opacity-0");
    current.setAttribute("aria-hidden", "true");

    next.classList.remove("opacity-0", "hidden");
    next.setAttribute("aria-hidden", "false");

    const preloadIndex = (nextIndex + 1) % total;
    const preloadImage = document.querySelectorAll(
      `[data-id="${IDs[preloadIndex]}"]`
    )[0];
    if (preloadImage) {
      preloadImage.classList.add("opacity-0");
      preloadImage.classList.remove("hidden");
      preloadImage.setAttribute("aria-hidden", "true");
    }

    currentIndex = nextIndex;
  }, interval);
</script>
