import type MapImageLayer from "../../layers/MapImageLayer.js";
import type GPOptions from "../geoprocessor/GPOptions.js";
import type GPMessage from "./GPMessage.js";
import type ImageParameters from "./ImageParameters.js";
import type ParameterValue from "./ParameterValue.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { Progressor as ProgressorJSON } from "../../portal/jsonTypes.js";
import type { RequestOptions } from "../../request/types.js";
import type { WaitForJobOptions } from "../types.js";
import type { JobStatus } from "./types.js";
import type { GPMessageProperties } from "./GPMessage.js";

export interface JobInfoProperties extends Partial<Pick<JobInfo, "jobId" | "jobStatus" | "requestOptions" | "sourceUrl">> {
  /** An array of messages that include a type and description. */
  messages?: GPMessageProperties[] | null;
}

/**
 * Represents information pertaining to the execution of an asynchronous
 * [geoprocessor](https://developers.arcgis.com/javascript/latest/references/core/rest/geoprocessor/) request on the server.
 *
 * @since 4.20
 * @see [geoprocessor](https://developers.arcgis.com/javascript/latest/references/core/rest/geoprocessor/)
 * @see [GPMessage](https://developers.arcgis.com/javascript/latest/references/core/rest/support/GPMessage/)
 * @see [ParameterValue](https://developers.arcgis.com/javascript/latest/references/core/rest/support/ParameterValue/)
 */
