import type ExpressionInfo from "./ExpressionInfo.js";
import type Field from "../layers/support/Field.js";
import type FieldsIndex from "../layers/support/FieldsIndex.js";
import type Relationship from "../layers/support/Relationship.js";
import type { ClonableMixin } from "../core/Clonable.js";
import type { JSONSupport } from "../core/JSONSupport.js";
import type { FormElementUnion } from "./types.js";
import type { AttachmentElementProperties } from "./elements/AttachmentElement.js";
import type { FieldElementProperties } from "./elements/FieldElement.js";
import type { GroupElementProperties } from "./elements/GroupElement.js";
import type { RelationshipElementProperties } from "./elements/RelationshipElement.js";
import type { TextElementProperties } from "./elements/TextElement.js";
import type { UtilityNetworkAssociationsElementProperties } from "./elements/UtilityNetworkAssociationsElement.js";
import type { ExpressionInfoProperties } from "./ExpressionInfo.js";

export interface FormTemplateProperties extends Partial<Pick<FormTemplate, "description" | "preserveFieldValuesWhenHidden" | "title">> {
  /**
   * An array of [form element](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/)
   * objects that represent an ordered list of form elements.
   *
   * Elements are designed to allow the form author the ability to
   * define the layout for fields when collecting and/or editing data.
   *
   * > [!WARNING]
   * >
   * > * Nested group elements are not supported.
   * > * The `AttachmentElement` is not yet fully supported by the [FeatureForm](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/) widget. Support will be added in a future release.
   *
   * @see [FieldElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/)
   * @see [GroupElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/GroupElement/)
   * @see [RelationshipElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/)
   * @see [TextElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/TextElement/)
   * @see [UtilityNetworkAssociationsElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/UtilityNetworkAssociationsElement/)
   * @example
   * // Create a new form template
   * const formTemplate = new FormTemplate({
   *   title: "Damage assessments",
   *   description: "Provide information for insurance",
   *   elements: [{ // Autocasts to new GroupElement
   *     type: "group",
   *     label: "Inspector Information",
   *     description: "Field inspector information",
   *     elements: [{
   *       // Autocasts to new FieldElement
   *       type: "field",
   *       fieldName: "inspector",
   *       label: "name"
   *     },{
   *       type: "field",
   *       fieldName: "inspemail",
   *       label: "Email address"
   *     },{
   *       type: "field",
   *       fieldName: "insp_date",
   *       label: "Date of inspection"
   *     }]
   *   }]
   * });
   */
  elements?: ((AttachmentElementProperties & { type: "attachment"; }) | (FieldElementProperties & { type: "field"; }) | (GroupElementProperties & { type: "group"; }) | (RelationshipElementProperties & { type: "relationship"; }) | (TextElementProperties & { type: "text"; }) | (UtilityNetworkAssociationsElementProperties & { type: "utilityNetworkAssociations"; }))[] | null;
  /**
   * An array of [ExpressionInfo](https://developers.arcgis.com/javascript/latest/references/core/form/ExpressionInfo/) objects
   * that reference [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) expressions following the specification
   * defined by the [Form Constraint Profile](https://developers.arcgis.com/javascript/latest/arcade/#constraint) or the
   * [Form Calculation Profile](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation). Form Constraint expressions
   * must return either `true` or `false`. Form Calculation expressions must return
   * a string, date, boolean, or a number.
   *
   * @see [Element.visibilityExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/#visibilityExpression)
   * @see [Sample - Update Feature Attributes](https://developers.arcgis.com/javascript/latest/sample-code/editing-groupedfeatureform/)
   * @see [Sample - Editing related data with calculated expressions](https://developers.arcgis.com/javascript/latest/sample-code/widgets-editor-relates-calculations/)
   * @see [Sample - Editing with calculated field expressions](https://developers.arcgis.com/javascript/latest/sample-code/widgets-featureform-async/)
   * @see [Form Constraint Profile Specification](https://developers.arcgis.com/javascript/latest/arcade/#constraint)
   * @see [Form Calculation Profile Specification](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation)
   */
  expressionInfos?: ExpressionInfoProperties[] | null;
}

