import { getCollection } from "astro:content";
import { join } from "node:path";
import type { APIContext, ImageMetadata } from "astro";
import {
  buildCollectionPhotos,
  collectionSlug,
  type PhotoSidecar,
} from "@/lib/collections";
import {
  buildCollectionVNode,
  buildPhotoVNode,
  imageToOgDataUri,
  renderOgImage,
} from "@/lib/og";

type CollectionPathProps = {
  type: "collection";
  title: string;
  description: string;
  location?: string;
  coverPath: string | null;
};

type PhotoPathProps = {
  type: "photo";
  title: string;
  alt: string;
  date: string;
  location: string;
  photoPath: string;
};

type PathProps = CollectionPathProps | PhotoPathProps;

export async function getStaticPaths() {
  const allCollections = await getCollection(
    "collections_photos",
    ({ data }) => !data.draft,
  );

  const sidecars = import.meta.glob<PhotoSidecar>(
    "/src/content/photos/collections/**/*.json",
    { eager: true },
  );
  const imageModules = import.meta.glob<{ default: ImageMetadata }>(
    "/src/content/photos/collections/**/*.jpg",
    { eager: true },
  );

  const paths: { params: { slug: string }; props: PathProps }[] = [];

  for (const col of allCollections) {
    const slug = collectionSlug(col);
    if (!slug) continue; // skip root collection index

    // Cover: first JPG in this collection's own img/ dir (sorted alphabetically)
    const imgPrefix = `/src/content/photos/collections/${slug}/img/`;
    const coverEntry = Object.entries(imageModules)
      .filter(
        ([p]) =>
          p.startsWith(imgPrefix) && !p.slice(imgPrefix.length).includes("/"),
      )
      .sort(([a], [b]) => a.localeCompare(b))[0];
    const coverPath = coverEntry?.[0] ?? null;

    paths.push({
      params: { slug },
      props: {
        type: "collection",
        title: col.data.title,
        description: col.data.description,
        ...(col.data.location !== undefined
          ? { location: col.data.location }
          : {}),
        coverPath,
      } satisfies CollectionPathProps,
    });

    // Individual photo paths
    const photos = buildCollectionPhotos(sidecars, imageModules, slug);
    for (const photo of photos) {
      const photoPath = `/src/content/photos/collections/${slug}/img/${photo.sidecar.id}.jpg`;
      paths.push({
        params: { slug: `${slug}/${photo.sidecar.id}` },
        props: {
          type: "photo",
          title: photo.sidecar.title[0] ?? photo.sidecar.id,
          alt: photo.sidecar.alt,
          date: photo.sidecar.date,
          location: photo.sidecar.location,
          photoPath,
        } satisfies PhotoPathProps,
      });
    }
  }

  return paths;
}

export async function GET({ props }: APIContext) {
  const typedProps = props as PathProps;
  const cwd = process.cwd();

  if (typedProps.type === "collection") {
    const coverDataUri = typedProps.coverPath
      ? await imageToOgDataUri(join(cwd, typedProps.coverPath))
      : undefined;
    const buffer = await renderOgImage(
      buildCollectionVNode({
        title: typedProps.title,
        description: typedProps.description,
        ...(typedProps.location !== undefined
          ? { location: typedProps.location }
          : {}),
        coverDataUri,
      }),
    );
    return new Response(buffer, { headers: { "Content-Type": "image/png" } });
  }

  // type === "photo"
  const photoDataUri = await imageToOgDataUri(join(cwd, typedProps.photoPath));
  const buffer = await renderOgImage(
    buildPhotoVNode({
      title: typedProps.title,
      alt: typedProps.alt,
      date: typedProps.date,
      location: typedProps.location,
      photoDataUri,
    }),
  );
  return new Response(buffer, { headers: { "Content-Type": "image/png" } });
}
