/**
 * This object contains helper methods for generating location-only visualizations (not data-driven) in
 * a [Layer](https://developers.arcgis.com/javascript/latest/references/core/layers/Layer/).
 * The [createRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/location/#createRenderer) method generates a
 * [SimpleRenderer](https://developers.arcgis.com/javascript/latest/references/core/renderers/SimpleRenderer/) object that may be applied directly to the layer. This
 * renderer contains a single symbol with a color optimally selected based on the background of the view.
 *
 * @since 4.2
 * @see [Styles and data visualization](https://developers.arcgis.com/javascript/latest/visualization/)
 */
import type FeatureFilter from "../../layers/support/FeatureFilter.js";
import type SimpleRenderer from "../../renderers/SimpleRenderer.js";
import type { AbortOptions } from "../../core/promiseUtils.js";
import type { FeatureLikeLayerOrAdapter } from "../support/adapters/types.js";
import type { LocationScheme, BasemapTheme } from "../symbology/types.js";
import type { MapViewOrSceneView } from "../../views/MapViewOrSceneView.js";

/**
 * Generates a [Renderer](https://developers.arcgis.com/javascript/latest/references/core/renderers/Renderer/) that may be applied directly to a
 * supported [Layer](https://developers.arcgis.com/javascript/latest/references/core/layers/Layer/). The
 * renderer contains a single symbol with a color optimally chosen based on the view's background.
 *
 * In most cases you will provide a `layer` and `view` to generate this renderer. If working in
 * a 3D [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/), then the `symbolType` option should be used.
 *
 * @param parameters - Input parameters for generating a location-based visualization.
 * @returns Resolves to an instance of [RendererResult](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/location/#RendererResult).
 * @example
 * let layer = new FeatureLayer({
 *   url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/counties_politics_poverty/FeatureServer/0"
 * });
 *
 * // simple visualization to indicate features with a single symbol
 * let params = {
 *   layer: layer,
 *   view: view
 * };
 *
 * // when the promise resolves, apply the renderer to the layer
 * locationRendererCreator.createRenderer(params)
 *   .then(function(response){
 *     layer.renderer = response.renderer;
 *   });
 */
export function createRenderer(parameters: RendererParameters): Promise<RendererResult>;

export type SymbolType = "2d" | "3d-flat" | "3d-volumetric" | "3d-volumetric-uniform";

export type ColorMixModeType = "tint" | "replace" | "multiply";

