import type Widget from "./Widget.js";
import type FeatureTemplatesViewModel from "./FeatureTemplates/FeatureTemplatesViewModel.js";
import type TemplateItem from "./FeatureTemplates/TemplateItem.js";
import type VisibleElements from "./FeatureTemplates/VisibleElements.js";
import type { Icon } from "@esri/calcite-components/components/calcite-icon";
import type { FeatureTemplatesViewModelEvents, FeatureTemplatesViewModelProperties } from "./FeatureTemplates/FeatureTemplatesViewModel.js";
import type { Filter, GroupByType } from "./FeatureTemplates/types.js";
import type { HeadingLevel } from "./support/types.js";
import type { VisibleElementsProperties } from "./FeatureTemplates/VisibleElements.js";
import type { WidgetProperties } from "./Widget.js";

export interface FeatureTemplatesProperties extends WidgetProperties, Partial<Pick<FeatureTemplates, "disabled" | "enableListScroll" | "filterFunction" | "filterText" | "groupBy" | "headingLevel" | "layers" | "selectionMode">> {
  /**
   * Icon displayed in the widget's button.
   *
   * @default "list-rectangle"
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  icon?: Icon["icon"] | null;
  /**
   * The widget's default label.
   *
   * @since 4.11
   */
  label?: string | 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
   * [FeatureTemplatesViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/FeatureTemplatesViewModel/) class to access
   * all properties and methods on the widget.
   */
  viewModel?: FeatureTemplatesViewModelProperties;
  /**
   * The visible elements that are displayed within the widget.
   * This property provides the ability to turn individual elements of the widget's display on/off.
   *
   * ![featureTemplatesFilter](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/featureTemplatesFilter.png)
   *
   * @since 4.15
   * @example
   * featureTemplates.visibleElements = {
   *    filter: false
   * };
   */
  visibleElements?: VisibleElementsProperties;
}

export interface FeatureTemplatesEvents extends FeatureTemplatesViewModelEvents {}

/**
 * The FeatureTemplates widget is part of the overall editing workflow. Its main purpose is to display
 * [FeatureLayer.templates](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#templates) from one or more [feature layers](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/).
 * In addition to displaying feature layer templates, it is also possible to [filter](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/#filterFunction) and [group](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/#groupBy) templates
 * for an easier editing experience. The widget listens for an end user to select a specific [template](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItem/)
 * in the widget. Its [@select](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/#event-select)
 * event is fired and the resulting template information is returned. This widget can be used in conjunction with
 * [FeatureLayer.applyEdits()](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#applyEdits) to enable an end user to
 * update one of its feature layers.
 *
 * [![featureTemplates](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/featureTemplates.png)](https://developers.arcgis.com/javascript/latest/sample-code/editing-applyedits/)
 *
 * @deprecated since version 5.0. Use the [Feature Templates (Legacy)](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-feature-templates-legacy/) component 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.10
 * @see [Sample - Update FeatureLayer using ApplyEdits](https://developers.arcgis.com/javascript/latest/sample-code/editing-applyedits/)
 * @see [FeatureTemplatesViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/FeatureTemplatesViewModel/)
 * @see [TemplateItem](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItem/)
 * @see [TemplateItemGroup](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItemGroup/)
 * @see [DefaultUI](https://developers.arcgis.com/javascript/latest/references/core/views/ui/DefaultUI/)
 * @see [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/)
 * @see [FeatureTemplate](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FeatureTemplate/)
 * @example
 * const templates = new FeatureTemplates({
 *   container: "templatesDiv",
 *   layers: layers
 * });
 */
