import type Element from "./Element.js";
import type RelatedRecordsInfoFieldOrder from "../../popup/support/RelatedRecordsInfoFieldOrder.js";
import type { ElementProperties } from "./Element.js";
import type { RelatedRecordsInfoFieldOrderProperties } from "../../popup/support/RelatedRecordsInfoFieldOrder.js";

export interface RelationshipElementProperties extends ElementProperties, Partial<Pick<RelationshipElement, "displayCount" | "editableExpression" | "relationshipId">> {
  /**
   * An array of [RelatedRecordsInfoFieldOrder](https://developers.arcgis.com/javascript/latest/api-reference/esri-popup-support-RelatedRecordsInfoFieldOrder.html)
   * objects indicating the field display order for the related records
   * and whether they should be sorted in ascending `asc` or descending `desc` order.
   */
  orderByFields?: RelatedRecordsInfoFieldOrderProperties[] | null;
}

/**
 * A `RelationshipElement` form element defines how a relationship between [FeatureLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html) or [MapImageLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-MapImageLayer.html) and [Map#tables](https://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html#tables) participates in the [FeatureForm](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureForm.html). When this element is present in the form, the option to add or edit related records is provided per the underlying service's editing permissions and whether it allows relationship editing.
 *
 * > [!WARNING]
 * >
 * > **Known Limitations when editing related data**
 * > Support is limited to 1:1 and 1:M cardinality.
 * > Support is limited to feature-to-table and feature-to-feature relationships, ie. origin-to-destination. The origin's entry point must be a feature with geometry.
 * > Relationship editing is only supported using ArcGIS Online and ArcGIS Enterprise version 11.2 or higher feature services.
 * > The layer and associated {@link form/elements/Relationship relationship elements} must be editable in order for the relationship to display.
 * > Data containing related records will display the relationship in the associated form as long as there is a {@link form/elements/Relationship relationship element} configured in the [layer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#formTemplate) or [form's](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureForm.html#formTemplate) formTemplate. This can be accomplished via the Map Viewer's [authoring experience](https://doc.arcgis.com/en/arcgis-online/create-maps/create-form-mv.htm), [Field Maps Designer](https://learn.arcgis.com/en/projects/build-a-form-with-field-maps-designer), or programmatically using the API.
 * > The related layer or table must also be added to the map to be able to configure {@link form/elements/Relationship relationship elements}.
 * > Relationship editing on layers with preset and group templates are not yet supported.
 *
 * @since 4.27
 * @see [FormTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-FormTemplate.html)
 * @see [Editor](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Editor.html)
 * @see [FeatureForm](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureForm.html)
 * @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/)
 * @example
 * // Create the relationship element
 * const relationshipElement = new RelationshipElement({
 *   description: "Past and present building owners",
 *   displayCount: 5,
 *   label: "Building owners",
 *   orderByFields: [{ //autocastable to RelatedRecordsInfoFieldOrder
 *     field: "owner_name",
 *     order: "desc"
 *   }],
 *   relationshipId: 0
 * });
 */
export default class RelationshipElement extends Element {
  constructor(properties?: RelationshipElementProperties);
  /**
   * A numeric value indicating the maximum number of related features to display in the list of related records.
   * If no value is specified, the `Show all` button will be available to display all related records and the associated
   * [RelationshipInput](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-FeatureForm-RelationshipInput.html) defaults to 3. If the total amount of features is greater than the `displayCount`, a `Show all` button displays.
   *
   * @default 3
   */
  accessor displayCount: number | null | undefined;
  /**
   * A string value indicating how to display related records within the relationship content. Currently, `list` is the only supported value.
   *
   * | Value    | Description |
   * | ------ | ----------- |
   * | list   | Shows a list of related records from the specified relationship. |
   *
   * @default "list"
   */
  get displayType(): "list";
  /**
   * 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.
   * The expression must follow the specification
   * defined in the [Form Constraint Profile](https://developers.arcgis.com/javascript/latest/arcade/#constraint). Expressions
   * may reference field values using the `$feature` global input and must return either `true` or `false`.
   *
   * When this expression evaluates to `true`, it is possible to edit the field value, and vice-versa if `false`. If the referenced related table is not editable, the editable expression is ignored and the element is not editable.
   *
   * > [!WARNING]
   * >
   * > 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.
   *
   * @see [Form Constraint Arcade Profile](https://developers.arcgis.com/javascript/latest/arcade/#constraint)
   */
  accessor editableExpression: string | null | undefined;
  /**
   * An array of [RelatedRecordsInfoFieldOrder](https://developers.arcgis.com/javascript/latest/api-reference/esri-popup-support-RelatedRecordsInfoFieldOrder.html)
   * objects indicating the field display order for the related records
   * and whether they should be sorted in ascending `asc` or descending `desc` order.
   */
  get orderByFields(): RelatedRecordsInfoFieldOrder[] | null | undefined;
  set orderByFields(value: RelatedRecordsInfoFieldOrderProperties[] | null | undefined);
  /** The numeric id value for the defined relationship. This value can be found on the [service](https://developers.arcgis.com/rest/services-reference/enterprise/feature-service.htm) itself or on the service's [relationships resource](https://developers.arcgis.com/rest/services-reference/enterprise/relationships-feature-service-.htm) if `supportsRelationshipResource` is `true`. */
  accessor relationshipId: number;
  /** Indicates the type of form [Element](https://developers.arcgis.com/javascript/latest/api-reference/esri-form-elements-Element.html). */
  get type(): "relationship";
  /**
   * Creates a deep clone of the RelationshipElement class.
   *
   * @returns A deep clone of the RelationshipElement instance.
   */
  clone(): RelationshipElement;
}