import type Color from "../../Color.js";
import type ElevationProfileLine from "./ElevationProfileLine.js";
import type Multipoint from "../../geometry/Multipoint.js";
import type { ElevationProfileLineProperties } from "./ElevationProfileLine.js";
import type { ElevationQueryResult, ElevationQueryOptions } from "../../layers/support/types.js";
import type { ColorLike } from "../../Color.js";

export interface ElevationProfileLineQueryProperties extends ElevationProfileLineProperties, Partial<Pick<ElevationProfileLineQuery, "source">> {
  /**
   * Color of the line on the chart and in the view.
   *
   * @default "#db334a"
   */
  color?: ColorLike;
}

/**
 * Represents a profile line that samples elevation from a custom elevation source, such as an
 * [ElevationLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ElevationLayer/), or from an elevation layer in
 * [Ground.layers](https://developers.arcgis.com/javascript/latest/references/core/Ground/#layers).
 *
 * You can also provide a custom source object with a `queryElevation` method that matches the signature of
 * [ElevationLayer.queryElevation()](https://developers.arcgis.com/javascript/latest/references/core/layers/ElevationLayer/#queryElevation), allowing for flexible elevation sampling
 * strategies.
 *
 * @since 4.34
 * @see [ElevationProfileAnalysis](https://developers.arcgis.com/javascript/latest/references/core/analysis/ElevationProfileAnalysis/)
 * @example
 * // Create an elevation profile analysis with a custom elevation layer as the source
 * const elevationLayer = new ElevationLayer({
 *   url: "https://sampleserver6.arcgisonline.com/arcgis/rest/services/Elevation/MtBaldy_Elevation/ImageServer"
 * });
 *
 * const analysis = new ElevationProfileAnalysis({
 *   profiles: [{
 *     type: "query",
 *     source: elevationLayer
 *   }]
 * });
 */
export default class ElevationProfileLineQuery extends ElevationProfileLine {
  constructor(properties?: ElevationProfileLineQueryProperties);
  /**
   * Color of the line on the chart and in the view.
   *
   * @default "#db334a"
   */
  get color(): Color;
  set color(value: ColorLike);
  /**
   * Elevation source used to sample elevation when generating the profile, for
   * example an [ElevationLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/ElevationLayer/).
   *
   * @example
   * const elevationLayer = new ElevationLayer({
   *   url: "https://sampleserver6.arcgisonline.com/arcgis/rest/.../Elevation/ImageServer"
   * });
   *
   * // Profile line with elevation layer source
   * const analysis1 = new ElevationProfileAnalysis({
   *   profiles: [{
   *     type: "query", // Autocasts as new ElevationProfileLineQuery(),
   *     source: elevationLayer
   *   }]
   * });
   * @example
   * // Profile line with a source coming from an elevation
   * // layer with a specific sampling resolution
   * const analysis2 = new ElevationProfileAnalysis({
   *   profiles: [{
   *     type: "query",
   *     source: {
   *       queryElevation(geometry, options) {
   *         return elevationLayer.queryElevation(geometry, { ...options, demResolution: 20 })
   *       }
   *     }
   *   }]
   * });
   * @example
   * // Profile line with a source that queries data
   * // on an elevation sampler
   * const sampler = await elevationLayer.createElevationSampler(extent);
   *
   * const analysis3 = new ElevationProfileAnalysis({
   *   profiles: [{
   *     type: "query",
   *     source: {
   *       queryElevation: async (geometry: Multipoint) => {
   *         return {
   *           geometry: await sampler.queryElevation(geometry),
   *           noDataValue: sampler.noDataValue
   *         };
   *       }
   *     }
   *   }]
   * });
   */
  accessor source: ElevationQuerySource;
  /** The line type. */
  readonly type: "query";
}

export interface ElevationQuerySource {
  /**
   * Function used to query elevation values for a [Multipoint](https://developers.arcgis.com/javascript/latest/references/core/geometry/Multipoint/) geometry.
   * It returns a promise that resolves with an [ElevationQueryResult](https://developers.arcgis.com/javascript/latest/references/core/layers/support/types/#ElevationQueryResult).
   *
   * @param geometry - The geometry to use for sampling elevation data.
   * @param options - Additional query options.
   * @returns Resolves to an object with the sampled geometry, resolution information, and no data value.
   */
  queryElevation(geometry: Multipoint, options?: ElevationQueryOptions): Promise<ElevationQueryResult<Multipoint>>;
}