import { type CollectionEntry, getCollection } from "astro:content";
import type { ImageMetadata } from "astro";

export type AnyLink = CollectionEntry<"links_json">;

export async function getLinks(): Promise<AnyLink[]> {
  const links = await getCollection("links_json");
  return links.sort(
    (a, b) => b.data.publishDate.valueOf() - a.data.publishDate.valueOf(),
  );
}

export type PhotoSidecar = {
  id: string;
  title: string[];
  alt: string;
  location: string;
  date: string;
  tags: string[];
  exif: {
    camera: string;
    lens: string;
    aperture: string;
    iso: string;
    focal_length: string;
    shutter_speed: string;
  };
};

export type LoadedPhoto = {
  sidecar: PhotoSidecar;
  image: ImageMetadata;
};

export type Breadcrumb = {
  label: string;
  href: string;
};

/**
 * Extract the clean slug from a collection entry id.
 * e.g. "travels/asia/chiang-mai/index.md" → "travels/asia/chiang-mai"
 *      "index.md" → ""
 */
export function collectionSlug(
  entry: CollectionEntry<"collections_photos">,
): string {
  return entry.id.replace(/\/index\.mdx?$/, "").replace(/^index\.mdx?$/, "");
}

/**
 * Load and sort photos from a specific collection's img/ directory.
 * Only loads photos directly in `collections/<slug>/img/` (not recursive).
 */
export function buildCollectionPhotos(
  sidecars: Record<string, PhotoSidecar>,
  imageModules: Record<string, { default: ImageMetadata }>,
  slug: string,
): LoadedPhoto[] {
  const prefix = slug
    ? `/src/content/photos/collections/${slug}/img/`
    : "/src/content/photos/collections/img/";

  return Object.entries(sidecars)
    .filter(([p]) => {
      // Must be in exactly this collection's img/ dir (no deeper nesting)
      if (!p.startsWith(prefix)) return false;
      const remainder = p.slice(prefix.length);
      return !remainder.includes("/");
    })
    .map(([jsonPath, sidecar]) => {
      const imgPath = jsonPath.replace(/\.json$/, ".jpg");
      const image = imageModules[imgPath]?.default;
      if (!image) return null;
      return { sidecar, image };
    })
    .filter((p): p is LoadedPhoto => p !== null)
    .sort(
      (a, b) =>
        new Date(a.sidecar.date).getTime() - new Date(b.sidecar.date).getTime(),
    );
}

/**
 * Build breadcrumb trail from root to the given slug.
 * e.g. slug "travels/asia/chiang-mai" → [
 *   { label: "Collections", href: "/photos/collections" },
 *   { label: "Travels",     href: "/photos/collections/travels" },
 *   { label: "Asia",        href: "/photos/collections/travels/asia" },
 *   { label: "Chiang Mai",  href: "/photos/collections/travels/asia/chiang-mai" },
 * ]
 */
export function buildBreadcrumbs(
  slug: string,
  allCollections: CollectionEntry<"collections_photos">[],
): Breadcrumb[] {
  const crumbs: Breadcrumb[] = [
    { label: "Collections", href: "/photos/collections" },
  ];

  if (!slug) return crumbs;

  const segments = slug.split("/");
  for (let i = 0; i < segments.length; i++) {
    const partialSlug = segments.slice(0, i + 1).join("/");
    const entry = allCollections.find((c) => collectionSlug(c) === partialSlug);
    crumbs.push({
      label: entry?.data.title ?? segments[i] ?? partialSlug,
      href: `/photos/collections/${partialSlug}`,
    });
  }

  return crumbs;
}

/**
 * Get immediate child collections of a given parent slug.
 */
export function getChildCollections(
  parentSlug: string,
  allCollections: CollectionEntry<"collections_photos">[],
): CollectionEntry<"collections_photos">[] {
  const depth = parentSlug ? parentSlug.split("/").length : 0;

  return allCollections
    .filter((c) => {
      const cs = collectionSlug(c);
      if (!cs) return false;
      if (parentSlug && !cs.startsWith(`${parentSlug}/`)) return false;
      if (!parentSlug && cs.includes("/")) return false;
      return cs.split("/").length === depth + 1;
    })
    .sort(
      (a, b) =>
        a.data.order - b.data.order || a.data.title.localeCompare(b.data.title),
    );
}
