import type Widget from "./Widget.js";
import type ExpandViewModel from "./Expand/ExpandViewModel.js";
import type { Icon } from "@esri/calcite-components/components/calcite-icon";
import type { MapViewOrSceneView } from "../views/MapViewOrSceneView.js";
import type { DomNodeOwner } from "./types.js";
import type { WidgetProperties } from "./Widget.js";
import type { ExpandViewModelProperties } from "./Expand/ExpandViewModel.js";

export interface ExpandProperties extends WidgetProperties, Partial<Pick<Expand, "autoCollapse" | "closeOnEsc" | "collapseTooltip" | "content" | "expanded" | "expandTooltip" | "focusTrapDisabled" | "group" | "iconNumber" | "mode" | "placement" | "view">> {
  /**
   * Calcite icon used to style the Expand button when the [content](https://developers.arcgis.com/javascript/latest/references/core/widgets/Expand/#content) can be collapsed.
   *
   * @default "chevrons-right"
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  collapseIcon?: Icon["icon"] | null;
  /**
   * Calcite icon used when the widget is collapsed.
   * Will automatically use the [content's](https://developers.arcgis.com/javascript/latest/references/core/widgets/Expand/#content) icon if it has one.
   *
   * @default "chevrons-left"
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  expandIcon?: 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
   * [ExpandViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/Expand/ExpandViewModel/) class to access
   * all properties and methods on the widget.
   */
  viewModel?: ExpandViewModelProperties;
}

export type ExpandContent = string | HTMLElement | Widget | DomNodeOwner;

/**
 * The Expand widget acts as a clickable button for displaying interactive content, most commonly other widgets.
 *
 * > [!WARNING]
 * >
 * > If adding a [Slider](https://developers.arcgis.com/javascript/latest/references/core/widgets/Slider/), [HistogramRangeSlider](https://developers.arcgis.com/javascript/latest/references/core/widgets/HistogramRangeSlider/),
 * > or [TimeSlider](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/) as [content](https://developers.arcgis.com/javascript/latest/references/core/widgets/Expand/#content) to the Expand widget, the container
 * > or parent container of the widget must have a `width` set in css for it to render inside the Expand widget.
 * >
 * > If setting the width on the slider's container, then set the `slider.container` as the content of the
 * > expand rather than the slider itself.
 * >
 * > `expand.content = slider.container`
 *
 * @deprecated since version 4.34. Use the [Expand component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-expand/) 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.3
 * @see [Samples with the Expand widget](https://developers.arcgis.com/javascript/latest/sample-code/?tagged=Expand)
 * @see [ExpandViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/Expand/ExpandViewModel/)
 * @see [DefaultUI](https://developers.arcgis.com/javascript/latest/references/core/views/ui/DefaultUI/)
 * @example
 * // LayerList
 * const layerList = new LayerList({
 *   container: document.createElement("div"),
 *   view: view
 * });
 * const layerListExpand = new Expand({
 *   expandIcon: "layers",  // see https://developers.arcgis.com/calcite-design-system/icons/
 *   // expandTooltip: "Expand LayerList", // optional, defaults to "Expand" for English locale
 *   view: view,
 *   content: layerList
 * });
 * view.ui.add(layerListExpand, "top-right");
 */
