import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared';
import z from 'zod';

type Awaitable<T> = T | Promise<T>;

export const layoutConfigSchema = z.object({
  /**
   * the shared options for layouts.
   */
  base: z
    .custom<() => Awaitable<BaseLayoutProps>>()
    .refine((v) => typeof v === 'function')
    .or(z.custom<BaseLayoutProps>().refine((v) => typeof v === 'object' && v !== null))
    .optional(),

  presets: z
    .object({
      /**
       * layout preset for Markdown files.
       */
      md: z.literal(['docs', 'flux']).default('docs'),
    })
    .optional(),
});

export const projectConfigSchema = z.object({
  /**
   * project name.
   */
  name: z.string(),
  /**
   * root directory for content files.
   */
  dir: z.string(),
  /**
   * a list of glob patterns, customize the content files to be scanned.
   */
  include: z.array(z.string()).optional(),
  /**
   * directory to the static assets
   */
  assetsDir: z.array(z.string()).optional(),

  /**
   * whether to enable file watch
   */
  watch: z.boolean().default(true),
});

export const contentConfigSchema = z.object({
  /**
   * a list of project configurations.
   */
  projects: z.array(projectConfigSchema).optional(),

  /**
   * allow file-system access outside of project directories.
   */
  unsafe_disableFileSystemChecks: z.boolean().default(false),
});

export const aiConfigSchema = z.object({
  /**
   * Specify a model ID, by default it uses OpenRouter.
   */
  model: z.string().optional(),

  ratelimit: z.boolean().default(true),
});

export const configSchema = z.object({
  layout: layoutConfigSchema.default(() => layoutConfigSchema.parse({})),
  content: contentConfigSchema.default(() => contentConfigSchema.parse({})),
  ai: aiConfigSchema.default(() => aiConfigSchema.parse({})),
});

export type LayoutConfig = z.infer<typeof layoutConfigSchema>;
export type ContentConfig = z.infer<typeof contentConfigSchema>;
export type ProjectConfig = z.infer<typeof projectConfigSchema>;
export type AppConfig = z.input<typeof configSchema>;
export type ParsedAppConfig = z.output<typeof configSchema>;

export function defineConfig(config: AppConfig = {}): AppConfig {
  return config;
}
