import type Element from "./Element.js";
import type { NestableFormElementUnion } from "../types.js";
import type { AttachmentElementProperties } from "./AttachmentElement.js";
import type { ElementProperties } from "./Element.js";
import type { FieldElementProperties } from "./FieldElement.js";
import type { RelationshipElementProperties } from "./RelationshipElement.js";
import type { TextElementProperties } from "./TextElement.js";
import type { GroupState } from "../../portal/jsonTypes.js";

export interface GroupElementProperties extends ElementProperties, Partial<Pick<GroupElement, "initialState">> {
  /**
   * An array of [field](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/), [relationship](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/), and [text](https://developers.arcgis.com/javascript/latest/references/core/form/elements/TextElement/) elements to display as grouped.
   * These objects represent an ordered list of [form](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/) elements.
   *
   * > [!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.
   */
  elements?: ((AttachmentElementProperties & { type: "attachment"; }) | (FieldElementProperties & { type: "field"; }) | (RelationshipElementProperties & { type: "relationship"; }) | (TextElementProperties & { type: "text"; }))[] | null;
}

/**
 * A `GroupElement` form element defines a container that holds a set of
 * [form elements](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/#elements)
 * that can be expanded, collapsed, or displayed together. Use this to set grouped field configurations within 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) `formTemplate`.
 *
 *
 * Form with individual field elements | Form with grouped field elements
 * -----------------------------------|----------------------------------
 * ![field element](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/formtemplate/field-elements.png) | ![group element](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/formtemplate/group-elements.png)
 *
 *
 * > [!WARNING]
 * >
 * > Nested group elements are not supported.
 * > A group element must be visible if it contains a [required](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/#requiredExpression) field.
 *
 * @since 4.16
 * @see [FormTemplate](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/)
 * @see [FeatureForm](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/)
 * @see [FieldElement](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/)
 * @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/)
 * @example
 * const fieldElement1 = new FieldElement({
 *   fieldName: "inspector",
 *   label: "Inspector name"
 * });
 *
 * const fieldElement2 = new FieldElement({
 *   fieldName: "inspdate",
 *   label: "Inspection date",
 *   description: "Date inspection was handled",
 *   input: { // autocastable to DateTimePickerInput
 *     type: "datetime-picker",
 *       includeTime: true,
 *       min: 1547678342000,
 *       max: 1610836742000
 *     }
 * });
 *
 * const fieldElement3 = new FieldElement({
 *   fieldName: "placename",
 *   label: "Business name",
 *   editable: false
 * });
 *
 * // Create the group element and pass in elements from above
 * const groupElement = new GroupElement({
 *   label: "Business contact information",
 *   description: "Enter the business contact name",
 *   elements:[fieldElement1, fieldElement2, fieldElement3]
 * });
 *
 * // Next pass in any elements to the FormTemplate
 * const formTemplate = new FormTemplate({
 *   title: "Inspector report",
 *   description: "Enter all relevant information below",
 *   elements: [groupElement] // Add group element to the template
 * });
 */
export default class GroupElement extends Element {
  constructor(properties?: GroupElementProperties);
  /**
   * An array of [field](https://developers.arcgis.com/javascript/latest/references/core/form/elements/FieldElement/), [relationship](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/), and [text](https://developers.arcgis.com/javascript/latest/references/core/form/elements/TextElement/) elements to display as grouped.
   * These objects represent an ordered list of [form](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/) elements.
   *
   * > [!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.
   */
  get elements(): NestableFormElementUnion[];
  set elements(value: ((AttachmentElementProperties & { type: "attachment"; }) | (FieldElementProperties & { type: "field"; }) | (RelationshipElementProperties & { type: "relationship"; }) | (TextElementProperties & { type: "text"; }))[] | null | undefined);
  /**
   * Defines if the group should be expanded or collapsed when the form is initially displayed.
   *
   * Possible Value | Description
   * ---------------|-------------
   * collapsed | The grouped elements appear collapsed.
   * expanded | The grouped elements appear expanded.
   *
   * @default "expanded"
   */
  accessor initialState: GroupState;
  /** The type of the [Element](https://developers.arcgis.com/javascript/latest/references/core/form/elements/Element/). */
  get type(): "group";
  /**
   * Creates a deep clone of the GroupElement class.
   *
   * @returns A deep clone of the GroupElement instance.
   */
  clone(): GroupElement;
}