import type Analysis from "./Analysis.js";
import type VolumeMeasurementCutFillOptions from "./VolumeMeasurement/VolumeMeasurementCutFillOptions.js";
import type VolumeMeasurementDisplayUnits from "./VolumeMeasurement/VolumeMeasurementDisplayUnits.js";
import type VolumeMeasurementInputUnits from "./VolumeMeasurement/VolumeMeasurementInputUnits.js";
import type Polygon from "../geometry/Polygon.js";
import type { AnalysisProperties } from "./Analysis.js";
import type { VolumeMeasureType } from "./VolumeMeasurement/types.js";
import type { VolumeMeasurementCutFillOptionsProperties } from "./VolumeMeasurement/VolumeMeasurementCutFillOptions.js";
import type { VolumeMeasurementDisplayUnitsProperties } from "./VolumeMeasurement/VolumeMeasurementDisplayUnits.js";
import type { VolumeMeasurementInputUnitsProperties } from "./VolumeMeasurement/VolumeMeasurementInputUnits.js";
import type { PolygonProperties } from "../geometry/Polygon.js";

export interface VolumeMeasurementAnalysisProperties extends AnalysisProperties, Partial<Pick<VolumeMeasurementAnalysis, "measureType">> {
  /** The configuration used when the [measureType](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurementAnalysis/#measureType) is set to "cut-fill". */
  cutFillOptions?: VolumeMeasurementCutFillOptionsProperties;
  /** Units used for displaying values in the UI. */
  displayUnits?: VolumeMeasurementDisplayUnitsProperties;
  /**
   * A polygon that defines the boundary for volume measurement computations and visualizations for all measure types.
   *
   * If the polygon has [z-values](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polygon/#hasZ) these will be ignored
   * as the polygon will be projected on the ground.
   */
  geometry?: PolygonProperties | null;
  /** Units used for interpreting input values. */
  inputUnits?: VolumeMeasurementInputUnitsProperties;
}

/**
 * > [!CAUTION]
 * >
 * > VolumeMeasurementAnalysis is currently in beta.
 * > To learn about features in beta, see the [Frequently Asked Questions](https://developers.arcgis.com/javascript/latest/faq/#what-does-the-beta-tag-mean).
 *
 * VolumeMeasurementAnalysis calculates and visualizes the volume of ground surfaces within a
 * defined polygonal area, offering multiple measure types and displaying results in a 3D [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
 *
 * The measure type is set with the [measureType](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurementAnalysis/#measureType) property, and can be further
 * customized using optional, type-specific [options](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurement/VolumeMeasurementCutFillOptions/).
 *
 * To display a volume measurement of a ground surface bounded by a given [Polygon](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polygon/):
 * - Create a new instance of VolumeMeasurementAnalysis.
 * - Set the [measureType](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurementAnalysis/#measureType) property.
 * - Set the [geometry](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurementAnalysis/#geometry) property to the given [Polygon](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polygon/) instance.
 * - If using the "cut-fill" [measureType](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurementAnalysis/#measureType), optionally set custom properties with
 * [VolumeMeasurementCutFillOptions](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurement/VolumeMeasurementCutFillOptions/).
 * - Add the VolumeMeasurementAnalysis instance to [SceneView.analyses](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#analyses).
 *
 * Use the [VolumeMeasurementAnalysisView3D](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/VolumeMeasurementAnalysisView3D/) to retrieve the
 * analysis [result](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/VolumeMeasurement/VolumeMeasurementResult/).
 *
 * ```js
 * // create analysis
 * const volumeMeasurementAnalysis = new VolumeMeasurementAnalysis({
 *   measureType: "stockpile", // if not set it defaults to "cut-fill"
 *   geometry: new Polygon({ }),
 * });
 *
 * // add to scene view
 * view.analyses.add(volumeMeasurementAnalysis);
 *
 * // retrieve the result from the analysis view once available
 * const analysisView = await view.whenAnalysisView(volumeMeasurementAnalysis);
 * await reactiveUtils.whenOnce(() => analysisView.result);
 *
 * const result = analysisView.result;
 * ```
 *
 * To draw a volume measurement polygon interactively, use the
 * [VolumeMeasurementAnalysisView3D.place()](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/VolumeMeasurementAnalysisView3D/#place) method.
 *
 * ```js
 * // cancel the placement operation at some later point
 * // by calling abortController.abort()
 * const abortController = new AbortController();
 *
 * try {
 *   await analysisView.place({ signal: abortController.signal });
 * } catch (error) {
 *   if (error.name === "AbortError") {
 *     console.log("Placement operation was cancelled.");
 *   }
 * }
 * ```
 * The analysis depends on the scene's spatial reference, and the length of the measured perimeter:
 *
 * - In **Projected Coordinate Systems (PCS)**, apart from Web Mercator used in **local** viewing mode, there is no limit
 * to the measurement's perimeter, making it the recommended setup for analysis as accuracy is not compromised.
 *
 * - In **Web Mercator PCS** used in **local** viewing mode, if the measurement's perimeter exceeds 10 km, the analysis
 * is considered invalid due to potential accuracy issues.
 *
 * - In **Geographic Coordinate Systems (GCS)** and **Web Mercator** in **global** viewing mode, if the measurement's
 * perimeter exceeds 50 km, the analysis is considered invalid due to potential accuracy issues.
 *
 * In certain situations (including information in Known Limitations below), the
 * [analysis result](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/VolumeMeasurement/VolumeMeasurementResult/) cannot be computed.
 * Refer to the [VolumeMeasurementAnalysisView3D.error](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/VolumeMeasurementAnalysisView3D/#error) property for more information.
 *
 * > [!WARNING]
 * >
 * > **Known Limitations**
 * >
 * > - This analysis is only supported in a 3D [SceneView](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/).
 * > - The results of the tool vary depending on the zoom level, as changes in zoom level affect the level of detail (LOD) of the scene geometry.
 * > - If the view is too close or too far from the measurement polygon, the results will not be computed due to LOD-induced inaccuracies.
 * > - The target elevation ("cut-fill" measureType) is restricted to the range between -11 km and +9 km.
 * > - This analysis operates only on the non-transparent [Map.ground](https://developers.arcgis.com/javascript/latest/references/core/Map/#ground), [IntegratedMeshLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/IntegratedMeshLayer/) and an [IntegratedMesh3DTilesLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/IntegratedMesh3DTilesLayer/).
 * > - This analysis does not support WGS 1984 spatial reference in a local [viewing mode](https://developers.arcgis.com/javascript/latest/references/core/webscene/InitialViewProperties/#viewingMode).
 *
 * @beta
 * @since 4.34
 * @see [VolumeMeasurementAnalysisView3D](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/VolumeMeasurementAnalysisView3D/)
 * @see [VolumeMeasurementCutFillOptions](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurement/VolumeMeasurementCutFillOptions/)
 * @see [VolumeMeasurementResult](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/VolumeMeasurement/VolumeMeasurementResult/)
 * @see [VolumeMeasurementDisplayUnits](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurement/VolumeMeasurementDisplayUnits/)
 * @see [VolumeMeasurementInputUnits](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurement/VolumeMeasurementInputUnits/)
 * @see [VolumeMeasurementError](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/VolumeMeasurement/VolumeMeasurementError/)
 * @see [Async cancellation with AbortController](https://developers.arcgis.com/javascript/latest/async-cancellation-with-abortcontroller/)
 * @see [Sample - Volume measurement analysis object](https://developers.arcgis.com/javascript/latest/sample-code/analysis-volume-measurement/)
 */
