import type Graphic from "../../Graphic.js";
import type Collection from "../../core/Collection.js";
import type Point from "../../geometry/Point.js";
import type ActionButton from "../../support/actions/ActionButton.js";
import type ActionToggle from "../../support/actions/ActionToggle.js";
import type { AbortOptions } from "../../core/promiseUtils.js";
import type { ClickEvent } from "../../views/input/types.js";

/** @since 5.0 */
export type PopupAction = ActionButton | ActionToggle;

/** @since 5.0 */
export type PopupPositionResult = "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";

/** @since 5.0 */
export type PopupPositionVariable = "auto" | "top-leading" | "top-trailing" | "bottom-leading" | "bottom-trailing";

/** @since 5.0 */
export type PopupPositionValue = PopupPositionVariable | PopupPositionResult;

/** @since 5.0 */
export type Alignment = PopupPositionValue | (() => PopupPositionValue);

/** @since 5.0 */
export type PopupDockPosition = PopupPositionValue | (() => PopupPositionValue);

/** @since 5.0 */
export interface ActionEvent {
  /**
   * The action clicked by the user. For a description
   * of this object and a specification of its properties, see the [Popup.actions](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#actions) property of this
   * class.
   *
   * @since 5.0
   */
  action: PopupAction;
}

/** @since 5.0 */
export interface DockOptionsBreakpoint {
  /**
   * The maximum width of the [View](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View.html)
   *                        at which the popup will be set to dockEnabled automatically.
   *
   * @default 544
   * @since 5.0
   */
  width?: number;
  /**
   * The maximum height of the [View](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View.html)
   *                        at which the popup will be set to dockEnabled automatically.
   *
   * @default 544
   * @since 5.0
   */
  height?: number;
}

/** @since 5.0 */
export interface DockOptions {
  /**
   * If `true`, displays the dock button. If `false`, hides the dock
   *                         button from the popup.
   *
   * @since 5.0
   */
  buttonEnabled?: boolean;
  /**
   * The position in the view at which to dock the popup.
   *                        Can be set as either a string or function. See the table below for known
   *                        string values and their position in the view based on the view's size.
   *                        <br><br>
   * Known Value | View size > breakpoint | View size < breakpoint ([at xsmall view breakpoint](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#breakpoints))
   * --------------- | ------------------------------- | -------------
   * auto | top-right | top-right
   * top-left | top-left | top-left
   * top-center | top-center | top 100%
   * top-right | top-right | top right
   * bottom-left | bottom-left | bottom left
   * bottom-center | bottom-center | bottom 100%
   * bottom-right | bottom-right | bottom right
   *
   * > [!WARNING]
   * >
   * > If viewing the popup in a mobile  UI, the default dock position is bottom 100%.
   *
   * @default auto
   * @since 5.0
   */
  position?: PopupDockPosition;
  /**
   * Defines the dimensions of the [View](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-View.html)
   *                        at which to dock the popup. Set to `false` to disable docking at a breakpoint.
   *
   * @default true
   * @since 5.0
   */
  breakpoint?: DockOptionsBreakpoint | boolean;
}

/** @since 5.0 */
export type InitialDisplayOptions = "list" | "feature";

/** @since 5.0 */
export interface PopupOpenOptions {
  /**
   * This property allows you to specify a collection of [actions](https://developers.arcgis.com/javascript/latest/api-reference/esri-support-actions-ActionButton.html)
   * to the action bar when the Features widget opens.
   *
   * @since 5.0
   */
  actions?: Collection<PopupAction>;
  /**
   * Sets the [Popup.content](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#content) of the popup.
   *
   * @since 5.0
   */
  content?: any;
  /**
   * Indicates whether the widget displays its content. If `true`, only the header displays.
   *
   * @default false
   * @since 5.0
   */
  collapsed?: boolean;
  /**
   * Sets the popup's [Popup.features](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#features), which populate the title and content of the popup based on each graphic's [PopupTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-PopupTemplate.html).
   *
   * @since 5.0
   */
  features?: Graphic[];
  /**
   * This property enables multiple features in a popup to display in a list rather than displaying the first selected feature. Setting this to `true`
   * allows the user to scroll through the list of features.
   * This value will only be honored if [PopupViewModel.initialDisplayMode](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup-PopupViewModel.html#initialDisplayMode) is set to `feature`.
   *
   * @default false
   * @since 5.0
   */
  featureMenuOpen?: boolean;
  /**
   * Sets the title to display on the widget while viewing the feature menu.
   *
   * @since 5.0
   */
  featureMenuTitle?: string;
  /**
   * When `true`, indicates the the content of this feature should be fetched and displayed. If no [PopupTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-PopupTemplate.html) exists, a default template is created for the layer if
   * [Popup.defaultPopupTemplateEnabled](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#defaultPopupTemplateEnabled) = `true`. In order for this option to work, there must be a valid `view` and `location` set.
   *
   * @default false
   * @since 5.0
   */
  fetchFeatures?: boolean;
  /**
   * Sets the popup's [Popup.location](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#location), which is the geometry used to position the popup.
   *
   * @since 5.0
   */
  location?: Point;
  /**
   * Sets pending [Popup.promises](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#promises) on the popup. The popup will display once the promises resolve. Each promise must resolve to an array of [Graphics](https://developers.arcgis.com/javascript/latest/api-reference/esri-Graphic.html).
   *
   * @since 5.0
   */
  promises?: Promise<any>[];
  /**
   * Sets the [Popup.title](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#title) of the popup.
   *
   * @since 5.0
   */
  title?: string;
  /**
   * When `true`, indicates the popup should update its [Popup.location](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#location) for each paginated feature based on the [selectedFeature's](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#selectedFeature) geometry.
   *
   * @default false
   * @since 5.0
   */
  updateLocationEnabled?: boolean;
  /**
   * When `true`, indicates that the focus should be on the popup after it has been opened.
   *
   * @default false
   * @since 5.0
   */
  shouldFocus?: boolean;
}

/** @since 5.0 */
export type State = "disabled" | "ready";

/**
 * Optional properties to use with the [Features.fetchFeatures()](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Features.html#fetchFeatures) and [Popup.fetchFeatures()](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Popup.html#fetchFeatures) methods.
 *
 * @since 5.0
 */
export interface FetchFeaturesOptions extends AbortOptions {
  /**
   * The `click` event for either the [MapView](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html) or [SceneView](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-SceneView.html).
   * The event can be supplied in order to adjust the query radius depending on the pointer type. For example, touch events query a larger radius.
   *
   * @since 5.0
   */
  event?: ClickEvent;
}