/**
 * A module for importing types used in smart mapping statistics modules.
 *
 * @since 4.33
 */
import type Graphic from "../../Graphic.js";
import type FeatureFilter from "../../layers/support/FeatureFilter.js";
import type { MapViewOrSceneView } from "../../views/MapViewOrSceneView.js";
import type { AbortOptions } from "../../core/promiseUtils.js";
import type { DateProperties } from "../../intl/date.js";
import type { Feature as FeatureJSON } from "../../portal/jsonTypes.js";
import type { ClassificationMethod, NormalizationType } from "../../renderers/types.js";
import type { SupportedLayer, SmartMappingTimeUnit } from "../types.js";
import type { OutStatisticTypes } from "../../statistics/types.js";

/** The result returned from the [histogram()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/histogram/#histogram) method. */
export interface HistogramResult {
  /** An array of objects representing each bin in the histogram. */
  bins: HistogramBin[];
  /** The maximum value returned by the field. */
  maxValue?: number | null;
  /** The minimum value returned by the field. */
  minValue?: number | null;
  /**
   * The number used to normalize all values when `percent-of-total`
   *   is specified as the `normalizationType`.
   */
  normalizationTotal?: number | null;
}

/**
 * Represents the bin of a histogram. A bin consists of
 * a minimum and a maximum value and a count. It indicates the
 * number of values in a dataset that lie between the
 * min and max values.
 */
export interface HistogramBin {
  /** The minimum value (or bound) of the bin. */
  minValue: number;
  /** The maximum value (or bound) of the bin. */
  maxValue: number;
  /**
   * The number of values in a dataset that are
   *   contained between the indicated `minValue` and `maxValue`.
   */
  count: number;
}

export interface SummaryStatisticsParameters extends AbortOptions {
  /** The layer from which to generate statistics for the given `field`. */
  layer?: SupportedLayer | null;
  /**
   * The name of the numeric or string field for which the summary statistics will be generated.
   *   This property is ignored if a `valueExpression` is used.
   */
  field?: string | null;
  /**
   * 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 may reference field values using the `$feature` profile variable and must return
   * a number. This property overrides the `field` property and therefore is used instead of an input `field` value.
   * The `view` parameter is required if specifying a `valueExpression`. When using a `valueExpression`, client-side
   * statistics are calculated based on the features in the view's extent. To generate statistics for the entire layer,
   * set an equivalent `sqlExpression`.
   */
  valueExpression?: string | null;
  /**
   * A SQL expression evaluating to a number. When provided, statistics are
   *   queried from the server for the entire layer. Only use this parameter when querying statistics based on
   *   an equivalent `valueExpression`. This parameter is ignored for client-side layer types.
   */
  sqlExpression?: string | null;
  /**
   * A SQL where clause used to filter features for the statistics query. For example,
   * this is useful in situations where you want to avoid dividing by zero as is the case with creating a predominance
   * visualization.
   */
  sqlWhere?: string | null;
  /**
   * |
   * | field | Divides the data value using the value of the field specified in the `normalizationField` parameter. A `normalizationField` must be provided if this value is used. |
   * percent-of-total | Divides the data value by the sum of all data values then multiplies by 100. Use `normalizationTotal` to define the total value by which to normalize. |
   * log | Computes the base 10 logarithm of the data values. This can be a useful approach for viewing highly skewed data distributions because it reduces the influence of outliers. Only positive values are computed. You should avoid this normalization type if your data contains a significant number of negative values. |
   * natural-log | Computes the natural logarithm of the data values. This can be a useful approach for viewing highly skewed data distributions because it reduces the influence of outliers. Only positive values are computed. You should avoid this normalization type if your data contains a significant number of negative values. |
   * square-root | Computes the square root of the data values. This can be a useful approach for viewing highly skewed data distributions because it reduces the influence of outliers. Only positive values are computed. You should avoid this normalization type if your data contains a significant number of negative values. |
   */
  normalizationType?: NormalizationType | null;
  /** The field by which to normalize the values returned from the given `field`. */
  normalizationField?: string | null;
  /**
   * Only applies if `normalizationType` is `percent-of-total`. Indicates the total amount
   * with which to normalize field values.
   */
  normalizationTotal?: number | null;
  /**
   * A subset of features for which to calculate the statistics.
   *
   * @deprecated since version 4.23. Use `useFeaturesInView` instead.
   */
  features?: Graphic[] | FeatureJSON[] | null;
  /**
   * Only applicable when the input `layer` is a
   *   service-backed FeatureLayer. When `true`, statistics will be calculated on the client from features
   *   visible in the view. If `false`, statistics will be requested from the service.
   *
   * @since 4.23
   */
  useFeaturesInView?: 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.25
   */
  filter?: FeatureFilter | null;
  /**
   * The minimum bounding value for the statistics calculation. Use this in conjunction with `maxValue` to
   * generate statistics between lower and upper bounds.
   */
  minValue?: number | null;
  /**
   * The maximum bounding value for the statistics calculation. Use this in conjunction with `minValue` to
   * generate statistics between lower and upper bounds.
   */
  maxValue?: number | null;
  /**
   * Indicates whether the generated statistics are for a binning or clustering visualization.
   *   If `true`, then the input field(s) in this method should refer to [aggregate fields](https://developers.arcgis.com/javascript/latest/references/core/layers/support/AggregateField/) defined in the `featureReduction` property of the layer.
   */
  forBinning?: boolean | null;
  /**
   * Indicates the statistics to calculate. If not defined, all statistics are calculated by default. The object should have the following properties.
   *
   * @since 4.31
   */
  outStatisticTypes?: OutStatisticTypes | null;
  /**
   * A [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/) or [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/) instance is
   * required when a `valueExpression` is specified.
   */
  view?: MapViewOrSceneView | null;
}