export interface RendererParameters extends AbortOptions {
  /**
   * The layer for
   * which the visualization is generated. When a client-side layer type is provided, spatial statistics are calculated
   * only from features in the view's extent. When a server-side layer type is provided, the statistics
   * are calculated from the entire layer.
   */
  layer?: FeatureLikeLayerOrAdapter | null;
  /**
   * In authoring apps,
   * the user may select a pre-defined location scheme. Pass the scheme object to this property to avoid getting one
   * based on the view's background.
   */
  locationScheme?: LocationScheme | null;
  /**
   * The view where the input layer is rendered. This method
   *   inspects the view's background (i.e. basemap, web map background, or view container) to determine optimal
   *   colors for the output renderer. This parameter should always be set in practice, but if not provided this method
   *   will assume the generated renderer will display on a light background.
   */
  view?: MapViewOrSceneView | null;
  /**
   * The type of symbol to generate. This depends on the view
   * in which you are working and the desired visualization. This parameter does not need to be specified for layers
   * with a `mesh` geometry type. Possible values are described below.
   *
   * | Value | Description |
   * | ----- | ----------- |
   * | 2d | Generates a visualization using 2D symbols such as [SimpleMarkerSymbol](https://developers.arcgis.com/javascript/latest/references/core/symbols/SimpleMarkerSymbol/), [SimpleLineSymbol](https://developers.arcgis.com/javascript/latest/references/core/symbols/SimpleLineSymbol/), or [SimpleFillSymbol](https://developers.arcgis.com/javascript/latest/references/core/symbols/SimpleFillSymbol/). Use this option if generating a visualization for data in a [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/). |
   * | 3d-flat | Generates a visualization using 3D symbols with flat symbol layers such as [IconSymbol3DLayer](https://developers.arcgis.com/javascript/latest/references/core/symbols/IconSymbol3DLayer/), [LineSymbol3DLayer](https://developers.arcgis.com/javascript/latest/references/core/symbols/LineSymbol3DLayer/), or [FillSymbol3DLayer](https://developers.arcgis.com/javascript/latest/references/core/symbols/FillSymbol3DLayer/). Use this option if generating a 2D visualization for data in a [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/). |
   * | 3d-volumetric | Generates a visualization using 3D symbols with volumetric symbol layers such as [ObjectSymbol3DLayer](https://developers.arcgis.com/javascript/latest/references/core/symbols/ObjectSymbol3DLayer/), [PathSymbol3DLayer](https://developers.arcgis.com/javascript/latest/references/core/symbols/PathSymbol3DLayer/), or [ExtrudeSymbol3DLayer](https://developers.arcgis.com/javascript/latest/references/core/symbols/ExtrudeSymbol3DLayer/). Use this option if generating a 3D visualization for data in a [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/). A SceneView instance must be provided to the `view` parameter if this option is used. |
   * | 3d-volumetric-uniform | Generates a visualization using uniformly sized 3D symbols with volumetric symbol layers. Use this option if generating a 3D visualization for data in a [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/) and the symbol should be sizes uniformly, for example with spheres. A SceneView instance must be provided to the `view` parameter if this option is used. |
   *
   * @default 2d
   */
  symbolType?: SymbolType | null;
  /**
   * **This option only applies to generating renderers for mesh SceneLayers**.
   * Specifies how the symbol's color is applied to the geometry color/texture. See the documentation in
   * [FillSymbol3DLayer.material](https://developers.arcgis.com/javascript/latest/references/core/symbols/FillSymbol3DLayer/#material) for more context.
   * See the table below for possible values.
   *
   * Value | Description
   * ------|------------
   * tint | Applies the symbol `color` to the unsaturated geometry/texture color.
   * replace | Removes the geometry/texture color and applies the symbol `color`.
   * multiply | Multiplies geometry/texture color value with the symbol `color` value. The result is a darker color. Multiplying with white keeps the geometry color the same.
   *
   * @default replace
   */
  colorMixMode?: ColorMixModeType | null;
  /**
   * For polygon layers only. Indicates whether the
   *   polygon outline width should vary based on view scale. When set, a valid [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/)
   *   instance must be provided in the `view` parameter. This option is not supported for 3D
   *   [SceneViews](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
   *
   * @default false
   */
  outlineOptimizationEnabled?: boolean | null;
  /**
   * For point and polyline layers only. Indicates whether
   *   symbol sizes should vary based on view scale. When set, a valid [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/)
   *   instance must be provided in the `view` parameter. This option is not supported for 3D
   *   [SceneViews](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
   *
   * @default false
   */
  sizeOptimizationEnabled?: boolean | null;
  /** Indicates whether the generated renderer is for a binning or clustering visualization. */
  forBinning?: boolean | null;
  /**
   * When defined, only features included in the filter
   *   are considered in the attribute and spatial statistics calculations when determining the final renderer.
   *   This is useful when a lot of variation exists in the data
   *   that could result in undesired data ranges. A common use case would be to set a filter that only
   *   includes features in the current extent of the view where the data is most likely to be viewed. Currently, only
   *   geometry filters with an `intersects` spatial relationship are supported. All other filter types (including `where`) are ignored.
   *
   * @since 4.31
   */
  filter?: FeatureFilter | null;
}

/**
 * The result object of the [createRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/location/#createRenderer) method. See the table
 * below for details of each property.
 */
export interface RendererResult {
  /**
   * A simple renderer configured with a single color best
   * suited to match the background of the view. Set this to a layer's `renderer` property to
   * update its visualization.
   */
  renderer: SimpleRenderer;
  /**
   * The location scheme
   *   used by the renderer.
   */
  locationScheme: LocationScheme;
  /** The ID of the basemap used to determine the optimal fill color of the features. */
  basemapId?: string | null;
  /** Indicates whether the average color of the input view's basemap is `light` or `dark`. */
  basemapTheme?: BasemapTheme | null;
}