import type { JSONSupport } from "../core/JSONSupport.js";
import type { FormExpressionReturnType } from "../portal/jsonTypes.js";

export interface ExpressionInfoProperties extends Partial<Pick<ExpressionInfo, "expression" | "name" | "returnType" | "title">> {}

/**
 * The `ExpressionInfo` class defines the makeup of [visibility expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#visibilityExpression), [required expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#requiredExpression), [editable expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#editableExpression), and [value expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#valueExpression). [Visibility expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#visibilityExpression) are available on [field](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/), [group](https://developers.arcgis.com/javascript/latest/references/core/form/elements/GroupElement/), and [relationship](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/) elements. These [FormTemplate.elements](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/#elements) are contained within a `formTemplate` set directly on either a [FeatureForm.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/#formTemplate) or [FeatureLayer.formTemplate](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#formTemplate).
 *
 * All of the [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) expressions referenced above, excluding [value expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#valueExpression), must follow the specification defined in the [Form Constraint Profile](https://developers.arcgis.com/javascript/latest/arcade/#forms). This profile may reference field values using the `$feature` variable and the expression must return `true` or `false`.
 *
 * [Value expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#valueExpression) must follow the specification defined in the [Form Calculation Profile](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation). It may reference field values within an individual `$feature` or in other layers and must return either a date, number, or string value. Once the expression evaluates, the form's field value updates to the expressions' result.
 *
 * > [!WARNING]
 * >
 * > It is required to set the [FeatureForm.map](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/#map)
 * > property when instantiating a [FeatureForm](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/) widget
 * > and using expressions that use the `$map` variable.
 *
 * @since 4.16
 * @see [FormTemplate](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/)
 * @see [FieldElement.visibilityExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#visibilityExpression)
 * @see [GroupElement.visibilityExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/GroupElement/#visibilityExpression)
 * @see [FieldElement.requiredExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#requiredExpression)
 * @see [FieldElement.editableExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#editableExpression)
 * @see [FieldElement.valueExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#valueExpression)
 * @see [RelationshipElement.visibilityExpression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/#visibilityExpression)
 * @see [Sample - Editor using calculated expressions](https://developers.arcgis.com/javascript/latest/sample-code/widgets-featureform-async)
 * @see [Form Constraint Profile Specification](https://developers.arcgis.com/javascript/latest/arcade/#forms)
 * @see [Form Calculation Profile](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation)
 */
export default class ExpressionInfo extends JSONSupport {
  constructor(properties?: ExpressionInfoProperties);
  /**
   * An [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) expression following the specification
   * defined by the [Form Constraint](https://developers.arcgis.com/javascript/latest/arcade/#forms) or [Form Calculation](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation) profiles. [Visibility expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#visibilityExpression), [required expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#requiredExpression), and [editable expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#editableExpression) follow the specification defined in the [Form Constraint](https://developers.arcgis.com/javascript/latest/arcade/#forms) profile. These expressions may reference field values using the `$feature` profile variable and must return either `true` or `false`.
   *
   * [Value expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#valueExpression) adhere to the specification defined in the [Form Calculation](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation) profile. The available profile variables when working with [value expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#valueExpression) extend beyond just `$feature` since it is also possible to access values beyond the individual feature that is being displayed.
   *
   * @see [Form Constraint Arcade Profile](https://developers.arcgis.com/javascript/latest/arcade/#forms)
   * @see [Form Calculation](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation)
   * @example
   * // Sets the visibility of a field in the form template only if the date is within the last 24 hours.
   * expressionInfo.expression = "IIF(DateDiff(Now(), $feature.incident_date, 'hours') < 24)";
   */
  accessor expression: string;
  /**
   * The name of the expression. Set this name to the
   * [visibility expression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#visibilityExpression), [required expression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#requiredExpression), [editable expression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#editableExpression), and/or [value expression](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#valueExpression) properties of its respective elements.
   *
   * @example expressionInfo.name = "withinRange";
   */
  accessor name: string;
  /**
   * Indicates the return type of the Arcade expression. In FeatureForm
   * expressions, the returnType can be `boolean`, `date`, `number` or `string`. This is dependant upon the type of expression used. For example, [visibility expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#visibilityExpression), [required expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#requiredExpression), and [editable expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#editableExpression) only return a boolean, whereas [value expressions](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#valueExpression) return either `date`, `number`, or `string`.
   *
   * @default "boolean"
   * @see [Form Constraint Arcade Profile](https://developers.arcgis.com/javascript/latest/arcade/#forms)
   * @see [Form Calculation](https://developers.arcgis.com/javascript/latest/arcade/#form-calculation)
   */
  accessor returnType: FormExpressionReturnType;
  /**
   * The title used to describe the value returned by the expression.
   *
   * @example expressionInfo.title = "Did the incident occur within the last 24 hours?";
   */
  accessor title: string | null | undefined;
  /**
   * Creates a deep clone of the ExpressionInfo class.
   *
   * @returns A deep clone of the ExpressionInfo instance.
   */
  clone(): ExpressionInfo;
}