/**
 * Imagery utility functions for Web Components.
 *
 * @internal
 * @internal
 */
import type Extent from "../../geometry/Extent.js";
import type Multipoint from "../../geometry/Multipoint.js";
import type Point from "../../geometry/Point.js";
import type Polygon from "../../geometry/Polygon.js";
import type Polyline from "../../geometry/Polyline.js";
import type ImageryLayer from "../../layers/ImageryLayer.js";
import type ImageryTileLayer from "../../layers/ImageryTileLayer.js";
import type WCSLayer from "../../layers/WCSLayer.js";
import type FeatureSet from "../../rest/support/FeatureSet.js";
import type { AbortOptions } from "../../core/promiseUtils.js";

/**
 * Fetch pixels as point features using the provided geometry.
 * Returned features are in the layer's spatial reference.
 *
 * @param layer - The layer object.
 * @param parameters - An object with the following properties.
 * @param options - An object with the following properties.
 * @returns Resolves to an object containing the pixels as point features.
 * @internal
 * @internal
 */
export function fetchPixelFeatureSet(layer: ImageryLayer | ImageryTileLayer | WCSLayer, parameters: PixelFeatureSetParameters, options?: AbortOptions): Promise<object>;

/**
 * @internal
 * @internal
 */
export interface ImagePixelBlockParameters {
  /**
   * The geometry.
   *
   * @internal
   */
  geometry: Extent | Polygon | Polyline;
  /**
   * The request pixel size. Default to source pixel size of the layer.
   *
   * @internal
   */
  pixelSize?: Point | null;
  /**
   * When true, auto resample the image (reading pyramid) to reduce the amount of reading and result features.
   *
   * @internal
   */
  autoResample?: boolean | null;
  /**
   * Auto resample (reading pyramid) is performed based on the provided maximum pixel count.
   *
   * @internal
   */
  maxPixelCount?: number | null;
}

/**
 * @internal
 * @internal
 */
export interface PixelFeatureSetParameters extends ImagePixelBlockParameters {
  /**
   * Sample pixels by skipping provided number of rows and cols.
   *
   * @internal
   */
  skipFactor?: number | null;
}

/**
 * Read intersecting pixels for the provided area of interest.
 *
 * @param layer - The layer object.
 * @param parameters - An object with the following properties.
 * @param options - An object with the following properties.
 * @returns Resolves to an array of objects, each element contain the intersected pixel center location and value.
 * @internal
 * @internal
 */
export function readIntersectingPixels(layer: ImageryTileLayer | ImageryLayer | WCSLayer, parameters: ReadIntersectingPixelsParameters, options?: AbortOptions): Promise<object[]>;

/**
 * @internal
 * @internal
 */
export interface ReadIntersectingPixelsParameters {
  /**
   * The geometry.
   *
   * @internal
   */
  geometry: Polygon | Extent | Polyline;
}

/**
 * Compute a raster attribute table for the provided area of interest.
 *
 * @param layer - The layer object.
 * @param parameters - An object with the following properties.
 * @param options - An object with the following properties.
 * @returns Resolves to a raster attribute table object.
 * @internal
 * @internal
 */
export function computeRasterAttributeTable(layer: ImageryTileLayer | ImageryLayer | WCSLayer, parameters: ComputeRasterAttributeTableParameters, options?: AbortOptions): Promise<FeatureSet | null | undefined>;

/**
 * @internal
 * @internal
 */
export interface ComputeRasterAttributeTableParameters {
  /**
   * The geometry.
   *
   * @internal
   */
  geometry: Extent | Polygon | Polyline;
}

/**
 * A read cursor that iterates over the image using a fixed size pixel blocks and
 * return as point features in the layer's spatial reference.
 * Point id is arbitrary.
 *
 * @param layer - The layer object.
 * @param parameters - An object with the following properties.
 * @param options - An object with the following properties.
 * @returns Returns async generator, each part resolves to an object containing the extent and feature set that represent pixel centers.
 * @internal
 * @internal
 */
