import type Collection from "../../core/Collection.js";
import type ListItem from "./ListItem.js";
import type { EventedAccessor } from "../../core/Evented.js";
import type { MapViewOrSceneView } from "../../views/MapViewOrSceneView.js";
import type { Action, ListItemModifier, State } from "./types.js";

export interface LayerListViewModelProperties extends Partial<Pick<LayerListViewModel, "checkPublishStatusEnabled" | "listItemCreatedFunction" | "listModeDisabled" | "view">> {}

export interface LayerListViewModelEvents {
  /**
   * Emitted when the user clicks an [action](https://developers.arcgis.com/javascript/latest/references/core/support/actions/ActionButton/) or
   * [action toggle](https://developers.arcgis.com/javascript/latest/references/core/support/actions/ActionToggle/) in a layer list.
   * Use this event to run custom logic when a specific action is triggered.
   *
   * @see [BasemapLayerList.@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/BasemapLayerList/#event-trigger-action)
   * @see [CatalogLayerList.@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/CatalogLayerList/#event-trigger-action)
   * @see [CatalogLayerListViewModel.@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/CatalogLayerList/CatalogLayerListViewModel/#event-trigger-action)
   * @see [LayerList.@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/#event-trigger-action)
   * @see [@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/LayerListViewModel/#event-trigger-action)
   */
  "trigger-action": LayerListViewModelTriggerActionEvent;
}

/**
 * The event object for the `trigger-action` event in the layer lists.
 *
 * @see [BasemapLayerList.@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/BasemapLayerList/#event-trigger-action)
 * @see [CatalogLayerList.@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/CatalogLayerList/#event-trigger-action)
 * @see [CatalogLayerListViewModel.@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/CatalogLayerList/CatalogLayerListViewModel/#event-trigger-action)
 * @see [LayerList.@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/#event-trigger-action)
 * @see [@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/LayerListViewModel/#event-trigger-action)
 */
export interface LayerListViewModelTriggerActionEvent {
  /** The action that was clicked by the user. */
  action: Action;
  /** The list item associated with the action. */
  item: ListItem;
}

/**
 * Provides the logic for the [LayerList](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/) widget and [component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-layer-list/).
 * To hide layers in the map from the LayerList widget, set the
 * [Layer.listMode](https://developers.arcgis.com/javascript/latest/references/core/layers/Layer/#listMode) property on the layer(s) to `hide`.
 *
 * @since 4.2
 * @see [LayerList](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/) widget
 * @see [Layer List component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-layer-list/)
 * @see [Programming patterns: Widget viewModel pattern](https://developers.arcgis.com/javascript/latest/programming-patterns/#widget-viewmodel-pattern)
 */
