import type Graphic from "../Graphic.js";
import type EsriMap from "../Map.js";
import type Collection from "../core/Collection.js";
import type UtilityNetworkAssociationType from "../popup/support/UtilityNetworkAssociationType.js";
import type Widget from "./Widget.js";
import type BatchAttributeFormViewModel from "./BatchAttributeForm/BatchAttributeFormViewModel.js";
import type VisibleElements from "./BatchAttributeForm/VisibleElements.js";
import type UtilityNetworkAssociationsElementInput from "./BatchAttributeForm/inputs/UtilityNetworkAssociationsElementInput.js";
import type { Icon } from "@esri/calcite-components/components/calcite-icon";
import type { WidgetProperties } from "./Widget.js";
import type { BatchAttributeFormViewModelEvents, BatchAttributeFormViewModelProperties } from "./BatchAttributeForm/BatchAttributeFormViewModel.js";
import type { AssociationsLayerUnion, AttributeFormSupportedLayerInfo, FooterButtonInfo, Page, SelectedAttachmentDetails, SelectedAttachmentIdentifier } from "./BatchAttributeForm/types.js";
import type { HeadingLevel } from "./support/types.js";
import type { VisibleElementsProperties } from "./BatchAttributeForm/VisibleElements.js";

export interface BatchAttributeFormProperties extends WidgetProperties, Partial<Pick<BatchAttributeForm, "activeFeatureIndex" | "attachmentsEnabled" | "disabled" | "features" | "groupDisplay" | "headingLevel" | "layerInfos" | "map" | "readOnly" | "timeZone">> {
  /**
   * Icon displayed in the widget's button.
   *
   * @default "edit-attributes"
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  icon?: Icon["icon"] | null;
  /**
   * The view model for this widget. This is a class that contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [BatchAttributeFormViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/BatchAttributeForm/BatchAttributeFormViewModel/) class to access
   * all properties and methods on the widget.
   */
  viewModel?: BatchAttributeFormViewModelProperties;
  /** Defines which elements are visible in the widget. */
  visibleElements?: VisibleElementsProperties;
}

export interface BatchAttributeFormEvents extends BatchAttributeFormViewModelEvents {}

/**
 * The `BatchAttributeForm` provides a user-friendly interface for editing attributes. It supports both batch and single feature editing modes, allowing users to switch between editing all selected features at once or focusing on individual features as needed. It provides a dynamic form that adapts to the fields of the selected features, ensuring that editors can efficiently manage and update feature attributes. This is ideal when multiple features must share consistent attribute values, as it reduces redundant data entry.
 *
 * > [!WARNING]
 * >
 * > **Known Limitations**
 * >
 * >  Currently, [relationship elements](https://developers.arcgis.com/javascript/latest/references/core/form/elements/RelationshipElement/) and [associations elements](https://developers.arcgis.com/javascript/latest/references/core/form/elements/UtilityNetworkAssociationsElement/) are not supported within this widget. Users can individually edit related records and association fields using the [FeatureForm](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureForm/) widget.
 *
 * @deprecated since version 5.0. Use the [Editor](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-editor/) component to edit attributes of multiple features instead. For information on widget deprecation, read about [Esri's move to web components](https://developers.arcgis.com/javascript/latest/components-transition-plan/).
 * @since 4.33
 * @see [BatchAttributeFormViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/BatchAttributeForm/BatchAttributeFormViewModel/)
 * @see [DefaultUI](https://developers.arcgis.com/javascript/latest/references/core/views/ui/DefaultUI/)
 * @see [Editor](https://developers.arcgis.com/javascript/latest/references/core/widgets/Editor/)
 * @example
 * const batchAttributeForm = new BatchAttributeForm({
 *   container: formDiv, // id of HTML div
 *   features: featureCollection,
 *   map: map, // Required if using Arcade expressions that use the global $map variable
 * });
 */
