import type OrderByInfo from "../support/OrderByInfo.js";
import type { OrderByInfoProperties } from "../support/OrderByInfo.js";

export interface OrderedLayerProperties {
  /**
   * Determines the order in which features are drawn in the view. You
   * can sort features by a field value or the value returned from an
   * [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) expression in ascending or descending order.
   *
   * When `null` (default), features are drawn in the order they are returned from
   * the service or client.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > - This property only controls feature drawing order in [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/). Configuring
   * > feature drawing order in [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/) is not supported.
   * > - This property does not control the drawing order of clusters. It only applies to individual features.
   * > - Feature drawing order configurations defined with Arcade expressions cannot be [saved](https://developers.arcgis.com/javascript/latest/references/core/WebMap/#save) to web maps.
   * > - Currently, you can only sort features by one field or expression.
   *
   * @since 4.21
   * @see [Arcade Feature Z Profile](https://developers.arcgis.com/javascript/latest/arcade/#feature-sorting)
   * @example
   * // Features with smaller population values will
   * // be rendered on top of larger features.
   * layer.orderBy = [{
   *   field: "POPULATION"
   * }];
   * @example
   * // Features with larger population values will
   * // be rendered on top of smaller features.
   * layer.orderBy = [{
   *   field: "POPULATION",
   *   order: "descending"
   * }];
   * @example
   * // Orders features by date in descending order.
   * // The most recent features will be rendered
   * // on top of older features.
   * layer.orderBy = [{
   *   field: "Alarm_Date",
   *   order: "descending"
   * }];
   * @example
   * // Orders features by storm warning duration in descending order.
   * // Warnings with longer durations
   * // be rendered on top of warnings with shorter durations.
   * layer.orderBy = [{
   *   valueExpression: "DateDiff($feature.Watch_End, $feature.Watch_Start, 'hours' )",
   *   order: "descending"
   * }];
   * @example
   * // Orders features by data values used in a size visual variable
   * const sizeVariable = layer.renderer.visualVariables.find( vv => vv.type === "size");
   * const { field, valueExpression } = sizeVariable;
   * layer.orderBy = [{
   *   field,
   *   valueExpression,
   *   order: "ascending"
   * }];
   */
  orderBy?: OrderByInfoProperties[] | null;
}

/**
 * Mixin for layers that support orderBy.
 *
 * @since 4.21
 */
export abstract class OrderedLayer {
  constructor(...args: any[]);
  /**
   * Determines the order in which features are drawn in the view. You
   * can sort features by a field value or the value returned from an
   * [Arcade](https://developers.arcgis.com/javascript/latest/arcade/) expression in ascending or descending order.
   *
   * When `null` (default), features are drawn in the order they are returned from
   * the service or client.
   *
   * > [!WARNING]
   * >
   * > **Known Limitations**
   * >
   * > - This property only controls feature drawing order in [MapView](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/). Configuring
   * > feature drawing order in [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/) is not supported.
   * > - This property does not control the drawing order of clusters. It only applies to individual features.
   * > - Feature drawing order configurations defined with Arcade expressions cannot be [saved](https://developers.arcgis.com/javascript/latest/references/core/WebMap/#save) to web maps.
   * > - Currently, you can only sort features by one field or expression.
   *
   * @since 4.21
   * @see [Arcade Feature Z Profile](https://developers.arcgis.com/javascript/latest/arcade/#feature-sorting)
   * @example
   * // Features with smaller population values will
   * // be rendered on top of larger features.
   * layer.orderBy = [{
   *   field: "POPULATION"
   * }];
   * @example
   * // Features with larger population values will
   * // be rendered on top of smaller features.
   * layer.orderBy = [{
   *   field: "POPULATION",
   *   order: "descending"
   * }];
   * @example
   * // Orders features by date in descending order.
   * // The most recent features will be rendered
   * // on top of older features.
   * layer.orderBy = [{
   *   field: "Alarm_Date",
   *   order: "descending"
   * }];
   * @example
   * // Orders features by storm warning duration in descending order.
   * // Warnings with longer durations
   * // be rendered on top of warnings with shorter durations.
   * layer.orderBy = [{
   *   valueExpression: "DateDiff($feature.Watch_End, $feature.Watch_Start, 'hours' )",
   *   order: "descending"
   * }];
   * @example
   * // Orders features by data values used in a size visual variable
   * const sizeVariable = layer.renderer.visualVariables.find( vv => vv.type === "size");
   * const { field, valueExpression } = sizeVariable;
   * layer.orderBy = [{
   *   field,
   *   valueExpression,
   *   order: "ascending"
   * }];
   */
  get orderBy(): OrderByInfo[] | null | undefined;
  set orderBy(value: OrderByInfoProperties[] | null | undefined);
}