export default class Expand extends Widget {
  constructor(properties?: ExpandProperties);
  /**
   * Automatically collapses the expand widget instance when the view's
   * [viewpoint](https://developers.arcgis.com/javascript/latest/references/core/views/View2D/#viewpoint) updates.
   *
   * @default false
   */
  accessor autoCollapse: boolean;
  /**
   * When true, the Expand widget will close after the Escape key is pressed when the keyboard focus is within its content.
   * This property can also be set to a function that returns a boolean, allowing for more customization for when to allow the Expand widget
   * to be closed from the `esc` key.
   *
   * @default true
   * @example
   * let expand = new Expand({
   *    view: view,
   *    content: search,
   *    // widget will not be able to be closed from the ESC key
   *    closeOnEsc: false
   * });
   * @example
   * let expand = new Expand({
   *    view: view,
   *    content: search,
   *    // widget will close on ESC when Search has no active menu
   *    closeOnEsc: function() {
   *      return search.activeMenu === "none"
   *    }
   * });
   */
  accessor closeOnEsc: boolean | ((event: KeyboardEvent) => boolean);
  /**
   * Calcite icon used to style the Expand button when the [content](https://developers.arcgis.com/javascript/latest/references/core/widgets/Expand/#content) can be collapsed.
   *
   * @default "chevrons-right"
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  get collapseIcon(): Icon["icon"];
  set collapseIcon(value: Icon["icon"] | null | undefined);
  /**
   * Tooltip to display to indicate Expand widget can be collapsed.
   * If not provided, the widget will use "Collapse" (or equivalent in
   * non-English locales).
   *
   * @default ""
   */
  accessor collapseTooltip: string;
  /**
   * The content to display within the expanded Expand widget.
   *
   * > [!WARNING]
   * >
   * > If adding a [Slider](https://developers.arcgis.com/javascript/latest/references/core/widgets/Slider/), [HistogramRangeSlider](https://developers.arcgis.com/javascript/latest/references/core/widgets/HistogramRangeSlider/),
   * > or [TimeSlider](https://developers.arcgis.com/javascript/latest/references/core/widgets/TimeSlider/) as content to the Expand widget, the container
   * > or parent container of the widget must have a `width` set in css for it to render inside the Expand widget.
   * >
   * > If setting the width on the slider's container (rather than a parent container), then set the
   * > `slider.container` as the content of the expand rather than the slider itself.
   * >
   * > `expand.content = slider.container`
   *
   * @default ""
   * @example
   * // A. specify content with a widget
   *    let searchWidget = new Search({
   *      view: view
   *    });
   *
   *    let expand = new Expand({
   *      expandIcon: "search",
   *      view: view,
   *      content: searchWidget
   *    });
   *    view.ui.add(expand, "bottom-left");
   * @example
   * // B. specify content with a string (of HTML)
   *    content: "Hi, I can have <input placeholder='HTML'/>!"
   * @example
   * // C. specify content with a DOM node
   *    let node = domConstruct.create("div", {
   *      innerHTML: "I'm a real node!"
   *    });
   *
   *    let expand = new Expand({
   *      expandIcon: "arrow-right",
   *      view: view,
   *      content: node
   *    });
   *    view.ui.add(expand, "top-right");
   */
  accessor content: ExpandContent;
  /**
   * Indicates whether the widget is currently expanded or not.
   *
   * @default false
   */
  accessor expanded: boolean;
  /**
   * Calcite icon used when the widget is collapsed.
   * Will automatically use the [content's](https://developers.arcgis.com/javascript/latest/references/core/widgets/Expand/#content) icon if it has one.
   *
   * @default "chevrons-left"
   * @since 4.27
   * @see [Calcite Icon Search](https://developers.arcgis.com/calcite-design-system/icons/)
   */
  get expandIcon(): Icon["icon"];
  set expandIcon(value: Icon["icon"] | null | undefined);
  /**
   * Tooltip to display to indicate Expand widget can be expanded.
   * If not provided, the widget will use "Expand" (or equivalent in
   * non-English locales).
   *
   * @default ""
   */
  accessor expandTooltip: string;
  /**
   * Disables focus trapping within the expand widget.
   *
   * @default false
   * @since 4.32
   */
  accessor focusTrapDisabled: boolean;
  /**
   * This value associates two or more Expand widget instances with each other, allowing one
   * instance to auto collapse when another instance in the same group is expanded. For auto collapsing
   * to take effect, all instances of the group must be included in the view's `ui` property.
   *
   * For example, if you place multiple Expand instances in the top-left of the view's ui, you can assign them to a
   * group called `top-left`. If one Expand instance is expanded and the user clicks on a different instance in the
   * `top-left` group, then the first instance is collapsed, allowing the content of the second instance to be
   * fully visible.
   *
   * @since 4.6
   * @example
   * let expand1 = new Expand({
   *   view: view,
   *   content: document.getElementById("bg-gallery"),
   *   expandIcon: "basemap",
   *   group: "bottom-right"
   * });
   * let expand2 = new Expand({
   *   view: view,
   *   content: document.getElementById("legend"),
   *   expandIcon: "key",
   *   group: "bottom-right"
   * });
   *
   * view.ui.add([expand1, expand2], "bottom-right");
   */
  accessor group: string | null | undefined;
  /**
   * A number to display at the corner of the widget to indicate the number of, for example, open issues or unread notices.
   *
   * ![expand widget icon number](https://developers.arcgis.com/javascript/latest/assets/img/apiref/widgets/expand-with-iconnumber.png)
   *
   * @default 0
   */
  accessor iconNumber: number;
  /**
   * The widget's default label.
   *
   * @since 4.11
   */
  get label(): string;
  set label(value: string | null | undefined);
  /**
   * The mode in which the widget displays. These modes are listed below.
   *
   * mode | description
   * ---------------|------------
   * auto | This is the default mode. It is responsive to browser size changes and will update based on whether the widget is viewed in a desktop or mobile application.
   * floating | Use this mode if you wish to always display the widget as floating regardless of browser size.
   * drawer | Use this mode if you wish to always display the widget in a panel regardless of browser size.
   *
   * @default "auto"
   * @since 4.7
   */
  accessor mode: "auto" | "floating" | "drawer";
  /**
   * The placement used by the [calcite popover](https://developers.arcgis.com/calcite-design-system/components/popover/) when the widget is expanded.
   *
   * @since 4.30
   */
  accessor placement: "auto" | "auto-start" | "auto-end" | "top" | "top-start" | "top-end" | "bottom" | "bottom-start" | "bottom-end" | "right" | "right-start" | "right-end" | "left" | "left-start" | "left-end" | "leading-start" | "leading" | "leading-end" | "trailing-end" | "trailing" | "trailing-start" | null | undefined;
  /** A reference to the [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/) or [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/). Set this to link the widget to a specific view. */
  accessor view: MapViewOrSceneView | 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
   * [ExpandViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/Expand/ExpandViewModel/) class to access
   * all properties and methods on the widget.
   */
  get viewModel(): ExpandViewModel;
  set viewModel(value: ExpandViewModelProperties);
  /** Collapse the widget. */
  collapse(): void;
  /** Expand the widget. */
  expand(): void;
  /** Toggle the widget by expanding it if it's collapsed, or collapsing it if it's expanded. */
  toggle(): void;
}