import type Basemap from "../Basemap.js";
import type Widget from "./Widget.js";
import type BasemapToggleViewModel from "./BasemapToggle/BasemapToggleViewModel.js";
import type { Icon } from "@esri/calcite-components/components/calcite-icon";
import type { BasemapProperties } from "../Basemap.js";
import type { MapViewOrSceneView } from "../views/MapViewOrSceneView.js";
import type { WidgetProperties } from "./Widget.js";
import type { BasemapToggleViewModelProperties } from "./BasemapToggle/BasemapToggleViewModel.js";

export interface BasemapToggleProperties extends WidgetProperties, Partial<Pick<BasemapToggle, "view" | "visibleElements">> {
  /**
   * Icon which represents the widget. It is typically used when the widget is controlled by another
   * one (e.g. in the Expand widget).
   *
   * @default "layer-basemap"
   * @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 next basemap for toggling. One of the following values may be set to this property:
   *
   * * The [string ID](https://developers.arcgis.com/javascript/latest/references/core/Map/#basemap) of any Esri basemap.
   * * A custom [Basemap](https://developers.arcgis.com/javascript/latest/references/core/Basemap/) object.
   */
  nextBasemap?: BasemapProperties | 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
   * [BasemapToggleViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/BasemapToggle/BasemapToggleViewModel/) class to access
   * all properties and methods on the widget.
   */
  viewModel?: BasemapToggleViewModelProperties;
}

/**
 * The visible elements that are displayed within the widget.
 * This provides the ability to turn individual elements of the widget's display on/off.
 */
export interface VisibleElements {
  /** Indicates whether to the title will be displayed. Default is `false`. */
  title?: boolean;
}

/**
 * The BasemapToggle provides a widget which allows an end-user to switch between
 * two basemaps. The toggled basemap is set inside the [view's](https://developers.arcgis.com/javascript/latest/references/core/widgets/BasemapToggle/#view)
 * [View.map](https://developers.arcgis.com/javascript/latest/references/core/views/View/#map) object.
 *
 * ![basemap-toggle](https://developers.arcgis.com/javascript/latest/assets/references/core/widgets/basemap-toggle.png)
 *
 * Starting with version 4.23, the BasemapToggle widget can have two basemaps with different spatial references.
 * Set the [MapView.spatialReferenceLocked](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#spatialReferenceLocked) property to `true`
 * to disable basemaps in different spatial references and prevent users from changing the view's spatial reference at runtime.
 *
 * @deprecated since version 4.32. Use the [Basemap Toggle component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-basemap-toggle/) 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.0
 * @see [BasemapToggleViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/BasemapToggle/BasemapToggleViewModel/)
 * @example
 * // Create a map with an initial basemap
 * let map = new Map({
 *   basemap: "streets-vector",  // The initial basemap to toggle from
 *   ground: "world-elevation"
 * });
 *
 * // Reference the map in the view instance
 * let view = new SceneView({
 *   container: "viewDiv",
 *   map: map
 * });
 *
 * let basemapToggle = new BasemapToggle({
 *   view: view,  // The view that provides access to the map's "streets-vector" basemap
 *   nextBasemap: "hybrid"  // Allows for toggling to the "hybrid" basemap
 * });
 */
export default class BasemapToggle extends Widget {
  /**
   * @example
   * // typical usage
   * let basemapToggle = new BasemapToggle({
   *   view: view,
   *   nextBasemap: "satellite"
   * });
   */
  constructor(properties?: BasemapToggleProperties);
  /** The map's [Map.basemap](https://developers.arcgis.com/javascript/latest/references/core/Map/#basemap). */
  get activeBasemap(): Basemap | null | undefined;
  /**
   * Icon which represents the widget. It is typically used when the widget is controlled by another
   * one (e.g. in the Expand widget).
   *
   * @default "layer-basemap"
   * @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);
  /**
   * The next basemap for toggling. One of the following values may be set to this property:
   *
   * * The [string ID](https://developers.arcgis.com/javascript/latest/references/core/Map/#basemap) of any Esri basemap.
   * * A custom [Basemap](https://developers.arcgis.com/javascript/latest/references/core/Basemap/) object.
   */
  get nextBasemap(): Basemap | null | undefined;
  set nextBasemap(value: BasemapProperties | string | 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/). This view
   * provides the BasemapToggle widget with access to the initial
   * [Map.basemap](https://developers.arcgis.com/javascript/latest/references/core/Map/#basemap) to toggle from
   * via the view's [View.map](https://developers.arcgis.com/javascript/latest/references/core/views/View/#map) property.
   */
  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
   * [BasemapToggleViewModel](https://developers.arcgis.com/javascript/latest/references/core/widgets/BasemapToggle/BasemapToggleViewModel/) class to access
   * all properties and methods on the widget.
   */
  get viewModel(): BasemapToggleViewModel;
  set viewModel(value: BasemapToggleViewModelProperties);
  /**
   * 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.
   *
   * @since 4.15
   * @example
   * basemapToggle.visibleElements = {
   *   title: false
   * };
   */
  accessor visibleElements: VisibleElements;
  /**
   * Toggles to the [next basemap](https://developers.arcgis.com/javascript/latest/references/core/widgets/BasemapToggle/#nextBasemap).
   *
   * @returns Resolves after the widget has toggled to the next basemap.
   */
  toggle(): Promise<void>;
}