/** The statistics returned from the [summaryStatistics()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/summaryStatistics/#summaryStatistics) query. */
export interface SummaryStatisticsResult {
  /** The average of all values returned from the field or expression. */
  avg?: number | null;
  /** The total number of features with a non-null value for the given field. */
  count?: number | null;
  /** The maximum of all values returned from the field or expression. */
  max?: number | null;
  /** The minimum of all values returned from the field or expression. */
  min?: number | null;
  /** The standard deviation calculated from values returned from the field or expression. */
  stddev?: number | null;
  /** The sum of all values returned from the field or expression. */
  sum?: number | null;
  /** The calculated variance from all values returned from the field or expression. */
  variance?: number | null;
  /**
   * The number of null values stored in the given field.
   *   Only applies to summary statistics calculated with a field value at **version 4.20** or later.
   */
  nullcount?: number | null;
  /**
   * The median of all values returned from the field or expression.
   *
   * @since 4.22
   */
  median?: number | string | null;
}

export interface ClassBreaksParameters extends AbortOptions {
  /**
   * The layer from which to generate class breaks. When a client-side layer type is provided, attribute and 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?: SupportedLayer | null;
  /**
   * The class breaks will be generated based on values of this field.
   * If a field is provided, the values from the given field from all features
   * will be queried in the service.
   */
  field?: string | null;
  /**
   * 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 may reference field values using the `$feature` profile variable and must return
   * a number. This property overrides the `field` property and therefore is used instead of an input `field` value.
   * The `view` parameter is required if specifying a `valueExpression`. When using a `valueExpression`, client-side
   * statistics are calculated based on the features in the view's extent.
   */
  valueExpression?: string | null;
  /**
   * When `classificationMethod = "standard-deviation"`, this
   * sets the interval at which each class break should be set (e.g. `0.25`, `0.33`, `0.5`, `1`).
   * See the table below for a list of possible values.
   *
   *
   * | Possible Value | Description |
   * |---------------|------------ |
   * | field | Divides the data value using the attribute value of the field specified in the `normalizationField` property. A `normalizationField` must be provided if This value is used. |
   * log | Computes the base 10 logarithm of the data value. This can be a useful approach for some data distributions because it reduces the influence of very large data values. |
   * percent-of-total | Divides the data value by the sum of all data values then multiplies by 100. Use `normalizationTotal` to define the total value by which to normalize. |
   * then set the total amount with which to normalize field values.
   */
  standardDeviationInterval?: number | null;
  /** The field by which to normalize the values returned from the given `field`. */
  normalizationField?: string | null;
  /**
   * The minimum bounding value for the class breaks definition.
   * Use this in conjunction with `maxValue` to generate class breaks between lower and upper bounds.
   */
  minValue?: number | null;
  /**
   * The maximum bounding value for the class breaks definition. Use this
   * in conjunction with `minValue` to generate class breaks between lower and upper bounds.
   */
  maxValue?: number | null;
  /**
   * The method for classifying the data. See the table below
   * for a list of possible values.
   *
   * | Possible Value | Description |
   * |---------------|------------ |
   * | natural-breaks | Data values that cluster are placed into a single class. Class breaks occur where gaps exist between clusters. You should use this method if your data is unevenly distributed; that is, many features have the same or similar values and there are gaps between groups of values. |
   * | equal-interval | Each class has an equal range of values; in other words, the difference between the high and low value is equal for each class. You should use this method if your data is evenly distributed and you want to emphasize the difference in values between the features. |
   * | quantile | Each class has roughly the same number of features. If your data is evenly distributed and you want to emphasize the difference in relative position between features, you should use the quantile classification method. If, for example, the point values are divided into five classes, points in the highest class would fall into the top fifth of all points.  |
   * | standard-deviation | Class breaks are placed above and below the mean value at intervals of `1`, `0.5`, or `0.25` standard deviations until all the data values are included in a class.  |
   */
  classificationMethod?: ClassificationMethod | null;
  /** Indicates the number of classes to generate for the class breaks definition. */
  numClasses?: number | null;
  /**
   * A subset of features for which to generate the class breaks.
   *
   * @deprecated since version 4.23. Use `useFeaturesInView` instead.
   */
  features?: Graphic[] | FeatureJSON[] | null;
  /**
   * Only applicable when the input `layer` is a
   *   service-backed FeatureLayer. When `true`, statistics will be calculated on the client from features
   *   visible in the view. If `false`, statistics will be requested from the service.
   *
   * @since 4.23
   */
  useFeaturesInView?: boolean | null;
  /**
   * A feature filter used to filter
   *   statistic queries by geometry. This parameter is only used for filtering statistics by geometry. Any
   *   attribute filters set on the `FeatureFilter.where` property are ignored. Currently, only the `intersects`
   *   spatial relationship is supported. This is useful if you already
   *   define a feature filter by geometry on your layer and want to calculate statistics for the included
   *   features.
   *
   * @since 4.25
   */
  filter?: FeatureFilter | null;
  /**
   * Indicates whether the generated statistics are for a binning or clustering visualization.
   *   If `true`, then the input field(s) in this method should refer to [aggregate fields](https://developers.arcgis.com/javascript/latest/references/core/layers/support/AggregateField/) defined in the `featureReduction` property of the layer.
   */
  forBinning?: boolean | null;
  /**
   * A [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/) or [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/) instance is
   * required when a `valueExpression` is specified.
   */
  view?: MapViewOrSceneView | null;
}