/**
 * A `FormTemplate` formats and defines the content of a [FeatureForm](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/) for
 * a specific [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) or [SubtypeSublayer](https://developers.arcgis.com/javascript/latest/references/core/layers/support/SubtypeSublayer/).
 * The `FormTemplate` allows the user to create and update feature attribute values which can be set directly on a [FeatureLayer.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#formTemplate), [SubtypeSublayer.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/layers/support/SubtypeSublayer/#formTemplate),a [FeatureForm.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/#formTemplate), a [FeatureForm view model](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/FeatureFormViewModel/#formTemplate), or within the [Editor's layerInfos](https://developers.arcgis.com/javascript/latest/references/core/widgets/Editor/#layerInfos).
 * The `FormTemplate` is composed of various [elements](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/#elements) that display a specific type of form data. Each element is designed to allow the form author the ability to define the layout for fields when collecting and/or editing data.
 *
 * Forms can be created with a variety of elements, including:
 * * [FieldElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/): Represents a single field in the form.
 * * [GroupElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/GroupElement/): Represents a group of `field`, `relationship`, or `text` elements in the form.
 * * [RelationshipElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/): Represents a relationship in the form.
 * * [TextElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/TextElement/): Represents a text element in the form.
 *
 * The `FormTemplate` also supports the use of [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) expressions to define form constraints and calculations. These expressions can be used to set the [visibility](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/#visibilityExpression) of all form elements, make [fields required](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#requiredExpression), or dynamically [calculate field values](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#valueExpression).
 *
 * If a `FormTemplate` is set on a [FeatureLayer.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#formTemplate), [SubtypeSublayer.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/layers/support/SubtypeSublayer/#formTemplate), or the [Editor widget's layerInfos](https://developers.arcgis.com/javascript/latest/references/core/widgets/Editor/#layerInfos), it is used for all features within the specified layer. If the form's template is authored using the Map Viewer's [authoring experience](https://doc.arcgis.com/en/arcgis-online/create-maps/create-form-mv.htm) or [Field Maps Designer](https://learn.arcgis.com/en/projects/build-a-form-with-field-maps-designer), the resulting saved layer or web map [item's](https://doc.arcgis.com/en/arcgis-online/get-started/item-details.htm) JSON will contain a [formInfo](https://developers.arcgis.com/web-map-specification/objects/formInfo/) object.
 *
 * @since 4.16
 * @see [Sample - Update Feature Attributes](https://developers.arcgis.com/javascript/latest/sample-code/editing-groupedfeatureform/)
 * @see [Sample - Advanced Attribute Editing](https://developers.arcgis.com/javascript/latest/sample-code/editing-featureform-fieldvisibility/)
 * @see [Sample - Update FeatureLayer using applyEdits()](https://developers.arcgis.com/javascript/latest/sample-code/editing-applyedits/)
 * @see [Sample - Editing with calculated field expressions](https://developers.arcgis.com/javascript/latest/sample-code/widgets-featureform-async/)
 * @see [Sample - Edit FeatureLayers with form elements ](https://developers.arcgis.com/javascript/latest/sample-code/widgets-editor-form-elements/)
 * @see [Sample - Editing related data with calculated expressions](https://developers.arcgis.com/javascript/latest/sample-code/widgets-editor-relates-calculations/)
 * @see [FeatureForm.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/#formTemplate)
 * @see [FeatureFormViewModel.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/FeatureFormViewModel/#formTemplate)
 * @see [FeatureLayer.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#formTemplate)
 * @see [SubtypeSublayer.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/layers/support/SubtypeSublayer/#formTemplate)
 * @see [Editor.layerInfos.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/widgets/Editor/#layerInfos)
 * @see [Web Map Specification - formInfo](https://developers.arcgis.com/web-map-specification/objects/formInfo/)
 * @example
 * // Create a FieldElement
 * const fieldElement = new FieldElement({
 *   fieldName: "inspector",
 *   label: "Inspector name"
 * });
 *
 * // Create a TextElement
 * const textElement = new TextElement({
 *   textFormat: "markdown",
 *   text: "**This text is bold.**"
 * });
 *
 * // Create the group element and pass in the field and text elements
 * const groupElement = new GroupElement({
 *   label: "This is a group",
 *   elements: [fieldElement, textElement]
 * });
 *
 * // Create the Form template and pass in elements
 * const formTemplate = new FormTemplate({
 *   title: "Inspector report",
 *   description: "Enter all relevant information below",
 *   elements: [groupElement] // Add all elements to the template
 * });
 *
 * // Add a new feature form with grouped fields
 * const form = new FeatureForm({
 *   container: "form",
 *   groupDisplay: "sequential", // only display one group at a time
 *   formTemplate: formTemplate // set it to template created above
 * });
 *
 * // Add a formtemplate to a feature layer
 * const featureLayer = new FeatureLayer({
 *  url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/ServiceRequest/FeatureServer/0",
 *  outFields: ["*"],
 *  formTemplate: formTemplate
 * });
 * map.add(featureLayer);
 *
 * // Add a formtemplate to a subtype sublayer
 * const sublayer = new SubtypeSublayer({
 *   layer: featureLayer,
 *   subtype: "1",
 *   formTemplate: formTemplate
 * });
 *
 * // Add a formtemplate to the Editor's layerInfos
 * const editor = new Editor({
 *   view: view,
 *   layerInfos: [
 *   {
 *     layer: featureLayer,
 *     formTemplate: formTemplate
 *   }]
 * });
 */