export default class LayerListViewModel extends EventedAccessor {
  /**
   * @deprecated
   * Do not directly reference this property.
   * Use EventNames and EventTypes helpers from \@arcgis/core/Evented
   */
  "@eventTypes": LayerListViewModelEvents;
  constructor(properties?: LayerListViewModelProperties);
  /**
   * Whether to provide an indication if a layer is being published in the
   * [LayerList](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/). When a layer is publishing,
   * a rotating square will appear to the right of the list item title.
   * The [ListItem.publishing](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/ListItem/#publishing) property
   * will be `false` if `checkPublishStatusEnabled` is `false`.
   *
   * @default false
   * @since 4.25
   */
  accessor checkPublishStatusEnabled: boolean;
  /**
   * Specifies a function that accesses each [ListItem](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/ListItem/).
   * Each list item can be modified according to its modifiable properties.
   * Actions can be added to list items using the
   * [ListItem.actionsSections](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/ListItem/#actionsSections) property.
   *
   * @since 4.4
   * @example
   * layerListViewModel.listItemCreatedFunction = function (event) {
   *
   *    // The event object contains properties of the
   *    // layer in the LayerList widget.
   *    const { item } = event;
   *
   *    if (item.title === "US Demographics") {
   *      // open the list item in the LayerList
   *      item.open = true;
   *      // change the title to something more descriptive
   *      item.title = "Population by county";
   *      // set an action for zooming to the full extent of the layer
   *      item.actionsSections = [[{
   *        title: "Go to full extent",
   *        className: "esri-icon-zoom-out-fixed",
   *        id: "full-extent"
   *      }]];
   *    }
   * });
   */
  accessor listItemCreatedFunction: ListItemModifier | null | undefined;
  /**
   * Specifies whether to ignore the [Layer.listMode](https://developers.arcgis.com/javascript/latest/references/core/layers/Layer/#listMode) property to display all layers.
   * A common use case for `listModeDisabled` is when you want to use the
   * [LayerList](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/) to manage and configure a layer's `listMode` value.
   *
   * @default false
   * @since 4.30
   * @see [Layer.listMode](https://developers.arcgis.com/javascript/latest/references/core/layers/Layer/#listMode)
   */
  accessor listModeDisabled: boolean;
  /**
   * A collection of [ListItem](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/ListItem/)s representing operational layers.
   * To hide layers from the LayerList widget, set the
   * [Layer.listMode](https://developers.arcgis.com/javascript/latest/references/core/layers/Layer/#listMode) property to `hide`.
   *
   * @see [Layer.listMode](https://developers.arcgis.com/javascript/latest/references/core/layers/Layer/#listMode)
   */
  get operationalItems(): Collection<ListItem>;
  /**
   * The view model's state.
   *
   * @default "disabled"
   */
  get state(): State;
  /** The view from which the widget will operate. */
  accessor view: MapViewOrSceneView | null | undefined;
  /**
   * Moves a list item from one position to another in the LayerList widget. This allows the user to reorder the operational layers in a
   * map or even reorganize sublayers of [GroupLayers](https://developers.arcgis.com/javascript/latest/references/core/layers/GroupLayer/). You cannot move
   * [MapImageLayer sublayers](https://developers.arcgis.com/javascript/latest/references/core/layers/MapImageLayer/#sublayers) outside of a MapImageLayer.
   *
   * For the purposes of the documentation below, an item (or list item) refers to a layer in a map.
   * A parent item refers to a GroupLayer or MapImageLayer, and a child item refers to a sublayer of a GroupLayer or MapImageLayer.
   *
   * @param targetItem - The list item (or layer) to move.
   * @param fromParentItem - If the `targetItem` is a child of a parent list item and you want to move it out of the parentItem, then use this parameter to indicate the parent item to move from.
   * @param toParentItem - The parent list item to move the `targetItem` to if moving it as a child to another parent item.
   * @param newIndex - The new index to move the `targetItem` to. If moving the item as a child to a parent item, then specify the index of the item within that parent.
   * @since 4.16
   * @example
   * // Moves the first layer to the final position in the map
   * const viewModel = layerList.viewModel;
   * const item = layerList.operationalItems.at(0);
   * const lastIndex = layerList.operationalItems.length - 1;
   *
   * viewModel.moveListItem(item, null, null, lastIndex);
   * @example
   * // Moves the first sublayer in the first group layer
   * // to the first position in the second group layer
   * const viewModel = layerList.viewModel;
   * const parentItem1 = layerList.operationalItems.at(0);
   * const subItem1 = parentItem1.children.at(0);
   * const parentItem2 = layerList.operationalItems.at(1);
   *
   * viewModel.moveListItem(subItem1, parentItem1, parentItem2, 0);
   */
  moveListItem(targetItem: ListItem | null | undefined, fromParentItem: ListItem | null | undefined, toParentItem: ListItem | null | undefined, newIndex: number): void;
  /**
   * Triggers the [@trigger-action](https://developers.arcgis.com/javascript/latest/references/core/widgets/LayerList/LayerListViewModel/#event-trigger-action) event and executes
   * the given [action](https://developers.arcgis.com/javascript/latest/references/core/support/actions/ActionButton/) or [action toggle](https://developers.arcgis.com/javascript/latest/references/core/support/actions/ActionToggle/).
   *
   * @param action - The action to execute.
   * @param item - An item associated with the action.
   */
  triggerAction(action: Action, item: ListItem): void;
}