import type { JSONSupport, JSONSupportMixinProperties } from "../../core/JSONSupport.js";
import type { FormElementType } from "../../portal/jsonTypes.js";

export interface ElementProperties extends JSONSupportMixinProperties, Partial<Pick<Element, "description" | "label" | "visibilityExpression">> {}

/**
 * Form elements define what should display within the [FormTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-FormTemplate.html) elements.
 * There are five specific element types:
 *
 * * [FieldElement](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-FieldElement.html)
 * * [GroupElement](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-GroupElement.html)
 * * [RelationshipElement](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-RelationshipElement.html)
 * * [TextElement](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-TextElement.html)
 * * [UtilityNetworkAssociationsElement](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-UtilityNetworkAssociationsElement.html)
 *
 * The `Element` class is a read-only base class which has no constructor.
 *
 * @since 4.16
 */
export default abstract class Element extends JSONSupport {
  /** The element's description providing the purpose behind it. */
  accessor description: string | null | undefined;
  /** A string value containing the field alias. This should not be used for referencing fields in Arcade expressions. Rather, the service [FieldElement#fieldName](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-FieldElement.html#fieldName) should be referenced. */
  accessor label: string | null | undefined;
  /**
   * The type of form element to display.
   *
   * Possible Value | Description
   * ---------------|-------------
   * attachment | An individual [attachment](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-AttachmentElement.html) element that defines an input for attachments in a [FormTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-FormTemplate.html). _Note that this type is not fully supported in the [FeatureForm](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureForm.html) widget and is not intended for use in the SDK. Support will be added in a future release._
   * field | An individual [field](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-FieldElement.html) element that defines the field within a layer or [form's](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureForm.html#formTemplate) `formTemplate`.
   * group | Contains a [grouping](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-GroupElement.html) of [field](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-FieldElement.html) elements.
   * relationship | A [relationship](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-RelationshipElement.html) element defines a relationship between [Map#layers](https://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html#layers) and [Map#tables](https://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html#tables) and how they participate in the [FeatureForm](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureForm.html).
   * text | A [text](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-TextElement.html) element defines descriptive text in a [FormTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-FormTemplate.html).
   * utilityNetworkAssociations | A [utilityNetworkAssociations](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-UtilityNetworkAssociationsElement.html) element defines how utility network associations participate in the form.
   */
  get type(): FormElementType;
  /**
   * A reference to the [ExpressionInfo#name](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-ExpressionInfo.html#name) of an
   * [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) expression defined in the
   * [FormTemplate#expressionInfos](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-FormTemplate.html#expressionInfos) of the [FormTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-FormTemplate.html).
   *
   * When this expression evaluates to `true`, the element is displayed. When the expression evaluates to `false` the element is not displayed. If no expression
   * is provided, the element is always displayed.
   * Care must be taken when defining a visibility expression for a non-nullable
   * field as to make certain the specified field has either 1) a default value, or 2) is made visible to the end user to enter a value before submitting the form.
   *
   * > [!WARNING]
   * >
   * > The expression must follow the specification
   * > defined in the [Form Calculation Profile](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation). This expression references field values within an individual feature or in other layers and must return either a date, number, or string value.
   * > The referenced expression must be defined in the form template's [FormTemplate#expressionInfos](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-FormTemplate.html#expressionInfos).
   * > It cannot be set inline within the element object.
   * > [Field](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-FieldElement.html) and [Group](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-GroupElement.html) elements must be visible if the field or one of the grouped fields is [required](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-FieldElement.html#requiredExpression).
   *
   * @see [ExpressionInfo](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-ExpressionInfo.html)
   * @see [Sample - Update Feature Attributes](https://developers.arcgis.com/javascript/latest/sample-code/editing-groupedfeatureform/)
   * @see [Form Constraint Arcade Profile](https://developers.arcgis.com/javascript/latest/arcade/#constraint)
   * @example
   * // Expression created within ExpressionInfos and is referenced in element
   * const expression = new ExpressionInfo({
   *   name: "alwaysHidden",
   *   expression: "false"
   * });
   *
   * // Reference an already-defined visibilityExpression set within the ExpressionInfos
   * const fieldElement = new FieldElement({
   *   type: "field",
   *   fieldName: "inspemail",
   *   label: "Email address",
   *   visibilityExpression: "alwaysHidden"
   * });
   *
   * formTemplate.expressionInfos = [ expression ];
   * formTemplate.elements = [ fieldElement ];
   */
  accessor visibilityExpression: string | null | undefined;
}