import { z } from 'zod'

/**
 * Documentation Configuration Schema (docs.json)
 * 
 * Mintlify-compatible configuration schema for documentation sites.
 */

// ============================================================================
// Navigation Schemas
// ============================================================================

const anchorSchema = z.object({
  anchor: z.string(),
  href: z.string(),
  icon: z.string().optional(),
})

const navLinkSchema = z.object({
  label: z.string(),
  href: z.string(),
})

// Page can be a string or a nested group
const pageRefSchema: z.ZodType<string | { group: string; pages: (string | object)[] }> = z.lazy(() => 
  z.union([
    z.string(), // Page path like "quickstart" or "guides/intro"
    z.object({  // Nested group
      group: z.string(),
      pages: z.array(z.union([z.string(), z.lazy(() => pageRefSchema)])),
    }),
  ])
)

const groupSchema = z.object({
  group: z.string(),
  pages: z.array(pageRefSchema),
  icon: z.string().optional(),
})

// OpenAPI version schema
const openapiVersionSchema = z.object({
  version: z.string(),
  spec: z.string(),
  default: z.boolean().optional(),
})

// Different tab types
const docsTabSchema = z.object({
  tab: z.string(),
  type: z.literal('docs').optional(),
  groups: z.array(groupSchema),
})

const openapiTabSchema = z.object({
  tab: z.string(),
  type: z.literal('openapi'),
  path: z.string().optional(),
  versions: z.array(openapiVersionSchema).optional(),
  spec: z.string().optional(),
  groups: z.array(groupSchema).optional(), // Doc groups alongside API reference
})

const graphqlTabSchema = z.object({
  tab: z.string(),
  type: z.literal('graphql'),
  path: z.string().optional(),
  schema: z.string(), // GraphQL schema file path
  endpoint: z.string().optional(), // GraphQL endpoint URL
  groups: z.array(groupSchema).optional(), // Doc groups alongside API reference
})

const changelogTabSchema = z.object({
  tab: z.string(),
  type: z.literal('changelog'),
  path: z.string().optional(),
})

const tabSchema = z.union([docsTabSchema, openapiTabSchema, graphqlTabSchema, changelogTabSchema])

const navigationSchema = z.object({
  tabs: z.array(tabSchema).optional(),
  groups: z.array(groupSchema).optional(), // For single-tab sites
  global: z.object({
    anchors: z.array(anchorSchema).optional(),
  }).optional(),
})

// ============================================================================
// Theme & Branding Schemas
// ============================================================================

const colorSchema = z.object({
  primary: z.string(),
  light: z.string().optional(),
  dark: z.string().optional(),
  background: z.object({
    light: z.string().optional(),
    dark: z.string().optional(),
  }).optional(),
})

const logoSchema = z.object({
  light: z.string(),
  dark: z.string(),
  href: z.string().optional(),
})

const faviconSchema = z.string()

// ============================================================================
// Navbar Schema
// ============================================================================

const navbarPrimarySchema = z.object({
  type: z.enum(['button', 'github', 'link']),
  label: z.string().optional(),
  href: z.string(),
})

const navbarSchema = z.object({
  links: z.array(navLinkSchema).optional(),
  primary: navbarPrimarySchema.optional(),
})

// ============================================================================
// Footer Schema
// ============================================================================

const footerLinkSchema = z.object({
  label: z.string(),
  href: z.string(),
})

const footerGroupSchema = z.object({
  title: z.string(),
  links: z.array(footerLinkSchema),
})

const footerSchema = z.object({
  socials: z.record(z.string(), z.string()).optional(),
  links: z.array(footerGroupSchema).optional(),
})

// ============================================================================
// API Configuration Schema
// ============================================================================

const apiAuthSchema = z.object({
  method: z.enum(['bearer', 'basic', 'api-key', 'none']),
  name: z.string().optional(),
})

