import type { ImageMetadata } from "astro";
import { getImage } from "astro:assets";

import { getCollection, type CollectionEntry } from "astro:content";
type Project = CollectionEntry<"projects">;

const tracks = await getCollection("tracks");

const allProjectOtherImages = import.meta.glob<{ default: ImageMetadata }>(
  "/src/assets/img/projects/**/*",
  { eager: true }
);

const allProjectHeros = import.meta.glob<{ default: ImageMetadata }>(
  "/src/assets/img/project-heros/*",
  { eager: true }
);

const allImages = import.meta.glob<{ default: ImageMetadata }>(
  "/**/*.{jpeg,jpg,png,gif}",
  {
    eager: true
  }
);

export function getImageByPath(path: string): ImageMetadata | null {
  for (const [imagePath, mod] of Object.entries(allImages)) {
    if (imagePath.includes(path)) {
      return mod.default;
    }
  }

  return null;
}

export function getProjectHero(project: Project): ImageMetadata {
  let image: ImageMetadata = Object.values(allProjectHeros)[0].default;
  for (const [path, mod] of Object.entries(allProjectHeros)) {
    if (path.includes(project.data.images.hero.src)) {
      image = mod.default;
    }
  }

  return image;
}

export function getProjectOtherImages(project: Project): ImageMetadata[] {
  const images: ImageMetadata[] = [];

  if (!project.data.images.other) {
    return images;
  }

  for (const [path, mod] of Object.entries(allProjectOtherImages)) {
    if (path.includes(project.data.images.other)) {
      images.push(mod.default);
    }
  }

  return images;
}

export function getAllProjectImages(project: Project): ImageMetadata[] {
  const images: ImageMetadata[] = [];

  const heroImage = getProjectHero(project);

  if (heroImage) {
    images.push(heroImage);
  }

  if (!project.data.images.other) {
    return images;
  }
  const otherImages = getProjectOtherImages(project);

  for (const otherImage of otherImages) {
    images.push(otherImage);
  }

  return images;
}

export function shuffleArray<T>(array: Array<T>): Array<T> {
  for (let i = array.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [array[i], array[j]] = [array[j], array[i]];
  }
  return array;
}

export async function convertEagerImagesImportGlobToArray(
  images: Record<
    string,
    () => Promise<{
      default: ImageMetadata;
      eager: true;
    }>
  >
) {
  return await Promise.all(
    Object.values(images).map(async (image) => (await image()).default)
  );
}

export async function convertImagesImportGlobToArray(
  images: Record<
    string,
    () => Promise<{
      default: ImageMetadata;
    }>
  >
) {
  const arrayOfPromises = await Promise.all(
    Object.values(images).map(async (image) => image())
  );

  const returnedImages: ImageMetadata[] = [];
  arrayOfPromises.forEach((image) => {
    returnedImages.push(image.default);
  });

  return returnedImages;
}

export async function getFullExternalURLOfImage(
  image: ImageMetadata
): Promise<string> {
  return new URL((await getImage({ src: image })).src, import.meta.env.SITE)
    .href;
}

export function slugify(input: string): string {
  if (!input) return "";
  let slug = input.toLowerCase().trim();
  slug = slug.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
  slug = slug.replace(/[^a-z0-9\s-]/g, " ");
  slug = slug.replace(/[\s-]+/g, "-");
  slug = slug.replace(/^-+|-+$/g, "");
  return slug;
}

export function getTrackByID(id: string): CollectionEntry<"tracks"> | null {
  for (const track of tracks) {
    if (track.id === id) {
      return track;
    }
  }

  return null;
}