/**
 * Object returned from the [classBreaks()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/classBreaks/#classBreaks) method. This object describes classes
 * generated from data in a [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/) for a given field with a
 * specified classification method.
 */
export interface ClassBreaksResult {
  /**
   * The minimum value of features in the dataset. This will be the lower
   *   bound of the lowest class break.
   */
  minValue?: number | null;
  /**
   * The maximum value of features in the dataset. This will be the upper
   *   bound of the highest class break.
   */
  maxValue?: number | null;
  /** An array of objects describing the class breaks generated from the [classBreaks()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/classBreaks/#classBreaks) method. */
  classBreakInfos: ClassBreak[];
  /**
   * The normalization total if `normalizationType` is set to `percent-of-total`
   *   when generating class breaks with [createClassBreaksRenderer()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/renderers/color/#createClassBreaksRenderer).
   */
  normalizationTotal?: number | null;
}

/** An object describing a single class break generated from the [classBreaks()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/classBreaks/#classBreaks) method. */
export interface ClassBreak {
  /** The lower bound of the class break. */
  minValue: number;
  /** The upper bound of the class break. */
  maxValue: number;
  /**
   * The label describing the given class break
   *   for use in the [Legend](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-legend/).
   */
  label?: string | null;
}

export interface HistogramParameters extends AbortOptions {
  /**
   * The layer for which to generate a histogram. When a client-side layer type is provided, attribute and 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, unless a `valueExpression` is provided.
   */
  layer?: SupportedLayer | null;
  /**
   * The name of the numeric field for which the histogram will be generated.
   *   This property is ignored if a `valueExpression` is used.
   */
  field?: string | null;
  /**
   * The method for classifying the data. See the table below
   * for a list of possible values.
   *
   * | Possible Value | Description |
   * |---------------|------------ |
   * | natural-breaks | Data values that cluster are placed into a single class. Class breaks occur where gaps exist between clusters. You should use this method if your data is unevenly distributed; that is, many features have the same or similar values and there are gaps between groups of values. |
   * | equal-interval | Each class has an equal range of values; in other words, the difference between the high and low value is equal for each class. You should use this method if your data is evenly distributed and you want to emphasize the difference in values between the features. |
   * | quantile | Each class has roughly the same number of features. If your data is evenly distributed and you want to emphasize the difference in relative position between features, you should use the quantile classification method. If, for example, the point values are divided into five classes, points in the highest class would fall into the top fifth of all points.  |
   * | standard-deviation | Class breaks are placed above and below the mean value at intervals of `1`, `0.5`, or `0.25` standard deviations until all the data values are included in a class.  |
   */
  classificationMethod?: ClassificationMethod | null;
  /** The field by which to normalize the values returned from the given `field`. */
  normalizationField?: string | null;
  /**
   * |
   * | field | Divides the data value using the value of the field specified in the `normalizationField` parameter. A `normalizationField` must be provided if this value is used. |
   * percent-of-total | Divides the data value by the sum of all data values then multiplies by 100. Use `normalizationTotal` to define the total value by which to normalize. |
   * log | Computes the base 10 logarithm of the data values. This can be a useful approach for viewing highly skewed data distributions because it reduces the influence of outliers. Only positive values are computed. You should avoid this normalization type if your data contains a significant number of negative values. |
   * natural-log | Computes the natural logarithm of the data values. This can be a useful approach for viewing highly skewed data distributions because it reduces the influence of outliers. Only positive values are computed. You should avoid this normalization type if your data contains a significant number of negative values. |
   * square-root | Computes the square root of the data values. This can be a useful approach for viewing highly skewed data distributions because it reduces the influence of outliers. Only positive values are computed. You should avoid this normalization type if your data contains a significant number of negative values. |
   */
  normalizationType?: NormalizationType | null;
  /**
   * Only applies if `normalizationType` is `percent-of-total`. Indicates the total amount
   * with which to normalize field values.
   */
  normalizationTotal?: number | null;
  /**
   * Indicates the number of classes to generate for the histogram.
   *
   * @default 10
   */
  numBins?: number | null;
  /**
   * When `classificationMethod = "standard-deviation"`, this
   * sets the interval at which each class break should be set (e.g. `0.25`, `0.33`, `0.5`, `1`).
   */
  standardDeviationInterval?: number | null;
  /**
   * 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 may reference field values using the `$feature` profile variable and must return
   * a number. This property overrides the `field` property and therefore is used instead of an input `field` value.
   * The `view` parameter is required if specifying a `valueExpression`. When using a `valueExpression`, client-side
   * statistics are calculated based on the features in the view's extent. To generate statistics for the entire layer,
   * set an equivalent `sqlExpression`.
   */
  valueExpression?: string | null;
  /**
   * A SQL expression evaluating to a number. When provided, statistics are
   *   queried from the server for the entire layer. Only use this parameter when querying statistics based on
   *   an equivalent `valueExpression`. This parameter is ignored for client-side layer types.
   */
  sqlExpression?: string | null;
  /**
   * A SQL where clause used to filter features for the statistics query. For example,
   * this is useful in situations where you want to avoid dividing by zero as is the case with creating a predominance
   * visualization.
   */
  sqlWhere?: string | null;
  /**
   * The minimum bounding value for the histogram.
   * Use this in conjunction with `maxValue` to generate a histogram between custom lower and upper bounds.
   */
  minValue?: number | null;
  /**
   * The maximum bounding value for the histogram. Use this
   * in conjunction with `minValue` to generate a histogram between custom lower and upper bounds.
   */
  maxValue?: number | null;
  /**
   * A subset of features for which to generate the histogram.
   *
   * @deprecated since version 4.23. Use `useFeaturesInView` instead.
   */
  features?: Graphic[] | FeatureJSON[] | null;
  /**
   * Only applicable when the input `layer` is a
   *   service-backed FeatureLayer. When `true`, statistics will be calculated on the client from features
   *   visible in the view. If `false`, statistics will be requested from the service.
   *
   * @since 4.23
   */
  useFeaturesInView?: boolean | null;
  /**
   * A feature filter used to filter
   *   statistic queries by geometry. This parameter is only used for filtering statistics by geometry. Any
   *   attribute filters set on the `FeatureFilter.where` property are ignored. Currently, only the `intersects`
   *   spatial relationship is supported. This is useful if you already
   *   define a feature filter by geometry on your layer and want to calculate statistics for the included
   *   features.
   *
   * @since 4.25
   */
  filter?: FeatureFilter | null;
  /**
   * Indicates whether the generated statistics are for a binning or clustering visualization.
   *   If `true`, then the input field(s) in this method should refer to [aggregate fields](https://developers.arcgis.com/javascript/latest/references/core/layers/support/AggregateField/) defined in the `featureReduction` property of the layer.
   */
  forBinning?: boolean | null;
  /**
   * A [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/) or [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/) instance is
   * required when a `valueExpression` is specified.
   */
  view?: MapViewOrSceneView | null;
}