export default class FeatureTemplates extends Widget {
  /**
   * @deprecated
   * Do not directly reference this property.
   * Use EventNames and EventTypes helpers from \@arcgis/core/Evented
   */
  "@eventTypes": FeatureTemplatesEvents;
  /**
   * @example
   * // Typical usage
   * const templates = new FeatureTemplates({
   *   container: "templatesDiv",
   *   layers: layers
   * });
   */
  constructor(properties?: FeatureTemplatesProperties);
  /**
   * Used to disable the widget user interface. This does not prevent the widget or
   * view model from functioning programmatically. Methods invoked programmatically
   * still work as expected.
   *
   * @default false
   * @since 4.28
   */
  accessor disabled: boolean;
  /**
   * Indicates whether the list of available feature [template items](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItem/) should scroll within its containing element.
   *
   * @default true
   * @since 4.28
   */
  accessor enableListScroll: boolean;
  /**
   * [function](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/types/#Filter) can be defined to help filter
   * [template items](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItem/) within the widget.
   * A custom function can be used to aid when searching for templates. It takes a function which passes in
   * an object containing a [name](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItem/#label)
   * property of the [template item](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItem/).
   *
   * ![featureTemplatesFilterFunction](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/featureTemplatesFilterFunction.png)
   *
   * @example
   * // Filter and display templates only if their labels contain the word `Street`
   * function myFilterFunction(filter) {
   *   let containsName = filter.label.includes("Street");
   *   return containsName;
   * }
   *
   * // Create the FeatureTemplates widget
   * templates = new FeatureTemplates({
   *   container: "templatesDiv",
   *   visibleElements: {
   *     filter: false, // disable the default filter UI
   *   },
   *   layers: [featureLayer], // in this example, one layer is used
   *   filterFunction: myFilterFunction
   * });
   */
  accessor filterFunction: Filter | null | undefined;
  /**
   * Text used to filter items.
   *
   * @default ""
   */
  accessor filterText: string;
  /**
   * It is possible to group [template items](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItem/). This can aid
   * in managing various template items and how they display within the widget. The values are discussed below.
   *
   * Type | Description | Example
   * ----- | ----------- | -------
   * layer | This is the *default* grouping. Groups template items by layers. | ![featureTemplatesGroupByLayer](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/groupByLayers.png)
   * geometry | Groups template items by geometry type. | ![FeatureTemplatesGroupByGeometry](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/groupByGeometry.png)
   * none | The widget displays everything in one list with no grouping. | ![featureTemplatesGroupByLayer](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/groupByNone.png)
   * [GroupByFunction](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/types/#GroupByFunction) | Custom function that takes an object containing a [FeatureTemplate](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FeatureTemplate/) and [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/). | ![FeatureTemplatesGroupByCustomGroupFunction](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/groupCustomGroup.png)
   *
   * @default "layer"
   * @example
   * // This example shows using a function to check if
   * // the layer title contains the word 'military'. If so,
   * // return a group of items called "All Military Templates"
   * function customGroup(grouping) {
   *   // Consolidate all military layers
   *   if (grouping.layer.title.toLowerCase().indexOf("military") > -1) {
   *     return "All Military Templates"
   *   }
   * // Otherwise, group by layer title
   *   return grouping.layer.title;
   * }
   *
   * // Create the FeatureTemplates widget
   * templates = new FeatureTemplates({
   *   container: "templatesDiv",
   *   layers: layers,
   *   groupBy: customGroup
   * });
   */
  accessor groupBy: GroupByType | null | undefined;
  /**
   * Indicates the heading level to use for the labels of grouped feature templates.
   * By default, the group label is rendered
   * as a level 4 heading (e.g. `<h4>Group label</h4>`). 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 4
   * @since 4.20
   * @see [Heading Elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Heading_Elements)
   * @example
   * // Group label will render as an <h3>
   * featureTemplates.headingLevel = 3;
   */
  accessor headingLevel: HeadingLevel;
  /**
   * Icon displayed in the widget's button.
   *
   * @default "list-rectangle"
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  get icon(): Icon["icon"];
  set icon(value: Icon["icon"] | null | undefined);
  /**
   * The widget's default label.
   *
   * @since 4.11
   */
  get label(): string;
  set label(value: string | null | undefined);
  /**
   * An array of [FeatureLayers](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/)
   * to display within the widget. The order in which these layers are
   * set in the array dictates how they display within the widget.
   *
   * > [!WARNING]
   * >
   * > The widget is designed to only display layers that are enabled for editing.
   * > It will not display layers that are enabled to only edit attributes.
   *
   * @example
   * // The layers to display within the widget
   * let militaryUnits = new FeatureLayer({
   *   url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/FeatureServer/2"
   * });
   *
   * let militaryHostile = new FeatureLayer({
   *   url: "http://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/FeatureServer/6"
   * });
   *
   * let layers = [militaryUnits, militaryHostile];
   *
   * // Create FeatureTemplates widget
   * templates = new FeatureTemplates({
   *   container: "templatesDiv",
   *   layers: layers
   * });
   */
  accessor layers: FeatureTemplatesViewModel["layers"];
  /**
   * Specifies the selection behavior of list items. The `"single"` selection mode keeps the clicked list item selected. Whereas, `"none"` does not preserve the selection after clicking the list item.
   *
   * @default "none"
   * @since 4.28
   */
  accessor selectionMode: "single" | "none" | null | undefined;
  /**
   * 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
   * [FeatureTemplatesViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/FeatureTemplatesViewModel/) class to access
   * all properties and methods on the widget.
   */
  get viewModel(): FeatureTemplatesViewModel;
  set viewModel(value: FeatureTemplatesViewModelProperties);
  /**
   * The visible elements that are displayed within the widget.
   * This property provides the ability to turn individual elements of the widget's display on/off.
   *
   * ![featureTemplatesFilter](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/featureTemplatesFilter.png)
   *
   * @since 4.15
   * @example
   * featureTemplates.visibleElements = {
   *    filter: false
   * };
   */
  get visibleElements(): VisibleElements;
  set visibleElements(value: VisibleElementsProperties);
  /**
   * Selects the [template item](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItem/) to use.
   *
   * @param item - The [template item](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/TemplateItem/) to select.
   * @see [select event](https://developers.arcgis.com/javascript/latest/references/core/widgets/FeatureTemplates/#event-select)
   */
  select(item: TemplateItem | null | undefined): void;
}