{-# LANGUAGE OverloadedStrings #-}
-- | Module: Gram.Schema.TypeScript
--
-- Generates TypeScript type definitions for Pattern<Subject>.
--
-- This module provides functions to generate TypeScript interfaces and types
-- that model Pattern<Subject> for downstream TypeScript/JavaScript ports.
--
-- @since 0.1.0
module Gram.Schema.TypeScript
  ( generateTypeScriptTypes
  ) where

import qualified Data.Text as T
import Data.Text (Text)

-- | Generate TypeScript type definitions for Pattern<Subject>
--
-- Returns TypeScript code with:
-- - Interface definitions for Pattern, Subject
-- - Discriminated union types for Value
-- - Type guards for runtime type checking
-- - JSDoc comments for documentation
--
-- Example usage:
-- @
-- let tsCode = generateTypeScriptTypes
-- writeFile "pattern.ts" (T.unpack tsCode)
-- @
--
-- @since 0.1.0
generateTypeScriptTypes :: Text
generateTypeScriptTypes :: Text
generateTypeScriptTypes = [Text] -> Text
T.unlines
  [ Text
"/**"
  , Text
" * Pattern<Subject> TypeScript Type Definitions"
  , Text
" * Generated from gram-hs canonical JSON Schema"
  , Text
" * Version: 0.1.0"
  , Text
" */"
  , Text
""
  , Text
"/**"
  , Text
" * A pattern with a subject and optional nested pattern elements."
  , Text
" * Patterns are recursive: they can contain other patterns as elements."
  , Text
" */"
  , Text
"export interface Pattern {"
  , Text
"  /** The subject of this pattern */"
  , Text
"  subject: Subject;"
  , Text
"  /** Nested pattern elements */"
  , Text
"  elements: Pattern[];"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * A subject with identity, labels, and properties."
  , Text
" */"
  , Text
"export interface Subject {"
  , Text
"  /** Identity symbol for the subject */"
  , Text
"  identity: string;"
  , Text
"  /** Set of labels classifying the subject */"
  , Text
"  labels: string[];"
  , Text
"  /** Map of property names to values */"
  , Text
"  properties: Record<string, Value>;"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Symbol value with type discriminator"
  , Text
" */"
  , Text
"export interface ValueSymbol {"
  , Text
"  type: 'symbol';"
  , Text
"  value: string;"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Tagged string value (e.g., URL, JSON, code)"
  , Text
" */"
  , Text
"export interface ValueTaggedString {"
  , Text
"  type: 'tagged';"
  , Text
"  tag: string;"
  , Text
"  content: string;"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Numeric range value with optional bounds"
  , Text
" */"
  , Text
"export interface ValueRange {"
  , Text
"  type: 'range';"
  , Text
"  lower: number | null;"
  , Text
"  upper: number | null;"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Measurement value with unit and numeric value"
  , Text
" */"
  , Text
"export interface ValueMeasurement {"
  , Text
"  type: 'measurement';"
  , Text
"  unit: string;"
  , Text
"  value: number;"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Value can be integer, number, boolean, string, symbol, tagged string,"
  , Text
" * array, map, range, or measurement."
  , Text
" *"
  , Text
" * This is a discriminated union type. Complex types use a 'type' field"
  , Text
" * for discrimination at runtime."
  , Text
" */"
  , Text
"export type Value ="
  , Text
"  | number              // Integer or decimal"
  , Text
"  | boolean"
  , Text
"  | string"
  , Text
"  | ValueSymbol"
  , Text
"  | ValueTaggedString"
  , Text
"  | Value[]             // Array of values"
  , Text
"  | Record<string, Value>  // Map (no 'type' field)"
  , Text
"  | ValueRange"
  , Text
"  | ValueMeasurement;"
  , Text
""
  , Text
"// Type guards for runtime type checking"
  , Text
""
  , Text
"/**"
  , Text
" * Type guard to check if a value is a ValueSymbol"
  , Text
" */"
  , Text
"export function isValueSymbol(value: Value): value is ValueSymbol {"
  , Text
"  return typeof value === 'object' && value !== null && 'type' in value && value.type === 'symbol';"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Type guard to check if a value is a ValueTaggedString"
  , Text
" */"
  , Text
"export function isValueTaggedString(value: Value): value is ValueTaggedString {"
  , Text
"  return typeof value === 'object' && value !== null && 'type' in value && value.type === 'tagged';"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Type guard to check if a value is a ValueRange"
  , Text
" */"
  , Text
"export function isValueRange(value: Value): value is ValueRange {"
  , Text
"  return typeof value === 'object' && value !== null && 'type' in value && value.type === 'range';"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Type guard to check if a value is a ValueMeasurement"
  , Text
" */"
  , Text
"export function isValueMeasurement(value: Value): value is ValueMeasurement {"
  , Text
"  return typeof value === 'object' && value !== null && 'type' in value && value.type === 'measurement';"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Type guard to check if a value is an array"
  , Text
" */"
  , Text
"export function isValueArray(value: Value): value is Value[] {"
  , Text
"  return Array.isArray(value);"
  , Text
"}"
  , Text
""
  , Text
"/**"
  , Text
" * Type guard to check if a value is a map (plain object without 'type' field)"
  , Text
" */"
  , Text
"export function isValueMap(value: Value): value is Record<string, Value> {"
  , Text
"  return typeof value === 'object' && value !== null && !Array.isArray(value) && !('type' in value);"
  , Text
"}"
  ]