import type Graphic from "../Graphic.js";
import type Renderer from "./Renderer.js";
import type CIMSymbol from "../symbols/CIMSymbol.js";
import type { RendererProperties } from "./Renderer.js";
import type { DictionaryUserConfig, DictionaryFieldMap, DictionaryConfigItem } from "./types.js";
import type { VisualVariablesMixin, VisualVariablesMixinProperties } from "./mixins/VisualVariablesMixin.js";

export interface DictionaryRendererProperties extends RendererProperties, VisualVariablesMixinProperties, Partial<Pick<DictionaryRenderer, "config" | "fieldMap" | "scaleExpression" | "scaleExpressionTitle" | "url">> {}

/**
 * Dictionary Renderer is used to symbolize layers using a dictionary of [CIMSymbols](https://developers.arcgis.com/javascript/latest/references/core/symbols/CIMSymbol/) configured with multiple
 * attributes. This renderer should be used when individual features need to be visualized based on multiple data attributes.
 * This may lead to many symbol permutations that would be inappropriate for using a UniqueValueRenderer.
 *
 * A dictionary renderer applies symbols to features through an associated dictionary symbol web style. The web style
 * contains all the symbol components as well as rules for displaying the symbol.
 *
 * ![dictionary-renderer](https://developers.arcgis.com/javascript/latest/assets/images/guide/whats-new/413/dictionary-renderer.png)
 *
 * > [!WARNING]
 * >
 * > **Known Limitations**
 * >
 * > - DictionaryRenderer may only be used to create visualizations for the following layer types:
 * >   - [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/)
 * >   - [CSVLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/CSVLayer/)
 * >   - [GeoJSONLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GeoJSONLayer/)
 * >   - [OGCFeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/OGCFeatureLayer/)
 * >   - [WFSLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/WFSLayer/)
 * >   - [StreamLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/StreamLayer/)
 * >
 * > - DictionaryRenderer is not supported in the [Legend](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-legend/).
 *
 * > [!WARNING]
 * >
 * > **Best Practices**
 * >
 * > - Dictionary symbol styles can be created manually or from ArcGIS Pro (since ArcGIS Pro 2.5). It is recommended to use ArcGIS Pro to create
 * > and publish your styles. See [Share a web style](https://pro.arcgis.com/en/pro-app/latest/help/sharing/overview/share-a-web-style.htm) for details.
 * > Instructions on creating dictionary symbol style manually are available at: [Creating Dictionary Symbol Style](https://github.com/annelfitz/annelfitz.github.io/tree/master/dictionaryRenderer/symbolService).
 * > - DictionaryRenderer works best when visualizing data at large scales (zoomed in closer to the ground). Because theses symbols
 * > can be complex, containing multiple icons and varied text per feature, layers rendered with DictionaryRenderer can be illegible
 * > when many features overlap one another and clutter the view. We suggest setting [FeatureLayer.minScale](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#minScale) and
 * > [FeatureLayer.maxScale](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#maxScale) on layers rendered with DictionaryRenderer to avoid displaying too
 * > much information at small scales.
 *
 * @since 4.13
 * @see [CIMSymbol](https://developers.arcgis.com/javascript/latest/references/core/symbols/CIMSymbol/)
 * @see [Sample - Visualize data with dictionary renderer](https://developers.arcgis.com/javascript/latest/sample-code/visualization-dictionary/)
 * @see [ArcGIS Pro - Dictionary symbology](https://pro.arcgis.com/en/pro-app/latest/help/mapping/layer-properties/dictionary-renderer.htm)
 * @see [ArcGIS Blog - Create custom dictionary styles for ArcGIS](https://www.esri.com/arcgis-blog/products/arcgis-pro/mapping/create-custom-dictionary-styles-for-arcgis/)
 * @example
 * let renderer = new DictionaryRenderer({
 *   url: "./alternative-fuel-stations",
 *   fieldMap: {
 *     fuel_type: "Fuel_Type_Code",
 *     name: "Station_Name"
 *   },
 *   config: {
 *     show_label: "false"
 *   }
 * });
 *
 * let layer = new FeatureLayer({
 *   url: "http://url.to.service",
 *   renderer: renderer
 * });
 */