export default class BatchAttributeForm extends Widget<BatchAttributeFormProperties> {
  /**
   * @deprecated
   * Do not directly reference this property.
   * Use EventNames and EventTypes helpers from \@arcgis/core/Evented
   */
  "@eventTypes": BatchAttributeFormEvents;
  /**
   * @example
   * // Typical usage
   * const batchAttributeForm = new BatchAttributeForm({
   *   container: "formDiv", // id of HTML div
   *   features: featureCollection, // Pass in the featureCollection that works with the widget
   *   map: map, // Required if using Arcade expressions that use the global $map variable
   * });
   */
  constructor(properties?: BatchAttributeFormProperties);
  /**
   * The index of the active feature that is currently being edited. This will be `-1` when [BatchAttributeFormViewModel.mode](https://developers.arcgis.com/javascript/latest/references/core/widgets/BatchAttributeForm/BatchAttributeFormViewModel/#mode) is `batch`.
   * To enter `single` mode, set this property to the index in the [features](https://developers.arcgis.com/javascript/latest/references/core/widgets/BatchAttributeForm/#features) array of the feature you wish to edit individually. To enter `batch` mode, set this property to `-1`.
   *
   * @default -1
   * @example
   * // Initialize BatchAttributeForm with single feature editing
   * const baf = new BatchAttributeForm({
   *   activeFeatureIndex: 0, // -1 for batch editing mode. In this case, single editing mode.
   *   layerInfos: [
   *   {
   *     layer: featureLayer,
   *     formTemplate
   *   }]
   * });
   */
  accessor activeFeatureIndex: number;
  /**
   * Indicates whether attachment elements should be rendered in the form. Changing this value will cause the form to regenerate
   * and discard any pending edits.
   *
   * @default false
   * @internal
   */
  accessor attachmentsEnabled: boolean;
  /**
   * Indicates if the widget is disabled. When `true`, the widget is not interactive and cannot be submitted.
   *
   * @default false
   */
  accessor disabled: boolean;
  /**
   * Indicates the component is in a disabled or readOnly state, disregarding updating
   *
   * @internal
   */
  get disabledOrReadOnly(): boolean;
  /**
   * Indicates the component is currently in a disabled state, accounting for when the
   * viewModel is in the process of updating.
   *
   * @internal
   */
  get effectiveDisabled(): boolean;
  /**
   * The title that should be displayed for the current page.
   *
   * @internal
   */
  get effectiveTitle(): string;
  /**
   * The collection of features whose attributes are being edited.
   *
   * @example
   * // Query for features
   * const { features } = await featureLayer.queryFeatures({
   *   // Ensure the features have a complete set of attributes for use in the form
   *   outFields: "*",
   * });
   * // Initialize BatchAttributeForm
   * const batchAttributeForm = new BatchAttributeForm({
   *  features // pass in the collection of features to edit
   * });
   */
  accessor features: Collection<Graphic>;
  /**
   * Configuration information about buttons displayed in the footer.
   * This can be used to replicate button behavior in an external panel (e.g. Editor).
   *
   * @internal
   */
  get footerButtonInfos(): FooterButtonInfo[];
  /**
   * Defines how groups will be displayed to the user.
   *
   * **Possible Values**
   *
   * Value | Description |
   * ----- | ----------- |
   * all | All groups will be expanded.
   * sequential | A single group will be expanded at a time.
   *
   * @default "all"
   */
  accessor groupDisplay: "all" | "sequential";
  /**
   * Indicates the heading level to use for the title of the form.
   * By default, the title is rendered as a level 2 heading (e.g. `<h2>Form title</h2>`).
   * In addition, group element labels default to a level 3 heading (e.g. `<h3>Group element label</h3>`).
   * Depending on the widget's placement
   * in your app, you may need to adjust this heading for proper semantics. This is
   * important for meeting accessibility standards.
   *
   * @default 2
   * @see [Heading Elements](https://developer.mozilla.org/docs/Web/HTML/Reference/Elements/Heading_Elements)
   * @example
   * // form title will render as an <h3>
   * // group element labels will render as an <h4>
   * form.headingLevel = 3;
   */
  accessor headingLevel: HeadingLevel;
  /**
   * Icon displayed in the widget's button.
   *
   * @default "edit-attributes"
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  get icon(): Icon["icon"];
  set icon(value: Icon["icon"] | null | undefined);
  /**
   * An array of objects containing a [FormTemplate](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/) and its corresponding layer.
   * This allows per-layer overrides which provides a [FormTemplate](https://developers.arcgis.com/javascript/latest/references/core/form/FormTemplate/) for building batch form templates. The `formTemplate` defined here overrides any `formTemplate` defined on the layer itself. Otherwise, the layer's own `formTemplate` is used if it exists.
   *
   * @example
   * // Query for features
   * const { features } = await featureLayer.queryFeatures();
   *
   * // Initialize BatchAttributeForm
   * const batchAttributeForm = new BatchAttributeForm({
   *   features: features, // pass in the collection of features to edit
   *   layerInfos: [{
   *     layer: featureLayer,
   *     formTemplate:  { // This will override any formTemplate defined on the layer itself
   *       elements: [
   *         {
   *           type: "field",
   *           fieldName: "fulladdr",
   *           label: "Full Address"
   *         }
   *       ]
   *     },
   *   }]
   * });
   */
  accessor layerInfos: AttributeFormSupportedLayerInfo[] | null | undefined;
  /**
   * A reference to the associated [Map](https://developers.arcgis.com/javascript/latest/references/core/Map/).
   *
   * > [!WARNING]
   * >
   * > This property is required if working with [Arcade expressions](https://developers.arcgis.com/javascript/latest/arcade/) in the `BatchAttributeForm` that make use of the `$map` global variable.
   */
  accessor map: EsriMap | null | undefined;
  /**
   * The 'page' the form is currently rendering. This is only relevant when nested views are required.
   *
   * @internal
   */
  get page(): Page;
  /**
   * Indicates whether the form is in a read-only state. If `true`, values cannot be modified.
   *
   * @default false
   */
  accessor readOnly: boolean;
  /** @internal */
  get selectedAttachment(): SelectedAttachmentIdentifier | null;
  /** @internal */
  get selectedAttachmentDetails(): SelectedAttachmentDetails | null;
  /**
   * The time zone used to interpret date values in the form. If this property is `null` or set to `"unknown"`, date values are displayed in the time zone specified by the layer's [FeatureLayer.preferredTimeZone](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#preferredTimeZone). If none is provided there, date values are interpreted in UTC.
   *
   * @see [FeatureLayer.preferredTimeZone](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#preferredTimeZone)
   * @see [View2D.timeZone](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#timeZone)
   */
  accessor timeZone: string | null | undefined;
  /** Indicates whether there are validation errors for any fields for any features. */
  get valid(): boolean;
  /**
   * The view model for this widget. This is a class that contains all the logic
   * (properties and methods) that controls this widget's behavior. See the
   * [BatchAttributeFormViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/BatchAttributeForm/BatchAttributeFormViewModel/) class to access
   * all properties and methods on the widget.
   */
  get viewModel(): BatchAttributeFormViewModel;
  set viewModel(value: BatchAttributeFormViewModelProperties);
  /** Defines which elements are visible in the widget. */
  get visibleElements(): VisibleElements;
  set visibleElements(value: VisibleElementsProperties);
  /**
   * Method for navigating back from nested pages. If there are no nested pages, this method does nothing.
   * NOTE: Method is async for future proofing.
   *
   * @internal
   */
  goBack(): Promise<void>;
  /**
   * Reset all nested views. This is similar to calling 'back()' until there are no more nested views.
   *
   * @internal
   */
  goHome(): Promise<void>;
  /** Focus the form on the first input element with an error. */
  goToFirstError(): void;
  /**
   * Used to specify an input to view associated layers for. This causes a list of associated layers to be displayed for the specified input.
   * The list is filtered further by the current active association type. Related to the 'viewing-associated-layers' page.
   *
   * @param input - A reference to the input to display associated layers for.
   * @internal
   */
  setActiveAssociationsInput(input: UtilityNetworkAssociationsElementInput | null | undefined): void;
  /**
   * Used to specify a layer to view associated features for. Causes a list of associated features to be displayed for the specified layer.
   * Related to the 'viewing-associated-features' page.
   *
   * @param layer - A reference to a specific layer.
   * @internal
   */
  setActiveAssociationsLayer(layer: AssociationsLayerUnion | null | undefined): void;
  /**
   * Used to filter the types of associations displayed in the 'viewing-associated-layers' page.
   *
   * @param type - A reference to a specific type of association.
   * @internal
   */
  setActiveAssociationType(type: UtilityNetworkAssociationType | null | undefined): void;
  /**
   * Usually, this is called when the user clicks a specified `submit` button or when the form is programmatically submitted and calls the [FeatureLayer.applyEdits()](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#applyEdits) method
   * to update the features' attributes.
   *
   * @returns Resolves after any pending attachment hydration completes and the `"submit"` event has been emitted.
   * @example
   * // Listen for when 'submit' is called on the form.
   * // Once it is fired, update the features.
   * form.on("submit", updateFeatures);
   * // When the DOM's button (btnUpdate) is clicked,
   * // execute the 'submit()' method.
   * document.getElementById("btnUpdate").addEventListener("click", () => form.submit());
   */
  submit(): Promise<void>;
}