{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "FormDefinition.schema.json",
  "title": "FormDefinition",
  "x-group": "Definitions",
  "type": "object",
  "description": "A comprehensive definition structure for building dynamic, configurable forms\n\n`FormDefinition` provides a flexible framework for creating character sheets, spell lists, inventory screens,\nand other data entry forms common in tabletop RPG systems. It supports hierarchical organization through tabs,\nsections, and fields, with conditional visibility and custom rendering options.",
  "properties": {
    "title": {
      "type": "string",
      "description": "The display title for the form.\n\nThis appears at the top of the form interface and helps users identify the purpose of the form.\nFor example: \"Character Sheet\", \"Inventory\", \"Spell List\"."
    },
    "icon": {
      "type": "string",
      "description": "An optional SF Symbol name or image identifier for the form.\n\nUsed to provide visual identification in tab bars, navigation, and form headers.\nExamples: \"person.fill\", \"bag.fill\", \"star.fill\""
    },
    "tabs": {
      "type": "array",
      "items": {
        "$ref": "#"
      },
      "description": "Child form definitions for tabbed interfaces.\n\nWhen present, creates a tabbed interface where each tab contains its own form definition.\nUseful for organizing complex character sheets with separate tabs for stats, inventory, spells, etc.\n\n- Note: If `tabs` is set, `sections` is typically `nil` at the root level, as content is organized within tabs."
    },
    "sections": {
      "type": "array",
      "items": {
        "$ref": "#"
      },
      "description": "The sections that make up this form.\n\nSections provide logical grouping of related fields (e.g., \"Ability Scores\", \"Skills\", \"Equipment\").\nEach section can have its own type, conditional visibility, and nested fields."
    },
    "partial": {
      "type": "string",
      "description": "A template string for partial rendering.\n\nUsed for custom rendering scenarios where the form needs to include dynamically generated content\nbased on character data. Templates use mustache-style syntax: `{{ attribute }}`."
    },
    "error": {
      "type": "string",
      "description": "An error message to display if form loading or validation fails.\n\nThis can be set when a form definition is invalid, missing required data, or encounters\nsystem-specific errors during initialization."
    }
  },
  "additionalProperties": false,
  "$defs": {
    "Section": {
      "title": "Section",
      "type": "object",
      "description": "A logical grouping of related form fields within a form.\n\nSections organize form content into meaningful units such as \"Ability Scores\", \"Skills\", or \"Equipment\".\nThey support different presentation types (groups, lists, pickers) and can contain nested forms for\ncomplex data structures.",
      "properties": {
        "id": {
          "type": "string",
          "description": "A unique identifier for this section.\n\nAutomatically generated using `UUID().uuidString` if not provided."
        },
        "title": {
          "type": "string",
          "description": "Examples: \"Ability Scores\", \"Skills\", \"Equipment\", \"Spellcasting\""
        },
        "units": {
          "type": "string",
          "description": "Optional units label for numeric fields in this section.\n\nExamples: \"ft\", \"lb\", \"gp\" (for feet, pounds, gold pieces)"
        },
        "type": {
          "$ref": "#/$defs/SectionType",
          "description": "The presentation type for this section.\n\nDefaults to `.group` if not specified."
        },
        "attribute": {
          "type": "string",
          "description": "The data model path for this section's primary value.\n\nUses dot notation to reference nested properties (e.g., \"stats.strength\", \"inventory.items\").\nFor list sections, this typically points to an array in the data model."
        },
        "attributeType": {
          "type": "string",
          "description": "The expected type of data for this section's attribute.\n\nUsed for validation and type coercion. Common values include:\n- \"String\", \"Int\", \"Double\", \"Bool\"\n- \"[String]\", \"[Item]\" for arrays\n- Custom type names for complex objects"
        },
        "defaultValue": {
          "description": "The default value to use when initializing new instances.\n\nParticularly useful for list sections where new items need default values.\nFor example, a new inventory item might default to `[\"name\": \"\", \"quantity\": 1]`."
        },
        "visibleIf": {
          "type": "string",
          "description": "A template condition determining when this section should be visible.\n\nSupports two formats:\n1. Template expressions: `\"{{ hasSpellcasting }}\"` - Shows section if value is truthy\n2. Conditional expressions: `\"level >= 3\"` - Shows section if condition evaluates to true\n\nSee `isVisible(data:)` for evaluation details."
        },
        "hiddenIf": {
          "type": "string",
          "description": "A template condition determining when this section should be hidden.\n\nOpposite of `visibleIf`. Supports the same formats:\n1. Template expressions: `\"{{ isNPC }}\"` - Hides section if value is truthy\n2. Conditional expressions: `\"level < 3\"` - Hides section if condition evaluates to true"
        },
        "custom": {
          "type": "object",
          "additionalProperties": true,
          "description": "Custom key-value pairs for section-specific metadata.\n\nAllows extensions and plugins to attach additional configuration without modifying the core structure.\nFor example, a game system plugin might store `[\"systemId\": \"dnd5e\", \"version\": \"2024\"]`."
        },
        "fields": {
          "type": "array",
          "items": {
            "$ref": "#"
          },
          "description": "The fields contained within this section.\n\nFor `.group` sections, these are displayed in order.\nFor `.list` sections, this is typically empty and the `form` property defines list item structure instead."
        },
        "form": {
          "$ref": "#",
          "description": "An embedded form definition for complex section items.\n\nPrimarily used for `.list` sections where each item has multiple fields.\nFor example, an inventory list might use a form with fields for item name, quantity, weight, and value."
        }
      },
      "required": [
        "id"
      ],
      "additionalProperties": false
    },
    "SectionType": {
      "title": "SectionType",
      "description": "The presentation style for a form section.\n\nDifferent section types determine how fields are laid out and how users interact with the data.",
      "type": "string",
      "enum": [
        "group",
        "list",
        "picker",
        "multiPicker",
        "dnd5eClassFeatures"
      ]
    },
    "Field": {
      "title": "Field",
      "type": "object",
      "description": "A single input field within a form section.\n\nFields represent individual data entry points like text boxes, number spinners, toggles, and pickers.\nThey bind to specific attributes in the data model and can have conditional visibility, validation,\nand custom rendering.",
      "properties": {
        "id": {
          "type": "string",
          "description": "A unique identifier for this field.\n\nAutomatically generated using `UUID().uuidString` if not provided."
        },
        "title": {
          "type": "string",
          "description": "Examples: \"Character Name\", \"Armor Class\", \"Hit Points\""
        },
        "units": {
          "type": "string",
          "description": "Optional units label for numeric fields.\n\nDisplayed alongside the field value. Examples: \"ft\", \"lb\", \"gp\""
        },
        "detail": {
          "type": "string",
          "description": "Supplementary text providing additional context.\n\nDisplayed below the field title. Examples: \"Your character's current hit points\",\n\"Base AC before adding modifiers\""
        },
        "placeholder": {
          "type": "string",
          "description": "Placeholder text shown when the field is empty.\n\nExamples: \"Enter character name\", \"Select a class\""
        },
        "type": {
          "$ref": "#/$defs/FieldType",
          "description": "The input type for this field.\n\nDefaults to `.text` if not specified."
        },
        "attribute": {
          "type": "string",
          "description": "The data model path this field binds to.\n\nUses dot notation for nested properties: \"stats.strength\", \"inventory.gold\""
        },
        "attributeType": {
          "type": "string",
          "description": "The expected type of data for this field's attribute.\n\nUsed for validation and type coercion. Common values:\n- \"String\", \"Int\", \"Double\", \"Bool\"\n- \"[String]\" for arrays\n- Custom type names for complex objects"
        },
        "filter": {
          "type": "string",
          "description": "A filter expression for limiting selection options.\n\nUsed with reference, picker, and multiPicker fields to filter available choices.\nExample: `\"type == 'Weapon' && rarity == 'Common'\"` for filtering items"
        },
        "defaultValue": {
          "description": "The default value when creating new instances.\n\nUsed when initializing new forms or adding list items."
        },
        "alignment": {
          "$ref": "ViewDefinition.schema.json#/$defs/Alignment",
          "description": "The text alignment for this field's content.\n\nExamples: `.leading`, `.center`, `.trailing`"
        },
        "text": {
          "type": "string",
          "description": "Static text content for display-only fields.\n\nUsed with certain field types to show non-editable text or labels."
        },
        "visibleIf": {
          "type": "string",
          "description": "A template condition determining when this field should be visible.\n\nSame format as `Section/visibleIf`. Examples:\n- `\"{{ class == 'Wizard' }}\"` - Show for wizards only\n- `\"level >= 5\"` - Show at level 5 or higher"
        },
        "hiddenIf": {
          "type": "string",
          "description": "A template condition determining when this field should be hidden.\n\nOpposite of `visibleIf`. Same format and evaluation rules."
        },
        "custom": {
          "type": "object",
          "additionalProperties": true,
          "description": "Custom key-value pairs for field-specific metadata.\n\nAllows extensions and plugins to attach additional configuration."
        },
        "form": {
          "$ref": "#",
          "description": "An embedded form definition for complex fields.\n\nUsed with `.form` field type to nest complete forms within a field."
        },
        "fields": {
          "type": "array",
          "items": {
            "$ref": "#"
          },
          "description": "Child fields for container field types.\n\nUsed with `.hStack` to define fields that should be laid out horizontally."
        }
      },
      "required": [
        "id"
      ],
      "additionalProperties": false
    },
    "FieldType": {
      "title": "FieldType",
      "description": "The type of input control for a form field.\n\nField types determine both the user interface control and the expected data type.",
      "type": "string",
      "enum": [
        "number",
        "decimal",
        "toggle",
        "reference",
        "text",
        "textArea",
        "picker",
        "multiPicker",
        "colorPicker",
        "menu",
        "tags",
        "attributes",
        "modifiers",
        "list",
        "form",
        "hStack",
        "checkbox"
      ]
    }
  }
}