export default class DictionaryRenderer extends DictionaryRendererSuperclass {
  /**
   * @example
   * // Typical usage
   * let renderer = new DictionaryRenderer({
   *   url: "./alternative-fuel-stations",
   *   fieldMap: {
   *     fuel_type: "Fuel_Type_Code",
   *     name: "Station_Name"
   *   },
   *   config: {
   *     show_label: "false"
   *   }
   * });
   */
  constructor(properties?: DictionaryRendererProperties);
  /**
   * This property allows you to set display options that can be configured on the dictionary symbol style. For example,
   * if the dictionary symbol style provides a display option to turn on/off a symbol/text, you could set it here.
   *
   * @example
   * renderer.config = {
   *  show_label: "true"
   * }
   */
  accessor config: DictionaryUserConfig | null | undefined;
  /**
   * Defines a field mapping that maps input fields from the feature to the dictionary symbol style's expected fields for symbols and
   * text. Each key identifies an expected field (defined in the dictionary's symbol and text properties).
   * The value identifies the corresponding mapped field from the dataset. Field names are case sensitive.
   *
   * @example
   * renderer.fieldMap = {
   *   fuel_type: "Fuel_Type_Code",
   *   connector_types: "EV_Connector_Types",
   *   network: "EV_Network",
   *   name: "Station_Name"
   * };
   */
  accessor fieldMap: DictionaryFieldMap | null | undefined;
  /**
   * A scaling expression can be set to increase or decrease the size of the dictionary symbols.
   * The scaling expression can be a constant value for all symbols or an [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) expression following the specification
   * defined by the [Arcade Visualization Profile](https://developers.arcgis.com/javascript/latest/arcade/#visualization). Expressions
   * in DictionaryRenderer may reference field values using the `$feature` profile variable and must return a number.
   *
   * @see [Arcade Visualization Profile](https://developers.arcgis.com/javascript/latest/arcade/#visualization)
   * @example renderer.scaleExpression = "2"; //Make the symbols two times bigger.
   * @example renderer.scaleExpression = "IIF($feature.symbolset == 10, 2, 1)"; //If the value of "symbolset" field of a feature is 10, make the symbols two times bigger.
   */
  accessor scaleExpression: string | null | undefined;
  /**
   * The title identifying and describing the associated [Arcade](https://developers.arcgis.com/javascript/latest/arcade/)
   * expression as defined in the [scaleExpression](https://developers.arcgis.com/javascript/latest/references/core/renderers/DictionaryRenderer/#scaleExpression) property.
   *
   * @example
   * renderer.scaleExpression = "IIF($feature.symbolset == 10, 2, 1)";
   * renderer.scaleExpressionTitle = "Scale by symbol set";
   */
  accessor scaleExpressionTitle: string | null | undefined;
  /**
   * The properties of the dictionary style configuration.
   *
   * @since 5.0
   */
  get styleConfigProperties(): DictionaryConfigItem[] | null | undefined;
  /**
   * The dictionary style name.
   *
   * @since 5.0
   */
  get styleName(): string | null | undefined;
  /**
   * Symbol fields of the dictionary style.
   *
   * @since 5.0
   */
  get styleSymbolFields(): string[] | null | undefined;
  /**
   * Text fields of the dictionary style.
   *
   * @since 5.0
   */
  get styleTextFields(): string[] | null | undefined;
  /**
   * The dictionary style UI schema.
   *
   * @since 5.0
   */
  get styleUISchema(): Object | null | undefined;
  /**
   * The dictionary style version.
   *
   * @since 5.0
   */
  get styleVersion(): string | null | undefined;
  /** The type of renderer. */
  get type(): "dictionary";
  /**
   * The URL to the dictionary style.
   *
   * @example renderer.url = "https://www.arcgis.com/sharing/rest/content/items/30cfbf36efd64ccf92136201d9e852af/data";
   */
  accessor url: string | null | undefined;
  /**
   * Creates a deep clone of the renderer.
   *
   * @returns A deep clone of the object that
   *                                                      invoked this method.
   * @example
   * // Creates a deep clone of the first layer's renderer
   * const renderer = view.map.layers.at(0).renderer.clone();
   */
  clone(): DictionaryRenderer;
  /**
   * This method will return the symbol for a given graphic using the dictionary renderer.
   *
   * @param graphic - The graphic used to get the resulting symbol.
   * @returns When resolved, a [CIMSymbol](https://developers.arcgis.com/javascript/latest/references/core/symbols/CIMSymbol/) will be returned.
   */
  getSymbolAsync(graphic: Graphic): Promise<CIMSymbol | null | undefined>;
}
declare const DictionaryRendererSuperclass: typeof Renderer & typeof VisualVariablesMixin