export default class FormTemplate extends FormTemplateSuperclass {
  constructor(properties?: FormTemplateProperties);
  /**
   * The description of the form. It is possible to substitute a template string for a field value within this description.
   *
   * @example formTemplate.description = "The population of {County}, {State} is: {Population}";
   */
  accessor description: string | null | undefined;
  /**
   * An array of [form element](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/)
   * objects that represent an ordered list of form elements.
   *
   * Elements are designed to allow the form author the ability to
   * define the layout for fields when collecting and/or editing data.
   *
   * > [!WARNING]
   * >
   * > * Nested group elements are not supported.
   * > * The `AttachmentElement` is not yet fully supported by the [FeatureForm](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/) widget. Support will be added in a future release.
   *
   * @see [FieldElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/)
   * @see [GroupElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/GroupElement/)
   * @see [RelationshipElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/)
   * @see [TextElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/TextElement/)
   * @see [UtilityNetworkAssociationsElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/UtilityNetworkAssociationsElement/)
   * @example
   * // Create a new form template
   * const formTemplate = new FormTemplate({
   *   title: "Damage assessments",
   *   description: "Provide information for insurance",
   *   elements: [{ // Autocasts to new GroupElement
   *     type: "group",
   *     label: "Inspector Information",
   *     description: "Field inspector information",
   *     elements: [{
   *       // Autocasts to new FieldElement
   *       type: "field",
   *       fieldName: "inspector",
   *       label: "name"
   *     },{
   *       type: "field",
   *       fieldName: "inspemail",
   *       label: "Email address"
   *     },{
   *       type: "field",
   *       fieldName: "insp_date",
   *       label: "Date of inspection"
   *     }]
   *   }]
   * });
   */
  get elements(): FormElementUnion[] | null | undefined;
  set elements(value: ((AttachmentElementProperties & { type: "attachment"; }) | (FieldElementProperties & { type: "field"; }) | (GroupElementProperties & { type: "group"; }) | (RelationshipElementProperties & { type: "relationship"; }) | (TextElementProperties & { type: "text"; }) | (UtilityNetworkAssociationsElementProperties & { type: "utilityNetworkAssociations"; }))[] | null | undefined);
  /**
   * An array of [ExpressionInfo](https://developers.arcgis.com/javascript/latest/references/core/form/ExpressionInfo/) objects
   * that reference [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) expressions following the specification
   * defined by the [Form Constraint Profile](https://developers.arcgis.com/javascript/latest/arcade/#constraint) or the
   * [Form Calculation Profile](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation). Form Constraint expressions
   * must return either `true` or `false`. Form Calculation expressions must return
   * a string, date, boolean, or a number.
   *
   * @see [Element.visibilityExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/#visibilityExpression)
   * @see [Sample - Update Feature Attributes](https://developers.arcgis.com/javascript/latest/sample-code/editing-groupedfeatureform/)
   * @see [Sample - Editing related data with calculated expressions](https://developers.arcgis.com/javascript/latest/sample-code/widgets-editor-relates-calculations/)
   * @see [Sample - Editing with calculated field expressions](https://developers.arcgis.com/javascript/latest/sample-code/widgets-featureform-async/)
   * @see [Form Constraint Profile Specification](https://developers.arcgis.com/javascript/latest/arcade/#constraint)
   * @see [Form Calculation Profile Specification](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation)
   */
  get expressionInfos(): ExpressionInfo[] | null | undefined;
  set expressionInfos(value: ExpressionInfoProperties[] | null | undefined);
  /**
   * Indicates whether to retain or clear a [form's](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/) [field element](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/) values. Use this property when a field element initially displays as visible but later updates to not be visible as a result of an applied [FieldElement.visibilityExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#visibilityExpression).
   *
   * @default false
   * @since 4.25
   * @see [FieldElement.visibilityExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#visibilityExpression)
   */
  accessor preserveFieldValuesWhenHidden: boolean;
  /**
   * The string defining how to format the title displayed at the top of a form. It is possible to substitute a template string for a field value within this description.
   *
   * @example formTemplate.title = "{County}, {State}";
   */
  accessor title: string | null | undefined;
  /**
   * Returns the names of all fields represented or referenced in any way by the
   * FormTemplate. This includes fields where [field elements](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/) exist in
   * the form, as well as any fields referenced in the form's [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) [expressions](https://developers.arcgis.com/javascript/latest/references/core/form/ExpressionInfo/#expression) and used in templated strings in the [title](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/#title) and [description](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/#description) of the form and in the [Element.label](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/#label) and [Element.description](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/#description) of its elements.
   *
   * >
   * > Below is a comprehensive list of all the possible ways in which a field can be utilized within a `FormTemplate`:
   * > * The `FormTemplate` contains a [field element](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/) associated with the field.
   * > * The field is identified by the [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) parser as being referenced in an [ExpressionInfo.expression](https://developers.arcgis.com/javascript/latest/references/core/form/ExpressionInfo/#expression) that is used by one (or more) of the elements in the
   * > `FormTemplate`. **Take note that expressions included in [ExpressionInfo](https://developers.arcgis.com/javascript/latest/references/core/form/ExpressionInfo/) but not used by any of the elements are not considered.**
   * > * The field is referenced via a template string, ie.`{}`, substitution syntax in the [title](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/#title) or [description](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/#description) properties of the `FormTemplate`.
   * > * The `FormTemplate` contains an element whose [Element.label](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/#label) or [Element.description](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/#description) properties reference the field via a template string, ie.`{}`, substitution syntax.
   * > * The `FormTemplate` contains [TextElement.text](https://developers.arcgis.com/javascript/latest/references/core/form/elements/TextElement/#text) that references the field via a template string, ie.`{}`, substitution syntax.
   * > * The form contains a [RelationshipElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/) that uses the field to order results, as specified in its [RelationshipElement.orderByFields](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/#orderByFields) property.
   * > * The field serves as a relationship key field for a relationship that is represented by a [RelationshipElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/) in the `FormTemplate`. These fields will be included in the output _only_ if a value is provided for the relationship parameter. **The `FormTemplate` by itself does not possess enough information to determine the key field of a relationship.**
   * > * The `FormTemplate` contains [UtilityNetworkAssociationsElement.label](https://developers.arcgis.com/javascript/latest/references/core/form/elements/UtilityNetworkAssociationsElement/#label) or [UtilityNetworkAssociationsElement.description](https://developers.arcgis.com/javascript/latest/references/core/form/elements/UtilityNetworkAssociationsElement/#description) that references the field via a template string, ie.`{}`, substitution syntax.
   *
   * @param fieldsIndex - The field index. It can be used to make
   * case-insensitive lookup by name for fields used in the `FormTemplate`.
   * @param relationships - An array of [Relationship](https://developers.arcgis.com/javascript/latest/references/core/layers/support/Relationship/) objects that define the relationships on the layer with which the `FormTemplate` is associated.
   * @returns Resolves with the names of the fields.
   * @since 4.30
   */
  getFieldsUsed<T extends Field = Field>(fieldsIndex?: FieldsIndex<T>, relationships?: Relationship[]): Promise<string[]>;
}
declare const FormTemplateSuperclass: typeof JSONSupport & typeof ClonableMixin