/**
 * Provides utility functions for generating [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) and SQL expressions
 * intended for use in an [predominance renderer](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/predominance/).
 *
 * @since 4.23
 * @see [predominance renderer](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/predominance/)
 */
import type CSVLayer from "../../../layers/CSVLayer.js";
import type FeatureLayer from "../../../layers/FeatureLayer.js";
import type GeoJSONLayer from "../../../layers/GeoJSONLayer.js";
import type OGCFeatureLayer from "../../../layers/OGCFeatureLayer.js";
import type OrientedImageryLayer from "../../../layers/OrientedImageryLayer.js";
import type SceneLayer from "../../../layers/SceneLayer.js";
import type StreamLayer from "../../../layers/StreamLayer.js";
import type SubtypeGroupLayer from "../../../layers/SubtypeGroupLayer.js";
import type WFSLayer from "../../../layers/WFSLayer.js";
import type CatalogFootprintLayer from "../../../layers/catalog/CatalogFootprintLayer.js";
import type KnowledgeGraphSublayer from "../../../layers/knowledgeGraph/KnowledgeGraphSublayer.js";
import type SubtypeSublayer from "../../../layers/support/SubtypeSublayer.js";

/**
 * Returns [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) and SQL expressions used for visualizing the predominant category (or field) among a set of competing fields.
 *
 * @param layer - The layer from which to generate the Arcade and SQL expressions for querying predominance statistics.
 * @param fieldNames - An array of numeric field names for which to create the Arcade and SQL expressions used to build the predominance renderer.
 * @returns Returns the Arcade and SQL expressions used for creating a predominance renderer. These expressions are used to query a feature service or the client-side layer for statistics relevant to creating the default predominance renderer for the given fields.
 * @example
 * const predominanceExpressions = predominanceUtils.getPredominanceExpressions({
 *   layer: featureLayer,
 *   fields: ["Corn", "Wheat", "Soybeans", "Vegetables", "Cotton"]
 * });
 *
 * console.log(`value expression for getting the predominant category from the given fields: ${predominanceExpressions.predominantCategory.valueExpression}`);
 */
export function getPredominanceExpressions(layer: FeatureLayer | SceneLayer | CSVLayer | GeoJSONLayer | WFSLayer | OGCFeatureLayer | StreamLayer | OrientedImageryLayer | KnowledgeGraphSublayer | SubtypeGroupLayer | CatalogFootprintLayer | SubtypeSublayer, fieldNames: string[]): PredominantExpressions;

/** The result object returned from the [getPredominanceExpressions()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/support/predominanceUtils/#getPredominanceExpressions) method. */
export interface PredominantExpressions {
  /** The Arcade expression used to get the predominant category among a set of fields. */
  predominantCategory: PredominantCategoryInfo;
  /** The Arcade and SQL expressions used to query the server or client-side layer for statistics of the sum of all competing fields considered for the predominance visualization. */
  size: SizeExpressionInfo;
  /** The Arcade and SQL expressions used to query the server or client-side layer for statistics of the percentage among all competing fields comprised by the predominant category. */
  opacity: OpacityExpressionInfo;
}

/** SQL expressions used to query feature services for predominant values and related statistics given a set of fields. */
export interface SQLExpressionInfo {
  /** The SQL expression used for querying the predominant category given a set of fields. This expression should match the logic of the Arcade expression in the parent info object. */
  sqlExpression: string;
  /** The SQL where clause used to query the predominant value. This should be used to ensure negative values are not considered in the predominance calculation. */
  sqlWhere: string;
}

export interface PredominantCategoryInfo {
  /**
   * valueExpression - 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).
   * The expression should be used to return the name of the predominant field among a set of competing fields. It may reference field values using the `$feature`
   * profile variable and must return a string.
   */
  valueExpression: string;
}

/** Contains the Arcade and SQL expressions used to query feature services and client-side layers for the sum of all values considered in a predominance visualization. */
export interface SizeExpressionInfo {
  /**
   * 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).
   * The expression should be used to calculate the sum of a set of numeric fields.
   * It may reference field values using the `$feature` profile variable and must return a number.
   */
  valueExpression: string;
  /** The SQL expressions used for querying the sum of a set of fields. This expression should match the logic of the Arcade expression. */
  statisticsQuery: SQLExpressionInfo;
  /** The SQL expressions used for querying the histogram for the sum of a set of fields. */
  histogramQuery: SQLExpressionInfo;
}

/**
 * Contains the Arcade and SQL expressions used to query feature services and client-side layers for the strength
 * of the predominant category compared with all other categories. In other words, these expressions should
 * calculate the percentage of the sum the winning value comprises.
 */
export interface OpacityExpressionInfo {
  /**
   * 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).
   * The expression should be used to calculate the percentage the winning field
   *  comprises among of a set of numeric fields.
   * It may reference field values using the `$feature` profile variable and must return a number.
   */
  valueExpression: string;
  /** The SQL expressions used for querying the percentage the predominant value comprises among of a set of fields. This expression should match the logic of the Arcade expression. */
  statisticsQuery: SQLExpressionInfo;
  /** The SQL expressions used for querying the histogram using the percentage the predominant value comprises among of a set of fields. */
  histogramQuery: SQLExpressionInfo;
}