import type AreaMeasurementAnalysis from "../../../analysis/AreaMeasurementAnalysis.js";
import type AnalysisView3D from "./AnalysisView3D.js";
import type { AbortOptions } from "../../../core/promiseUtils.js";
import type { AreaMeasurementPlacementResult, AreaMeasurementResult } from "../../analysis/AreaMeasurement/types.js";

/**
 * Represents the analysis view of an [AreaMeasurementAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/AreaMeasurementAnalysis/)
 * after it has been added to [SceneView.analyses](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#analyses).
 *
 * The AreaMeasurementAnalysisView3D is responsible for rendering a [AreaMeasurementAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/AreaMeasurementAnalysis/)
 * using custom visualizations.
 *
 * It allows to create a new analysis interactively using the [place()](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/AreaMeasurementAnalysisView3D/#place) method, query the measured [result](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/AreaMeasurementAnalysisView3D/#result),
 * or make an existing analysis editable by enabling the [interactive](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/AreaMeasurementAnalysisView3D/#interactive) property.
 *
 * The view for an analysis can be retrieved using [SceneView.whenAnalysisView()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#whenAnalysisView)
 * similar to how layer views are retrieved for layers using [SceneView.whenLayerView()](https://developers.arcgis.com/javascript/latest/references/core/views/SceneView/#whenLayerView).
 *
 * ```js
 * // retrieve analysis view for analysis
 * const analysis = new AreaMeasurementAnalysis();
 * view.analyses.add(analysis); // add to the scene view
 * const analysisView = await view.whenAnalysisView(analysis);
 * ```
 *
 * > [!WARNING]
 * >
 * > **Things to consider:**
 * > Snapping is enabled by default. This can be temporarily disabled by holding the `CTRL` key.
 * > Layer types currently supported for snapping are: [FeatureLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/), [GraphicsLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GraphicsLayer/) (except Mesh geometries),
 * > [GeoJSONLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/GeoJSONLayer/), [WFSLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/WFSLayer/), [CSVLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/CSVLayer/),
 * > [3D Object SceneLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/SceneLayer/), and [BuildingSceneLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/BuildingSceneLayer/).
 *
 * @see [AreaMeasurementAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/AreaMeasurementAnalysis/)
 * @see [Area Measurement 3D component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-area-measurement-3d/)
 * @see [Sample - Area measurement analysis object](https://developers.arcgis.com/javascript/latest/sample-code/analysis-area-measurement/)
 * @see [Sample - Analysis objects](https://developers.arcgis.com/javascript/latest/sample-code/analysis-objects/)
 */
export default abstract class AreaMeasurementAnalysisView3D extends AnalysisView3D {
  /**
   * The area measurement analysis object associated with the analysis view.
   *
   * @since 4.24
   */
  get analysis(): AreaMeasurementAnalysis;
  /**
   * Enables interactivity for the [analysis](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/AreaMeasurementAnalysisView3D/#analysis). When set to `true`, manipulators will be displayed, allowing
   * users to click and drag to edit the analysis if it has a valid
   * [AreaMeasurementAnalysis.geometry](https://developers.arcgis.com/javascript/latest/references/core/analysis/AreaMeasurementAnalysis/#geometry).
   *
   * This property is automatically set to `true` when the analysis is assigned to an
   * [Area Measurement 3D component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-area-measurement-3d/).
   *
   * @default false
   * @since 4.33
   */
  accessor interactive: boolean;
  /**
   * Result of the area measurement analysis. Result objects are created immediately but they are gradually updated as
   * the analysis is computed.
   */
  get result(): AreaMeasurementResult | null | undefined;
  /**
   * The analysis view type.
   *
   * @since 4.24
   */
  get type(): "area-measurement-view-3d";
  /**
   * When `true`, the analysis is visualized in the view.
   *
   * @since 4.24
   */
  accessor visible: boolean;
  /**
   * Starts the interactive placement of an area measurement.
   *
   * If the analysis does not have a [AreaMeasurementAnalysis.geometry](https://developers.arcgis.com/javascript/latest/references/core/analysis/AreaMeasurementAnalysis/#geometry) yet, the method allows creating one
   * interactively in the view. If the analysis already has a measurement, clicking in the view will remove it and
   * start the placement of a new geometry.
   *
   * The placement operation will finish when the user presses the escape key.
   * To stop the placing programmatically, pass an abort signal as an argument when calling the method.
   *
   * Calling this method sets [interactive](https://developers.arcgis.com/javascript/latest/references/core/views/3d/analysis/AreaMeasurementAnalysisView3D/#interactive) to `true`.
   *
   * @param options - An object specifying additional options.
   * @returns A promise which resolves when the operation is completed successfully or rejected if it is canceled.
   * @since 4.33
   * @example
   * const abortController = new AbortController();
   *
   * try {
   *   await analysisView.place({ signal: abortController.signal });
   * } catch (error) {
   *   if (error.name === "AbortError") {
   *     console.log("Placement operation was cancelled.");
   *   }
   * }
   *
   * // cancel the placement operation at some later point
   * abortController.abort();
   */
  place(options?: AbortOptions | null | undefined): Promise<AreaMeasurementPlacementResult>;
}