import type Analysis from "./Analysis.js";
import type Polyline from "../geometry/Polyline.js";
import type { SystemOrLengthUnit } from "../core/units.js";
import type { PolylineProperties } from "../geometry/Polyline.js";
import type { AnalysisProperties } from "./Analysis.js";

/**
 * Properties that can be used to construct a [DistanceMeasurementAnalysis](https://developers.arcgis.com/javascript/latest/api-reference/esri-analysis-DistanceMeasurementAnalysis.html) instance.
 *
 * @since 5.0
 */
export interface DistanceMeasurementAnalysisProperties extends AnalysisProperties, Partial<Pick<DistanceMeasurementAnalysis, "unit">> {
  /**
   * Polyline whose length is to be computed and displayed in the view.
   *
   * If the polyline has [z-values](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html#hasZ) then these will be treated
   * as absolute values.
   *
   * @since 5.0
   */
  geometry?: PolylineProperties | null;
}

/**
 * DistanceMeasurementAnalysis computes the length of a [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html) in a 2D [MapView](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html).
 *
 * To display a distance measurement, create an instance of a `DistanceMeasurementAnalysis`,
 * assign a [Polyline](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html) to the [geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-analysis-DistanceMeasurementAnalysis.html#geometry) property,
 * and add it to [MapView.analyses](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#analyses)
 *
 * Use the [DistanceMeasurementAnalysisView2D](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-2d-analysis-DistanceMeasurementAnalysisView2D.html) to retrieve analysis results.
 *
 * ```js
 * // create analysis
 * const distanceMeasurement = new DistanceMeasurementAnalysis({
 *   geometry: new Polyline({ })
 * });
 *
 * // add to map view
 * view.analyses.add(distanceMeasurement);
 *
 * // retrieve measured results from analysis view once available
 * const analysisView = await view.whenAnalysisView(distanceMeasurement);
 * await reactiveUtils.whenOnce(() => analysisView.result);
 *
 * const result = analysisView.result;
 * ```
 *
 * To draw a distance measurement interactively, use the
 * [DistanceMeasurementAnalysisView2D.place()](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-2d-analysis-DistanceMeasurementAnalysisView2D.html#place) method.
 *
 * ```js
 * 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();
 * ```
 * > [!WARNING]
 * >
 * > **Known Limitation**
 * >
 * > This analysis is only supported in a 2D [MapView](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html).
 *
 * @since 5.0
 */
export default class DistanceMeasurementAnalysis extends Analysis {
  /** @since 5.0 */
  constructor(properties?: DistanceMeasurementAnalysisProperties);
  /**
   * Polyline whose length is to be computed and displayed in the view.
   *
   * If the polyline has [z-values](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-Polyline.html#hasZ) then these will be treated
   * as absolute values.
   *
   * @since 5.0
   */
  get geometry(): Polyline | null | undefined;
  set geometry(value: PolylineProperties | null | undefined);
  /**
   * The type of analysis. For distance measurement analysis, this is always "distance-measurement".
   *
   * @since 5.0
   */
  get type(): "distance-measurement";
  /**
   * Unit system (imperial, metric) or specific unit used for displaying the computed lengths in the view.
   *
   * @since 5.0
   */
  accessor unit: SystemOrLengthUnit | null | undefined;
  /**
   * Indicates whether the analysis is ready to be computed and interacted with in the view. It requires the
   * geometry to be a valid polyline whose first path contains at least 2 points.
   *
   * @since 5.0
   */
  get valid(): boolean;
  /**
   * Clears the analysis by resetting the [geometry](https://developers.arcgis.com/javascript/latest/api-reference/esri-analysis-DistanceMeasurementAnalysis.html#geometry) property.
   *
   * @since 5.0
   */
  clear(): void;
}