export function createPixelFeatureSetCursor(layer: ImageryTileLayer | ImageryLayer | WCSLayer, parameters?: PixelFeatureSetCursorParameters, options?: AbortOptions): AsyncGenerator<any>;

/**
 * @internal
 * @internal
 */
export interface PixelFeatureSetCursorParameters {
  /**
   * The geometry, default to layer's full extent.
   *
   * @internal
   */
  geometry?: Extent | Polygon | Polyline | null;
  /**
   * Sample pixels by skipping provided number of rows and cols.
   *
   * @internal
   */
  skipFactor?: number | null;
}

/**
 * Compute box statistics for the provided area of interest.
 *
 * @param layer - The layer object.
 * @param parameters - An object with the following properties.
 * @param options - An object with the following properties.
 * @returns Resolves to an array, each element represent the box statistics of that band, including min, max, avg, median, quantile1 and quantile3.
 * @internal
 * @internal
 */
export function computeBoxStatistics(layer: ImageryTileLayer | ImageryLayer | WCSLayer, parameters: ComputeBoxStatisticsParameters, options?: AbortOptions): Promise<object[] | null | undefined>;

/**
 * @internal
 * @internal
 */
export interface ComputeBoxStatisticsParameters {
  /**
   * The geometry.
   *
   * @internal
   */
  geometry: Polygon | Extent | Polyline | Multipoint;
}

/**
 * Compute statistics and histograms in an area of interest.
 *
 * @param layer - The layer object.
 * @param parameters - An object with the following properties.
 * @param options - An object with the following properties.
 * @returns Resolves to an object containing histogram and statistics results.See the object specification table below for details.
 *
 * Property | Type | Description
 * ---------|------|-------------
 * histograms[] | [RasterHistogram](https://developers.arcgis.com/javascript/latest/references/core/layers/raster/types/#RasterHistogram) | Result containing raster histograms.
 * bandStatistics[] | [RasterBandStatistics](https://developers.arcgis.com/javascript/latest/references/core/layers/raster/types/#RasterBandStatistics) | Raster band statistics.
 * @internal
 * @internal
 */
export function computeStatisticsHistograms(layer: ImageryTileLayer | ImageryLayer | WCSLayer, parameters: PixelStatisticsParameters, options?: AbortOptions): Promise<object>;

/**
 * @internal
 * @internal
 */
export interface PixelStatisticsParameters {
  /**
   * The geometry.
   *
   * @internal
   */
  geometry: Polygon | Extent | Polyline;
  /**
   * The request pixel size. Default to source pixel size of the layer.
   *
   * @internal
   */
  pixelSize?: Point | null;
  /**
   * The transform type for pixel values. Default is not transformed.
   *
   * @internal
   */
  transformType?: "log" | "sqrt" | "inverse" | "box-cox";
  /**
   * Lambda for box-cox transform type. Default is 0.
   *
   * @internal
   */
  lambda?: number;
  /**
   * Shift for box-cox transform type. Default is 0.
   *
   * @internal
   */
  shift?: number;
  /**
   * The list of band ids.
   *
   * @internal
   */
  bandIds?: number[];
  /**
   * The size of the histogram. Default is up to 256.
   *
   * @internal
   */
  histogramSize?: number;
  /**
   * Field name from raster attribute table.
   *
   * @internal
   */
  valueAttributeFieldName?: string;
}

/**
 * Identify average pixel value for the provided area of interest.
 *
 * @param layer - The layer object.
 * @param parameters - An object with the following properties.
 * @param options - An object with the following properties.
 * @returns Resolves to an array of numbers, each element represented the average for the band.
 * @internal
 * @internal
 */
export function identifyAveragePixelValue(layer: ImageryTileLayer | ImageryLayer | WCSLayer, parameters: IdentityAveragePixelValueParameters, options?: AbortOptions): Promise<number[] | null | undefined>;

/**
 * @internal
 * @internal
 */
export interface IdentityAveragePixelValueParameters {
  /**
   * The geometry.
   *
   * @internal
   */
  geometry: Polygon | Extent | Polyline | Multipoint | Point;
}