import type LineOfSightLayer from "../../layers/LineOfSightLayer.js";
import type LineOfSightAnalysisView3D from "../3d/analysis/LineOfSightAnalysisView3D.js";
import type { AbortOptions } from "../../core/promiseUtils.js";
import type { LineOfSightPlacementResult } from "../3d/analysis/LineOfSight/types.js";

export interface LineOfSightLayerViewMixinProperties extends Partial<Pick<LineOfSightLayerViewMixin, "interactive">> {}

export abstract class LineOfSightLayerViewMixin {
  constructor(...args: any[]);
  /**
   * Enables interactivity for the [layer](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-layers-LineOfSightLayerViewMixin.html#layer). When set to `true`, manipulators will be displayed,
   * allowing users to click and drag to edit the layer's
   * [LineOfSightLayer#analysis](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-LineOfSightLayer.html#analysis) if it has a valid
   * [LineOfSightAnalysis#observer](https://developers.arcgis.com/javascript/latest/api-reference/esri-analysis-LineOfSightAnalysis.html#observer) and
   * [LineOfSightAnalysis#targets](https://developers.arcgis.com/javascript/latest/api-reference/esri-analysis-LineOfSightAnalysis.html#targets). Right-clicking a target will remove it.
   *
   * This property is automatically set to `true` when the analysis is assigned to a
   * [Line Of Sight component](https://developers.arcgis.com/javascript/latest/references/map-components/arcgis-line-of-sight/).
   *
   * @default false
   */
  accessor interactive: boolean;
  /** The layer being viewed. */
  get layer(): LineOfSightLayer;
  /**
   * Analysis results for each target.
   *
   * The order of results matches the order of targets, so if the index of the target is known the collection can be
   * indexed directly:
   *
   * ```js
   * const layerView = await view.whenLayerView(lineOfSightLayer);
   * const result = layerView.results.at(targetIdx);
   * ```
   *
   * Given a [target](https://developers.arcgis.com/javascript/latest/api-reference/esri-analysis-LineOfSightAnalysisTarget.html) object, the results collection can also be
   * searched:
   *
   * ```js
   * const result = layerView.results.find((result) => result.target === targetObject);
   * ```
   */
  get results(): LineOfSightAnalysisView3D["results"];
  /**
   * Starts the interactive placement of an observer and/or targets on the [layer](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-layers-LineOfSightLayerViewMixin.html#layer)'s
   * [LineOfSightLayer#analysis](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-LineOfSightLayer.html#analysis).
   *
   * If the analysis does not have a valid observer yet, this method will allow placing an observer, which can be followed
   * by zero or more targets. Otherwise, if it already has a valid observer, it will allow placing targets.
   *
   * 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.
   * The promise resolves when the operation is productive, i.e. an oberver or any targets were added.
   * Otherwise, if nothing was added or signal was aborted, the promise is rejected.
   *
   * Calling this method sets [interactive](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-layers-LineOfSightLayerViewMixin.html#interactive) to `true`.
   *
   * @param options - An object specifying additional options.
   * @returns A promise
   * which resolves when the operation is completed successfully - i.e. the user places an observer and/or target(s),
   * leaving the analysis in a valid state. Otherwise, the promise is rejected.
   * @since 4.33
   * @example
   * const abortController = new AbortController();
   *
   * try {
   *   await layerView.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<LineOfSightPlacementResult>;
}