export default class JobInfo extends JSONSupport {
  constructor(properties?: JobInfoProperties);
  /** The unique job ID assigned by geoprocessing server. */
  accessor jobId: string;
  /** The job status. */
  jobStatus: JobStatus;
  /** An array of messages that include a type and description. */
  get messages(): GPMessage[] | null | undefined;
  set messages(value: GPMessageProperties[] | null | undefined);
  /**
   * Displays the progress of the geoprocessing job.
   * This value is only present when [jobStatus](https://developers.arcgis.com/javascript/latest/references/core/rest/support/JobInfo/#jobStatus) is `job-executing` and is only updated every five seconds.
   *
   * @since 4.26
   * @see [GP Job Progress Messages](https://developers.arcgis.com/rest/services-reference/enterprise/gp-job/#progress-messages)
   * @example
   * // Submit an asynchronous geoprocessing job
   * const jobInfo = await submitJob(url, params);
   *
   * // Define a callback that will be called periodically. The function will print the
   * // geoprocessor's progress and percentage complete (if a step progressor).
   * const statusCallback = ({ jobStatus, progress }) => {
   *   if (jobStatus !== "job-executing") { return; }
   *
   *   const { message, percent } = progress;
   *   const status = `Message:  ${message}
   *                   Progress: ${percent ?? "not specified"}`
   *   console.log(`Status: ${status}`);
   * };
   *
   * // Wait for the geoprocessing job to complete and print job progress
   * // to the console every five seconds
   * await jobInfo.waitForJobCompletion({ interval: 5000, statusCallback });
   */
  get progress(): ProgressorJSON | null | undefined;
  /**
   * The [options](https://developers.arcgis.com/javascript/latest/references/core/request/#request) to be used for data requests. These options can also be controlled
   * through the `requestOptions` method parameter.
   */
  accessor requestOptions: RequestOptions | null | undefined;
  /** ArcGIS Server Rest API endpoint to the resource that receives the geoprocessing request. */
  accessor sourceUrl: string;
  /**
   * Cancels an asynchronous geoprocessing job. The returned promise will only resolve when the geoprocessing job has canceled on the server.
   *
   * @param requestOptions - Additional [options](https://developers.arcgis.com/javascript/latest/references/core/request/#request)
   *                         to be used for the data request (will override requestOptions defined
   *                         during construction).
   * @returns When resolved, returns a [JobInfo](https://developers.arcgis.com/javascript/latest/references/core/rest/support/JobInfo/).
   * @see [Geoprocessing Service (Async) | Cancel a job](https://developers.arcgis.com/rest/services-reference/enterprise/cancel-gp-job/)
   * @example
   * // Cancel an ongoing geoprocessing job when the user clicks a "cancel" button.
   * document.getElementById("cancelButton").addEventListener("click", () => {
   *   jobInfo.cancelJob().then(() => {
   *     console.log("Job cancelled successfully.");
   *   }).catch(() => {
   *     console.log("Problem occurred which cancelling the geoproccessing job");
   *   });
   * });
   */
  cancelJob(requestOptions?: RequestOptions): Promise<JobInfo>;
  /**
   * Sends a request for the current state of this job.
   *
   * @param requestOptions - Additional [options](https://developers.arcgis.com/javascript/latest/references/core/request/#request) to be used for the data request
   * (will override requestOptions defined during construction).
   * @returns When resolved, returns a [JobInfo](https://developers.arcgis.com/javascript/latest/references/core/rest/support/JobInfo/).
   */
  checkJobStatus(requestOptions?: RequestOptions | null): Promise<JobInfo>;
  /**
   * Stop monitoring this job for status updates.
   *
   * ```
   * // Stop monitoring this job for status updates.
   * jobInfo.destroy();
   * ```
   *
   * @see [waitForJobCompletion()](https://developers.arcgis.com/javascript/latest/references/core/rest/support/JobInfo/#waitForJobCompletion)
   */
  destroy(): void;
  /**
   * Sends a request to the GP Task to get the task result identified by `resultName`.
   *
   * @param resultName - The name of the result parameter as defined in Services Directory.
   * @param gpOptions - Input options for the geoprocessing service return values.
   * @param requestOptions - Additional [options](https://developers.arcgis.com/javascript/latest/references/core/request/#request) to be used for the data request
   * (will override requestOptions defined during construction).
   * @returns When resolved, returns an object with a property named `result` of type
   *   [ParameterValue](https://developers.arcgis.com/javascript/latest/references/core/rest/support/ParameterValue/), which contains the result
   *   parameters and the task execution messages.
   */
  fetchResultData(resultName: string, gpOptions?: GPOptions | null, requestOptions?: RequestOptions | null): Promise<ParameterValue<any>>;
  /**
   * Sends a request to the GP Task to get the task result identified by `jobId` and `resultName` as an image.
   *
   * @param resultName - The name of the result parameter as defined in the Services Directory.
   * @param imageParams - Specifies the properties of the result image.
   * @param requestOptions - Additional [options](https://developers.arcgis.com/javascript/latest/references/core/request/#request) to be used for the data request
   *                                      (will override requestOptions defined during construction).
   * @returns When resolved, returns an Object with a `mapImage` property of type [MapImage](https://developers.arcgis.com/javascript/latest/references/core/layers/support/MapImage/)
   */
  fetchResultImage(resultName: string, imageParams: ImageParameters, requestOptions?: RequestOptions): Promise<ParameterValue<any>>;
  /**
   * Get the task result identified by `jobId` as an [MapImageLayer](https://developers.arcgis.com/javascript/latest/references/core/layers/MapImageLayer/).
   *
   * @returns A promise resolving to an instance of MapImageLayer.
   * @example
   * // Get the resulting map image layer from a completed geoprocessing job.
   * jobInfo.fetchResultMapImageLayer(jobInfo.jobId)).then(function(layer){
   *   view.map.add(layer);
   * });
   */
  fetchResultMapImageLayer(): Promise<MapImageLayer>;
  /**
   * Resolves when an asynchronous job has completed. Optionally job progress can be monitored.
   *
   * @param options - Options. See properties below for object specifications.
   * @returns When resolved, returns a [JobInfo](https://developers.arcgis.com/javascript/latest/references/core/rest/support/JobInfo/).
   * @example
   * // Submit an asynchronous geoprocessing job. Display the remote job status every 1.5 seconds.
   * // When the job has completed, the output is a MapImageLayer.
   * const startDate = "1998-01-01 00:00:00";
   * const endDate = "1998-05-31 00:00:00";
   * const params = {
   *   query: "(Date >= date '" + startDate + "' and Date <= date '" + endDate + "')"
   * };
   *
   * const url = "https://sampleserver6.arcgisonline.com/arcgis/rest/services/911CallsHotspot/GPServer/911%20Calls%20Hotspot";
   *
   * submitJob(url, params).then((jobInfo) => {
   *   const jobid = jobInfo.jobId;
   *   console.log("ArcGIS Server job ID: ", jobid);
   *
   *   const options = {
   *     interval: 1500,
   *     statusCallback: (j) => {
   *       console.log("Job Status: ", j.jobStatus);
   *     }
   *   };
   *
   *   jobInfo.waitForJobCompletion(options).then(() => {
   *     const layer = jobInfo.fetchResultMapImageLayer.then(function(layer){
   *       map.add(layer);
   *     });
   *   });
   * });
   */
  waitForJobCompletion(options?: WaitForJobOptions): Promise<JobInfo>;
}