import { defineCollection, reference } from "astro:content";
import { file, glob } from "astro/loaders";
import { z } from "astro/zod";

const blog = defineCollection({
  loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/blog/posts" }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      description: z.string(),
      publishDate: z.coerce.date(),
      updatedDate: z.coerce.date().optional(),
      tags: z.array(z.string()).default([]),
      category: reference("categories").default({
        collection: "categories",
        id: "general",
      }),
      draft: z.boolean().default(false),
      seriesParent: z.string().optional(),
      seriesOrder: z.number().optional(),
      cover: image().optional(),
      coverAlt: z.string().optional(),
    }),
});

const categories = defineCollection({
  loader: glob({
    pattern: "**/*.{md,mdx}",
    base: "./src/content/blog/categories",
  }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      description: z.string(),
      order: z.number().int().default(99),
      cover: image().optional(),
      coverAlt: z.string().optional(),
    }),
});

const notes = defineCollection({
  loader: glob({ pattern: "**/*.{md,mdx}", base: "./src/content/notes" }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      publishDate: z.coerce.date(),
      description: z.string().optional(),
      cover: image().optional(),
      coverAlt: z.string().optional(),
      draft: z.boolean().default(false),
      tags: z.array(z.string()).default([]),
    }),
});

const links_json = defineCollection({
  loader: file("./src/content/links/links.json", {
    parser: (text) => {
      const entries = JSON.parse(text) as Array<Record<string, unknown>>;
      return entries.map((entry) => {
        if (!entry.id && !entry.slug) {
          const date = (
            String(entry.publishDate ?? "undated").split("T")[0] ?? "undated"
          ).replace(/-/g, "/");
          const slug = String(entry.title ?? "link")
            .toLowerCase()
            .replace(/[^a-z0-9]+/g, "-")
            .replace(/^-|-$/g, "");
          return { ...entry, id: `json/${date}/${slug}` };
        }
        return entry;
      });
    },
  }),
  schema: z.object({
    title: z.string(),
    url: z.url(),
    description: z.string().optional(),
    publishDate: z.coerce.date(),
    via: z.string().optional(),
    tags: z.array(z.string()).default([]),
    collection: z.string().optional(),
  }),
});

const projects_categories = defineCollection({
  loader: glob({
    pattern: "**/*.{md,mdx}",
    base: "./src/content/projects/categories",
  }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      description: z.string(),
      order: z.number().int().default(99),
      cover: image().optional(),
      coverAlt: z.string().optional(),
    }),
});

const projects = defineCollection({
  loader: glob({
    pattern: "**/*.{md,mdx}",
    base: "./src/content/projects/project",
  }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      description: z.string(),
      publishDate: z.coerce.date(),
      draft: z.boolean().default(false),
      url: z.url().optional(),
      github: z.url().optional(),
      tags: z.array(z.string()).default([]),
      category: reference("projects_categories").default({
        collection: "projects_categories",
        id: "general",
      }),
      cover: image().optional(),
      coverAlt: z.string().optional(),
    }),
});

const collections_photos = defineCollection({
  loader: glob({
    pattern: "**/index.{md,mdx}",
    base: "./src/content/photos/collections",
  }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    location: z.string().optional(),
    publishDate: z.coerce.date().optional(),
    draft: z.boolean().default(false),
    coverImage: z.string().optional(),
    order: z.number().int().default(0),
    set: z.boolean().default(false),
  }),
});

export const collections = {
  blog,
  categories,
  notes,
  links_json,
  collections_photos,
  projects,
  projects_categories,
};
