import { z } from 'zod'

// ============================================================================
// Content Block Schemas
// ============================================================================

/**
 * Text block schema
 * Renders styled text with optional variant
 */
export const TextBlockSchema = z.object({
  type: z.literal('text'),
  content: z.string(),
  variant: z.enum(['title', 'subtitle', 'body', 'caption', 'coverCompany', 'coverVertical', 'coverScope', 'coverSolutions']).optional(),
})

/**
 * Metric block schema
 * Displays a large value with a label
 */
export const MetricBlockSchema = z.object({
  type: z.literal('metric'),
  value: z.string(),
  label: z.string(),
  showAccent: z.boolean().optional(),
})

/**
 * List item schema - supports plain strings or objects with highlight
 */
export const ListItemSchema = z.union([
  z.string(),
  z.object({ text: z.string(), highlight: z.boolean().optional() }),
])

/**
 * List block schema
 * Renders bullet or numbered lists with optional highlighted items
 */
export const ListBlockSchema = z.object({
  type: z.literal('list'),
  items: z.array(ListItemSchema),
  ordered: z.boolean().optional(),
})

// ============================================================================
// Content Block Types
// ============================================================================

/**
 * Text block type
 */
export type TextBlock = z.infer<typeof TextBlockSchema>

/**
 * Metric block type
 */
export type MetricBlock = z.infer<typeof MetricBlockSchema>

/**
 * List item type - either plain string or object with text and optional highlight
 */
export type ListItem = z.infer<typeof ListItemSchema>

/**
 * List block type
 */
export type ListBlock = z.infer<typeof ListBlockSchema>

/**
 * Table block schema
 * Renders a data table with headers and rows
 */
export const TableBlockSchema = z.object({
  type: z.literal('table'),
  headers: z.array(z.string()),
  rows: z.array(z.array(z.string())),
  /** Optional column widths - pdfmake width values (number, '*', 'auto', or percentage string) */
  columnWidths: z.array(z.union([z.number(), z.string()])).optional(),
  /** Optional footer/totals row - styled like header row */
  footerRow: z.array(z.string()).optional(),
})

/**
 * Table block type
 */
export type TableBlock = z.infer<typeof TableBlockSchema>

// ============================================================================
// Leaf Content Block Schema (non-container blocks only)
// ============================================================================

/**
 * Leaf content block schema
 * Union of all non-container block types (no cards or columns)
 * Used to prevent recursive nesting - containers can only hold leaves
 */
export const LeafContentBlockSchema = z.union([
  TextBlockSchema,
  MetricBlockSchema,
  ListBlockSchema,
  TableBlockSchema,
])

/**
 * Leaf content block type
 * Non-container blocks that can be nested inside cards/columns
 */
export type LeafContentBlock = TextBlock | MetricBlock | ListBlock | TableBlock

/**
 * Card block type
 * Styled container that holds leaf content blocks (no nested cards/columns)
 */
export interface CardBlock {
  type: 'card'
  title?: string
  content: LeafContentBlock[]
  variant?: 'default' | 'accent' | 'light'
  layout?: 'vertical' | 'horizontal'
}

/**
 * Columns block type
 * Simple horizontal layout that holds leaf content blocks (no nested cards/columns)
 */
export interface ColumnsBlock {
  type: 'columns'
  content: LeafContentBlock[]
}

/**
 * Content block union type
 * All renderable content types for PDF pages
 */
export type ContentBlock = LeafContentBlock | CardBlock | ColumnsBlock

// ============================================================================
// Container Block Schemas (cards and columns hold leaf content only)
// ============================================================================

/**
 * Card block schema
 * Styled container that holds leaf content blocks (no nested cards/columns)
 */
export const CardBlockSchema: z.ZodType<CardBlock> = z.object({
  type: z.literal('card'),
  title: z.string().optional(),
  content: z.array(LeafContentBlockSchema),
  variant: z.enum(['default', 'accent', 'light']).optional(),
  layout: z.enum(['vertical', 'horizontal']).optional(),
})

/**
 * Columns block schema
 * Simple horizontal layout that holds leaf content blocks (no nested cards/columns)
 */
export const ColumnsBlockSchema: z.ZodType<ColumnsBlock> = z.object({
  type: z.literal('columns'),
  content: z.array(LeafContentBlockSchema),
})

/**
 * Content block schema
 * Union of all content block types (leaves + containers)
 */
export const ContentBlockSchema: z.ZodType<ContentBlock> = z.union([
  LeafContentBlockSchema,
  CardBlockSchema,
  ColumnsBlockSchema,
])

// ============================================================================
// Cover Page Schema
// ============================================================================

/**
 * Cover page logo configuration
 */
export const CoverLogoSchema = z.object({
  /** Logo source - URL or base64 */
  src: z.string(),
  /** Logo width in points (default: 60) */
  width: z.number().optional(),
  /** Logo position (default: 'left') */
  position: z.enum(['left', 'center', 'right']).optional(),
})

/**
 * Cover page configuration schema
 * Provides flexible layout for cover/title pages with positioned content areas
 */
export const CoverPageConfigSchema = z.object({
  /** Logo or content positioned at top-left */
  topLeft: z.union([CoverLogoSchema, z.array(ContentBlockSchema)]).optional(),
  /** Content positioned at top-right (e.g., "AUTOMATION PROPOSAL") */
  topRight: z.array(ContentBlockSchema).optional(),
  /** Center main content vertically on page */
  centerContent: z.boolean().optional(),
  /** Content positioned at bottom-left (e.g., "Prepared for...") */
  bottomLeft: z.array(ContentBlockSchema).optional(),
  /** Content positioned at bottom-right (e.g., date) */
  bottomRight: z.array(ContentBlockSchema).optional(),
})

export type CoverLogo = z.infer<typeof CoverLogoSchema>
export type CoverPageConfig = z.infer<typeof CoverPageConfigSchema>

// ============================================================================
// Header Schema
// ============================================================================

/**
 * Page header configuration schema
 * Supports different header styles for flexibility
 */
export const HeaderConfigSchema = z.object({
  /** Header title text */
  title: z.string().optional(),
  /** Subtitle text (smaller, shown above title) */
  subtitle: z.string().optional(),
  /** Logo source - URL or base64 (for logo-style headers) */
  logo: z.string().optional(),
  /** Header style variant */
  variant: z.enum(['default', 'accent']).optional(),
})

export type HeaderConfig = z.infer<typeof HeaderConfigSchema>

// ============================================================================
// Page Schema
// ============================================================================

/**
 * Page schema
 * Defines a single PDF page with sections, optional header, footer, and cover page config
 */
export const PageSchema = z.object({
  /** Main content sections */
  sections: z.array(ContentBlockSchema),
  /** Page header configuration */
  header: HeaderConfigSchema.optional(),
  /** Show footer (default: true) */
  footer: z.boolean().default(true),
  /** Cover page configuration - when present, enables cover page layout */
  cover: CoverPageConfigSchema.optional(),
})

// ============================================================================
// Document Schema
// ============================================================================

/**
 * Document schema
 * Full PDF document structure with pages and optional metadata
 */
export const DocumentSchema = z.object({
  pages: z.array(PageSchema),
  metadata: z
    .object({
      title: z.string().optional(),
      author: z.string().optional(),
    })
    .optional(),
})

// ============================================================================
// Page and Document Types
// ============================================================================

export type Page = z.infer<typeof PageSchema>
export type PDFDocument = z.infer<typeof DocumentSchema>
