import type SpatialReferenceClass from "../geometry/SpatialReference.js";

export type Color = [
    number,
    number,
    number,
    number
] | [
    number,
    number,
    number
];

export type LabelPosition = "curved" | "parallel";

export interface FeatureTemplatePrototype {
  attributes?: Record<string, any>;
}

export interface FeatureTemplateThumbnail {
  /** The MIME type of the image. */
  contentType: "png" | "jpg" | "jpeg" | "image";
  /** The height of the thumbnail. */
  height: number;
  /**
   * The [base64EncodedImageData](https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/Base64_encoding_and_decoding)
   * presenting the thumbnail image.
   */
  imageData: string;
  /** The width of the thumbnail. */
  width: number;
}

export interface Point {
  /** The m value of the camera position. */
  m?: number;
  /** The spatial reference of the camera position. If not specified, the spatial reference of the video layer is used. */
  spatialReference?: SpatialReferenceClass | null;
  /** The x coordinate of the anchor point, measured along the east/west axis. */
  x: number;
  /** The y coordinate of the anchor point, measured along the north/south axis. */
  y: number;
  /** The z coordinate of the camera position. */
  z?: number;
}

/** An envelope is a rectangle defined by a range of values for each coordinate and attribute. */
export interface Extent {
  /** The maximum X value in the area of the envelope. */
  xmax: number;
  /** The minimum X value in the area of the envelope. */
  xmin: number;
  /** The maximum Y value in the area of the envelope. */
  ymax: number;
  /** The minimum Y value in the area of the envelope. */
  ymin: number;
}

/**
 * The **VideoServiceLayerInfo** defines layer information for video layers published within the same
 * video service.
 */
export interface VideoServiceLayerInfo {
  /** The layer id of the video layer. */
  layerId: number;
  /** The URL to the poster image for the video layer. */
  posterUrl: string;
  /** The source type of the video layer. */
  sourceType: VideoSourceType;
  /** The title of the video layer. */
  title: string;
  /** The layer type. The type is always "Video Layer" for VideoLayers. */
  type: "Video Layer";
}

export type VideoSourceType = "ondemand" | "livestream";

export interface VideoGroundControlPoint {
  /** The latitude. */
  lat: number;
  /** The longitude. */
  lon: number;
  /** The x coordinate in pixels. */
  x: number;
  /** The y coordinate in pixels. */
  y: number;
}

export type VideoQuality = "sd" | "hd" | "fhd" | "qhd" | "uhd";

/** The **Codecs** is an object that represents the codecs used by the video layer. */
export interface Codecs {
  /** The audio codec used in the video layer. */
  audio: string;
  /** The text codec used in the video layer. */
  text: string;
  /** The video codec used in the video layer. */
  video: string;
}

/**
 * The **CameraInfo** is an object that represents the camera information of the video layer.
 *
 * @since 4.34
 */
export interface VideoCameraInfo {
  /** The far distance of the camera in meters. */
  farDistance: number;
  /** The field of view of the camera in degrees. */
  fov: number;
  /** The heading of the camera in degrees. */
  heading: number;
  /** The height of the camera in meters. */
  height: number;
  /** The near distance of the camera in meters. */
  nearDistance: number;
  /** The position of the camera. */
  position: Point;
  /** The tilt of the camera in degrees. */
  tilt: number;
}

/**
 * A JSON Feature object that can be added to a [StreamLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-StreamLayer.html) on the client by calling its
 * [sendMessageToClient()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-StreamLayer.html#sendMessageToClient) method.
 * It is an esri Feature JSON object as defined in the
 * [Feature object specification](https://next.gha.arcgis.com/documentation/common-data-types/feature-object.htm).
 */
export interface Feature {
  /** Name-value pairs of fields and field values associated with the received data. */
  attributes: Record<string, any>;
  /**
   * A location of the received data containing x, y coordinates for points, paths for lines, and rings for polygons, along with
   * the spatial reference wkid.
   */
  geometry?: object | null;
}

export type GeometryType = "esriGeometryPoint" | "esriGeometryPolyline" | "esriGeometryPolygon" | "esriGeometryEnvelope" | "esriGeometryMultiPatch" | "esriGeometryMultipoint";

export interface SimpleTransformation {
  /** the spatial reference well known id */
  wkid: number;
}

export interface CompositeTransformation {
  geoTransforms: GeoTransform[];
}

export interface GeoTransform {
  /** indicates whether to transform forward or not. */
  transformForward: boolean;
  /** the spatial reference well known id. */
  wkid: number;
}

export type DatumTransformation = number | SimpleTransformation | CompositeTransformation;

export type SQLFormat = "none" | "native" | "standard";

export interface Progressor {
  /** Progress message. */
  message: string;
  /** Progress percentage. */
  percent?: number;
}

export type FormElementType = "field" | "attachment" | "group" | "relationship" | "text" | "utilityNetworkAssociations";

export type TimeResolution = "minutes" | "seconds";

export type TimeResolutionMS = TimeResolution | "milliseconds";

export type InputMethod = "any" | "capture" | "upload";

export type FormAttachmentAssociationType = "any" | "exact" | "exactOrNone";

export type GroupState = "collapsed" | "expanded";

export type TextFormatType = "plain-text" | "markdown";

export type FormExpressionReturnType = "boolean" | "date" | "number" | "string";

export type TableElementType = "group" | "field" | "attachment" | "relationship";

export type LayoutType = "basic-grid" | "chronological-mono-timeline" | "chronological-multi-timeline" | "geographic-organic-standard" | "hierarchical-bottom-to-top" | "hierarchical-top-to-bottom" | "organic-community" | "organic-fusiform" | "organic-leaf-circle" | "organic-standard" | "radial-node-centric" | "radial-root-centric" | "tree-bottom-to-top" | "tree-left-to-right" | "tree-right-to-left" | "tree-top-to-bottom";

export type TimeDirection = "bottom" | "left" | "right" | "top";