/**
 * Provides the utility function to convert image coordinates to geographic coordinates.
 * This function is currently utilized in the Oriented Imagery widget to extract geographic world locations in the map-image location tool and for constructing the current footprint generated for the images displayed in the oriented imagery widget.
 *
 * @beta
 * @since 4.31
 * @see [OrientedImageryLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-OrientedImageryLayer.html)
 * @see [OrientedImageryViewer](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-OrientedImageryViewer.html)
 * @see [Sample - Creating an OrientedImageryLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-orientedImagery-transformations-imageToWorld.html#creating-an-orientedimagerylayer)
 */
import type Point from "../../../geometry/Point.js";
import type { ReadonlyArrayOrCollection } from "../../../core/Collection.js";
import type { ImageToWorldProperties, UpdateElevationProps } from "./types.js";
import type { LocationInImageSpace } from "../../../widgets/OrientedImageryViewer/types.js";

/**
 * Transforms image coordinates in pixels to a point or an array of points specifying the corresponding geographic world coordinates. The function supports both single points and collections of points.
 *
 * @param pixelOrPixels - A single `Pixel` object or an `ArrayOrCollection<Pixel>` representing the image coordinates in `x` and `y` (in rows and columns) to be transformed. Here (0, 0) corresponds to the center of the upper left pixel.
 * @param properties - An object containing the properties required for the transformation, such as camera location, rotation matrix, and image dimensions.
 * @param updateElevationProps - An object containing the properties required for correcting the elevation of the output point, resulting in a more accurate z-value. This is an optional parameter.
 * @returns A `Point` object if a single pixel is provided, or an array of `Point` objects if a collection of pixels is provided.
 * @example
 * const pixel = {
 *    x: 2601.062988,
 *    y: 1297.00708,
 *    };
 *
 * const properties: {
 *    affineTransformations: [2015.5, 1, 0, 1511.5, 0, -1],
 *    averageElevation: 0,
 *    cameraLocation: new Point({
 *      x: -13045995.27,
 *      y: 4036379.178,
 *      z: 1.549999952,
 *      spatialReference: SpatialReference.WebMercator,
 *    }),
 *    cameraPitch: 90,
 *    cameraRoll: 0,
 *    farDistance: 30,
 *    horizontalFieldOfView: 65.47045135,
 *    imageHeight: 3024,
 *    imageWidth: 4032,
 *    rotationMatrix: [
 *      -0.6710996455056446, 4.539564596921633e-17, -0.7413671599161904,
 *      -0.7413671599161904, -4.1093001638870556e-17, 0.6710996455056446,
 *       0, 1, 6.123233995736766e-17
 *     ],
 *    verticalFieldOfView: 46.39718246,
 * },
 *
 * const groundLocation = imageToWorld(pixel, properties);
 * console.log(imageLocation);
 */
export function imageToWorld(pixelOrPixels: LocationInImageSpace | ReadonlyArrayOrCollection<LocationInImageSpace>, properties: ImageToWorldProperties, updateElevationProps?: UpdateElevationProps): Promise<Point | Point[]>;