export interface UniqueValuesParameters extends AbortOptions {
  /**
   * The layer from which to query for unique values. When a client-side layer type is provided, attribute and 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, unless a `valueExpression` is provided.
   */
  layer?: SupportedLayer | null;
  /**
   * The name of the numeric or string field from which the unique values will be obtained.
   *   This property is ignored if a `valueExpression` is used.
   */
  field?: string | null;
  /**
   * 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 may reference field values using the `$feature` profile variable and must return
   * a string or a number. This property overrides the `field` property and therefore is used instead of an input `field` value.
   * The `view` parameter is required if specifying a `valueExpression`. When using a `valueExpression`, client-side
   * statistics are calculated based on the features in the view's extent. To generate statistics for the entire layer,
   * set an equivalent `sqlExpression`.
   */
  valueExpression?: string | null;
  /**
   * A SQL expression evaluating to a number or string. When provided, statistics are
   *   queried from the server for the entire layer. Only use this parameter when querying statistics based on
   *   an equivalent `valueExpression`. This parameter is ignored for client-side layer types.
   */
  sqlExpression?: string | null;
  /**
   * A SQL where clause used to filter features for the statistics query. For example,
   * this is useful in situations where you want to avoid dividing by zero as is the case with creating a predominance
   * visualization.
   */
  sqlWhere?: string | null;
  /**
   * A subset of features for which to generate the unique values.
   *
   * @deprecated since version 4.23. Use `useFeaturesInView` instead.
   */
  features?: Graphic[] | FeatureJSON[] | null;
  /**
   * Only applicable when the input `layer` is a
   *   service-backed FeatureLayer. When `true`, statistics will be calculated on the client from features
   *   visible in the view. If `false`, statistics will be requested from the service.
   *
   * @since 4.23
   */
  useFeaturesInView?: boolean | null;
  /**
   * A feature filter used to filter
   *   statistic queries by geometry. This parameter is only used for filtering statistics by geometry. Any
   *   attribute filters set on the `FeatureFilter.where` property are ignored. Currently, only the `intersects`
   *   spatial relationship is supported. This is useful if you already
   *   define a feature filter by geometry on your layer and want to calculate statistics for the included
   *   features.
   *
   * @since 4.25
   */
  filter?: FeatureFilter | null;
  /**
   * Indicates that all domain codes should be returned if the given field
   * has domain values.
   */
  returnAllCodedValues?: boolean | null;
  /**
   * Indicates whether the generated statistics are for a binning or clustering visualization.
   *   If `true`, then the input field(s) in this method should refer to [aggregate fields](https://developers.arcgis.com/javascript/latest/references/core/layers/support/AggregateField/) defined in the `featureReduction` property of the layer.
   */
  forBinning?: boolean | null;
  /**
   * A [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/) or [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/) instance is
   * required when a `valueExpression` is specified.
   */
  view?: MapViewOrSceneView | null;
}

