import { defineCollection, z } from 'astro:content';

// Define custom date validator that handles multiple formats
const customDateParser = (dateString: string | Date | null | undefined) => {
  // Handle null/undefined
  if (dateString === null || dateString === undefined) {
    return new Date();
  }
  
  // If date is already a Date object, return it
  if (dateString instanceof Date) {
    return dateString;
  }
  
  // Try to parse the date as is
  let date = new Date(dateString);
  
  // For format like "Jul 22 2023"
  if (isNaN(date.getTime()) && typeof dateString === 'string') {
    try {
      // Try various formats
      if (dateString.match(/^\d{2}\/\d{2}\/\d{4}$/)) {
        const [month, day, year] = dateString.split('/').map(Number);
        date = new Date(year, month - 1, day);
      }
    } catch (e) {
      // Default to current date if all parsing fails
      date = new Date();
    }
  }
  
  return date;
};

// Define the base schema for all content
const baseSchema = z.object({
  title: z.string(),
  description: z.string().optional(),
  pubDate: z.union([z.string(), z.date(), z.null()]).optional().default(() => new Date()).transform(customDateParser),
  updatedDate: z.union([z.string(), z.date(), z.null()]).optional().transform(val => val ? customDateParser(val) : undefined),
  heroImage: z.string().optional().nullable(),
  // Add categories array that falls back to the single category field
  categories: z.union([
    z.array(z.string()),
    z.string().transform(val => [val]),
    z.null()
  ]).optional().transform(val => {
    if (val === null || val === undefined) return ['Uncategorized'];
    return val;
  }),
  // Keep the original category field for backward compatibility
  category: z.string().optional().default('Uncategorized'),
  tags: z.union([z.array(z.string()), z.null()]).optional().default([]),
  draft: z.boolean().optional().default(false),
  readTime: z.union([z.string(), z.number()]).optional(),
  image: z.string().optional(),
  excerpt: z.string().optional(),
  author: z.string().optional(),
  github: z.string().optional(),
  live: z.string().optional(),
  technologies: z.array(z.string()).optional(),
}).passthrough() // Allow any other frontmatter properties
  .transform(data => {
    // If categories isn't set but category is, use category value to populate categories
    if ((!data.categories || data.categories.length === 0) && data.category) {
      data.categories = [data.category];
    }
    return data;
  });

// Define collections using the same base schema
const postsCollection = defineCollection({
  type: 'content',
  schema: baseSchema,
});

const configurationsCollection = defineCollection({
  type: 'content',
  schema: baseSchema,
});

const projectsCollection = defineCollection({
  type: 'content',
  schema: baseSchema,
});

const externalPostsCollection = defineCollection({
  type: 'content',
  schema: baseSchema,
});

// Export the collections
export const collections = {
  'posts': postsCollection,
  'configurations': configurationsCollection,
  'projects': projectsCollection,
  'external-posts': externalPostsCollection,
};