export default class VolumeMeasurementAnalysis extends Analysis {
  constructor(properties?: VolumeMeasurementAnalysisProperties);
  /** The configuration used when the [measureType](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurementAnalysis/#measureType) is set to "cut-fill". */
  get cutFillOptions(): VolumeMeasurementCutFillOptions;
  set cutFillOptions(value: VolumeMeasurementCutFillOptionsProperties);
  /** Units used for displaying values in the UI. */
  get displayUnits(): VolumeMeasurementDisplayUnits;
  set displayUnits(value: VolumeMeasurementDisplayUnitsProperties);
  /**
   * A polygon that defines the boundary for volume measurement computations and visualizations for all measure types.
   *
   * If the polygon has [z-values](https://developers.arcgis.com/javascript/latest/references/core/geometry/Polygon/#hasZ) these will be ignored
   * as the polygon will be projected on the ground.
   */
  get geometry(): Polygon | null | undefined;
  set geometry(value: PolygonProperties | null | undefined);
  /** Units used for interpreting input values. */
  get inputUnits(): VolumeMeasurementInputUnits;
  set inputUnits(value: VolumeMeasurementInputUnitsProperties);
  /**
   * Specifies the desired volume measure type.
   *
   * Mode | Description
   * -----|------------
   * "cut-fill"  | Computes cut and fill volumes relative to a flat, horizontal surface defined by the input polygon. [VolumeMeasurementCutFillOptions](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurement/VolumeMeasurementCutFillOptions/) allows setting the elevation of the target surface and the unit of elevation.
   * "stockpile" | Calculates cut and fill volumes against a surface approximated from the input polygon's control points.
   *
   * @default "cut-fill"
   */
  accessor measureType: VolumeMeasureType;
  /** Identifier for the analysis type. */
  get type(): "volume-measurement";
  /**
   * Indicates whether the analysis is ready to be computed and interacted with in the view. It requires the
   * geometry to be a valid polygon whose rings contain at least 4 points, with the first and last points being
   * the same to close the ring.
   */
  get valid(): boolean;
  /**
   * Clears the analysis by resetting the [geometry](https://developers.arcgis.com/javascript/latest/references/core/analysis/VolumeMeasurementAnalysis/#geometry) property.
   *
   * @since 5.0
   */
  clear(): void;
}