/**
 * An object that contains the unique values returned from the [uniqueValues()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/uniqueValues/#uniqueValues) query
 * of a layer's field.
 */
export interface UniqueValuesResult {
  /**
   * An array of objects, each containing a unique value/type/category
   * present in the field specified in the [uniqueValues()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/uniqueValues/#uniqueValues) query. See table below for
   * the specification of each object.
   */
  uniqueValueInfos: UniqueValueCountInfo[];
}

export interface UniqueValueCountInfo {
  /** A unique value representing a type or category of features in the layer. */
  value?: string | number | null;
  /** The number of features belonging to the predominant category. */
  count: number;
  /** The label describing the predominant category, or field name. */
  label?: string | null;
}

export interface HeatmapStatisticsParameters extends AbortOptions {
  /** The layer from which to generate statistics for the pixel intensity values and a given `field` if provided. */
  layer?: SupportedLayer | null;
  /** The name of the numeric field for which the statistics will be generated. */
  field?: string | null;
  /** The area of influence for each point as a radius in points from the point. */
  radius?: number | null;
  /**
   * A view instance used to calculate
   *   pixel intensity values based on the features in the current view.
   */
  view?: MapViewOrSceneView | null;
}

/** The statistics returned from the [heatmapStatistics()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/heatmapStatistics/#heatmapStatistics) function. */
export interface HeatmapStatisticsResult {
  /** The minimum kernel density value of all pixels in the view. */
  min?: number | null;
  /** The maximum kernel density value of all pixels in the view. */
  max?: number | null;
}