const apiPlaygroundSchema = z.object({
  mode: z.enum(['show', 'simple', 'hide']).optional(),
})

const apiConfigSchema = z.object({
  baseUrl: z.string().optional(),
  auth: apiAuthSchema.optional(),
  playground: apiPlaygroundSchema.optional(),
})

// ============================================================================
// SEO Schema
// ============================================================================

const seoSchema = z.object({
  indexHiddenPages: z.boolean().optional(),
  titleTemplate: z.string().optional(),
})

// ============================================================================
// Integrations Schema
// ============================================================================

const analyticsSchema = z.object({
  posthog: z.object({ apiKey: z.string() }).optional(),
  googleAnalytics: z.object({ measurementId: z.string() }).optional(),
  plausible: z.object({ domain: z.string() }).optional(),
})

const integrationsSchema = z.object({
  analytics: analyticsSchema.optional(),
})

// ============================================================================
// Contextual Menu Schema
// ============================================================================

const contextualOptionsEnum = z.enum([
  'copy',
  'view',
  'chatgpt',
  'claude',
  'perplexity',
  'mcp',
  'cursor',
  'vscode',
])

const contextualSchema = z.object({
  options: z.array(contextualOptionsEnum).optional(),
})

// ============================================================================
// Main Configuration Schema
// ============================================================================

export const docsConfigSchema = z.object({
  // Schema reference (optional)
  $schema: z.string().optional(),
  
  // Core identity
  name: z.string(),
  
  // Theme
  theme: z.enum(['default', 'mint', 'quill', 'venus']).optional(),
  colors: colorSchema.optional(),
  
  // Branding
  favicon: faviconSchema.optional(),
  logo: logoSchema.optional(),
  
  // Navigation
  navigation: navigationSchema,
  
  // Navbar
  navbar: navbarSchema.optional(),
  
  // Footer
  footer: footerSchema.optional(),
  
  // API Configuration
  api: apiConfigSchema.optional(),
  openapi: z.union([z.string(), z.array(z.string())]).optional(),
  
  // SEO
  seo: seoSchema.optional(),
  
  // Integrations
  integrations: integrationsSchema.optional(),
  
  // Contextual menu
  contextual: contextualSchema.optional(),
  
  // Topbar style
  topbar: z.object({
    style: z.enum(['default', 'gradient']).optional(),
  }).optional(),
  
  // Versioning
  versions: z.array(z.string()).optional(),
})

// ============================================================================
// Types
// ============================================================================

export type DocsConfig = z.infer<typeof docsConfigSchema>
export type NavigationTab = z.infer<typeof tabSchema>
export type NavigationGroup = z.infer<typeof groupSchema>
export type NavLink = z.infer<typeof navLinkSchema>
export type Anchor = z.infer<typeof anchorSchema>
export type ColorConfig = z.infer<typeof colorSchema>
export type LogoConfig = z.infer<typeof logoSchema>
export type ApiConfig = z.infer<typeof apiConfigSchema>

// ============================================================================
// Validation Functions
// ============================================================================

/**
 * Parse and validate docs configuration
 */
export function parseDocsConfig(data: unknown): DocsConfig {
  const result = docsConfigSchema.safeParse(data)
  
  if (!result.success) {
    const issues = result.error.issues || []
    const errors = issues.map((e) => 
      `${e.path.map(String).join('.')}: ${e.message}`
    ).join('\n')
    throw new Error(`Invalid docs.json configuration:\n${errors}`)
  }
  
  return result.data
}

/**
 * Safe parse that returns null on failure
 */
export function safeParseDocsConfig(data: unknown): DocsConfig | null {
  const result = docsConfigSchema.safeParse(data)
  return result.success ? result.data : null
}

/**
 * Get default configuration
 */
export function getDefaultDocsConfig(): Partial<DocsConfig> {
  return {
    theme: 'default',
    navigation: {
      groups: [],
    },
  }
}
