import type Graphic from "../../Graphic.js";
import type Collection from "../../core/Collection.js";
import type GraphicsLayer from "../../layers/GraphicsLayer.js";
import type LayerView from "./LayerView.js";
import type HighlightOptions from "../support/HighlightOptions.js";
import type { ResourceHandle } from "../../core/Handles.js";
import type { ObjectId } from "../types.js";
import type { LayerViewHighlightOptions } from "./types.js";
import type { HighlightOptionsProperties } from "../support/HighlightOptions.js";

/**
 * Represents the [LayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/LayerView/) of a [GraphicsLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GraphicsLayer/)
 * after it has been added to a [Map](https://developers.arcgis.com/javascript/latest/references/core/Map/) in either a [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/) or
 * [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
 *
 * The [GraphicsLayerView](https://developers.arcgis.com/javascript/latest/references/core/views/layers/GraphicsLayerView/) is responsible for rendering a [GraphicsLayer's](https://developers.arcgis.com/javascript/latest/references/core/layers/GraphicsLayer/)
 * features as [graphics](https://developers.arcgis.com/javascript/latest/references/core/Graphic/) in the [View](https://developers.arcgis.com/javascript/latest/references/core/views/View/). The interface provides the
 * `queryGraphics()` method so developers can query graphics in the view. See the method documentation below for
 * examples of how to access client-side graphics from the view.
 *
 * @since 4.4
 * @see [GraphicsLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GraphicsLayer/)
 */
export default abstract class GraphicsLayerView extends LayerView {
  /**
   * Options for configuring the highlight. Use the [FeatureLikeLayerView.highlight()](https://developers.arcgis.com/javascript/latest/references/core/views/layers/FeatureLikeLayerView/#highlight) method on the layer view to highlight a feature
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > The `highlightOptions` on layer views are only supported in [2D MapViews](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/). To
   * > configure highlights for a [3D SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/), use
   * > [SceneView.highlights](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#highlights) instead.
   *
   * @deprecated since version 4.34. Use the [View.highlights](https://developers.arcgis.com/javascript/latest/references/core/views/View/#highlights) property instead.
   * @since 4.26
   * @see [highlight()](https://developers.arcgis.com/javascript/latest/references/core/views/layers/FeatureLikeLayerView/#highlight)
   * @see [Sample: Highlight SceneLayer](https://developers.arcgis.com/javascript/latest/sample-code/highlight-scenelayer/)
   * @example
   * ```js
   * // Features in the layerview will be highlighted with bright
   * // yellow colors in the map.
   * const layerView = await view.whenLayerView(layer);
   * layerView.highlightOptions = {
   *   color: [255, 255, 0, 1],
   *   haloOpacity: 0.9,
   *   fillOpacity: 0.2
   * };
   * ```
   */
  get highlightOptions(): HighlightOptions | null | undefined;
  set highlightOptions(value: HighlightOptionsProperties | null | undefined);
  /** The layer being viewed. */
  get layer(): GraphicsLayer;
  /**
   * Highlights the given feature(s) in a layer view using the named [HighlightOptions](https://developers.arcgis.com/javascript/latest/references/core/views/support/HighlightOptions/)
   * from the view's [View.highlights](https://developers.arcgis.com/javascript/latest/references/core/views/View/#highlights) collection. If no `name` is provided, the
   * feature will use the `default` highlight options.
   *
   * Release-specific changes:
   * * As of version 4.32, the `highlight` method accepts an `options` parameter which can be used to provide a [HighlightOptions.name](https://developers.arcgis.com/javascript/latest/references/core/views/support/HighlightOptions/#name)
   * to apply specific [HighlightOptions](https://developers.arcgis.com/javascript/latest/references/core/views/support/HighlightOptions/).
   * If no `name` is provided, the `default` highlight options will be used.
   * * As of version 4.23, the `highlight()` method was added to [ImageryLayerView.highlight()](https://developers.arcgis.com/javascript/latest/references/core/views/layers/ImageryLayerView/#highlight),
   *   supported only in a [2D MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/).
   *
   * @param target - The feature(s) to highlight. When passing a graphic or an array of graphics, each feature must have a valid `objectID`.
   * You may alternatively pass one or more objectIDs as a single number, string, or an array of numbers or strings.
   * @param options - An object with the following properties.
   * @returns Returns a highlight handler with a `remove()` method that can be called to remove the highlight.
   * @see [View.highlights](https://developers.arcgis.com/javascript/latest/references/core/views/View/#highlights)
   * @see [Sample: Highlight features by geometry](https://developers.arcgis.com/javascript/latest/sample-code/highlight-features-by-geometry/)
   * @see [Sample: Highlight SceneLayer](https://developers.arcgis.com/javascript/latest/sample-code/highlight-scenelayer/)
   * @example
   * ```js
   * // Highlight features based on a query result
   *
   * // Add a new set of highlight options to the view's highlights collection
   * view.highlights.push({
   *   name: "oaks",
   *   color: "forestgreen",
   *   haloOpacity: 0.8,
   *   fillOpacity: 0.3
   * });
   *
   * // A handler can be used to remove any previous highlight when applying a new one
   * let highlight;
   *
   * // Query for particular features in a layer and then highlight them with the specified options
   * view.whenLayerView(treesLayer).then((layerView) => {
   *   let query = treesLayer.createQuery();
   *   query.where = "type = 'Quercus'";
   *
   *   treesLayer.queryFeatures(query).then((result) => {
   *     // Remove any previous highlight, if it exists
   *     highlight?.remove();
   *     // Apply the "oaks" highlight options to the corresponding tree features
   *     highlight = layerView.highlight(result.features, {name: "oaks"});
   *   });
   * });
   * ```
   * @example
   * ```js
   * // Use the default highlights collection to apply a highlight to features when you hover over them
   *
   * // A handler can be used to remove any previous highlight when applying a new one
   * let hoverHighlight;
   *
   * view.on("pointer-move", (event) => {
   *   // Search for the first feature in the featureLayer at the hovered location
   *   view.hitTest(event, { include: layer }).then((response) => {
   *     if (response.results[0]) {
   *       const graphic = response.results[0].graphic;
   *       view.whenLayerView(graphic.layer).then((layerView) => {
   *         // Remove any previous highlight, if it exists
   *         hoverHighlight?.remove();
   *         // Highlight the hit features with the temporary highlight options, which are pre-configured for this use case
   *         hoverHighlight = layerView.highlight(graphic, { name: "temporary" });
   *       });
   *     }
   *   });
   * });
   * ```
   */
  abstract highlight(target: Graphic | Graphic[] | ObjectId | ObjectId[], options?: LayerViewHighlightOptions): ResourceHandle;
  /**
   * Returns all graphics available for drawing in the layer view
   * as a [Collection](https://developers.arcgis.com/javascript/latest/references/core/core/Collection/).
   *
   * @returns When resolved, a [Collection](https://developers.arcgis.com/javascript/latest/references/core/core/Collection/) of all [graphics](https://developers.arcgis.com/javascript/latest/references/core/Graphic/) is returned.
   * @since 4.8
   * @example
   * let layer = new GraphicsLayer();
   *
   * // returns all the graphics from the layer view
   * const layerView = await view.whenLayerView(layer);
   * await reactiveUtils.whenOnce(() => !layerView.updating);
   * const results = await layerView.queryGraphics();
   * console.log(results);  // prints the array of client-side graphics to the console
   */
  abstract queryGraphics(): Promise<Collection<Graphic>>;
}