export interface PredominantCategoriesParameters extends AbortOptions {
  /** The layer from which to generate predominant categories for the given set of `fields`. */
  layer: SupportedLayer;
  /**
   * An array of numeric fields from which to determine predominant categories.
   *   The fields must all be number fields and they must be competing or complementary (e.g. population totals
   *   by language spoken at home, or harvested acres by crop type, or the results of an election by candidate or party).
   */
  fields: string[];
  /**
   * Indicates whether the generated statistics are for a binning or clustering visualization.
   *   If `true`, then the input field(s) in this method should refer to [aggregate fields](https://developers.arcgis.com/javascript/latest/references/core/layers/support/AggregateField/) defined in the `featureReduction` property of the layer.
   */
  forBinning?: boolean | null;
  /** The view in which features will be rendered. */
  view?: MapViewOrSceneView | null;
}

/** The statistics returned from the [predominantCategories()](https://developers.arcgis.com/javascript/latest/references/core/smartMapping/statistics/predominantCategories/#predominantCategories) function. */
export interface PredominantCategoriesResult {
  /**
   * An array of objects describing the count of each predominant
   *   category.
   */
  predominantCategoryInfos: UniqueValueCountInfo[];
}

export interface SummaryStatisticsForAgeParameters extends AbortOptions {
  /** The layer from which to generate age statistics for the given `startTime` and `endTime`. */
  layer: SupportedLayer;
  /**
   * The start time for the age calculation. This can be a field name or a date
   *   value, such as `Date.now()`. If a `Date` is provided, then the `endTime` parameter must be a field name.
   */
  startTime: DateProperties;
  /**
   * The end time for the age calculation. This can be a field name or a date
   *   value, such as `Date.now()`. If a `Date` is provided, then the `startTime` parameter must be a field name.
   */
  endTime: DateProperties;
  /** The desired units of the age result. */
  unit?: SmartMappingTimeUnit | null;
  /** The view in which features will be rendered. */
  view?: MapViewOrSceneView | null;
  /**
   * Indicates the statistics to calculate. If not defined, all statistics are calculated by default. The object should have the following properties.
   *
   * @since 4.31
   */
  outStatisticTypes?: OutStatisticTypes | 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;
}

export interface Attribute {
  /** The name of a numeric field. */
  field?: string | null;
  /**
   * 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 may reference field values using the `$feature` profile variable and must return
   *   a number. This property overrides the `field` property and therefore is used instead of an input `field`
   *   value if both are specified.
   */
  valueExpression?: string | null;
  /**
   * The label describing the field name (or category) in the legend. This is should be used
   *   if the given field doesn't have an intuitive field name or alias. For example, for a field named `dem` representing the total vote count
   *   for the Democratic party, you can set the label to `Democrat` to clarify the name of the category in the final visualization.
   */
  label?: string | null;
  /**
   * Text describing the value returned from
   *   the `valueExpression`. This will display in the legend.
   */
  valueExpressionTitle?: string | null;
}