import type Collection from "../../core/Collection.js";
import type EsriError from "../../core/Error.js";
import type SpatialReference from "../../geometry/SpatialReference.js";
import type PortalItem from "../../portal/PortalItem.js";
import type Portal from "../../portal/Portal.js";
import type PrintTemplate from "../../rest/support/PrintTemplate.js";
import type MapView from "../../views/MapView.js";
import type CustomTemplate from "./CustomTemplate.js";
import type FileLink from "./FileLink.js";
import type TemplateOptions from "./TemplateOptions.js";
import type { EventedAccessor } from "../../core/Evented.js";
import type { LoadableMixin, LoadableMixinProperties } from "../../core/Loadable.js";
import type { EsriPromiseMixin } from "../../core/Promise.js";
import type { PrintResponse } from "../../rest/types.js";
import type { Formats, Layouts, State, TemplateCustomTextElements, TemplatesInfo } from "./types.js";
import type { FileLinkProperties } from "./FileLink.js";
import type { ReadonlyArrayOrCollection } from "../../core/Collection.js";
import type { SpatialReferenceProperties } from "../../geometry/SpatialReference.js";
import type { PortalProperties } from "../../portal/Portal.js";
import type { TemplateOptionsProperties } from "./TemplateOptions.js";

export interface PrintViewModelProperties extends LoadableMixinProperties, Partial<Pick<PrintViewModel, "allowedFormats" | "allowedLayouts" | "extraParameters" | "includeDefaultTemplates" | "printServiceUrl" | "printTimeout" | "showPrintAreaEnabled" | "templateCustomTextElements" | "updateDelay" | "view">> {
  /**
   * The collection of links exported from Print.
   *
   * @since 4.33
   */
  exportedLinks?: ReadonlyArrayOrCollection<FileLinkProperties>;
  /**
   * The [spatial reference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-SpatialReference.html) used to render
   * the printed map on the server.
   *
   * @since 4.33
   */
  outSpatialReference?: SpatialReferenceProperties | null;
  /**
   * It is possible to search a specified portal instance's [locator services](https://enterprise.arcgis.com/en/portal/latest/administer/windows/configure-portal-to-geocode-addresses.htm).
   * Use this property to set this [ArcGIS Portal](https://enterprise.arcgis.com/en/portal/) instance to search.
   * This is especially helpful when working with a [custom print template](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-CustomTemplate.html).
   *
   * If this property is set, it is not necessary to set the [printServiceUrl](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-PrintViewModel.html#printServiceUrl) property.
   *
   * @since 4.18
   * @see [CustomTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-CustomTemplate.html)
   */
  portal?: PortalProperties;
  /**
   * Defines the layout template options to generate the print page.
   *
   * @since 4.33
   */
  templateOptions?: TemplateOptionsProperties;
}

/** The printed export. */
export interface PrintExport {
  /** The link for the exported file. */
  link: FileLink;
  /** The promise for the exported file. */
  promise: Promise<FileLink>;
}

export interface PrintViewModelEvents {
  /**
   * Fires when an export request begins, and returns a reference to the exported [link](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-FileLink.html).
   *
   * @since 4.17
   * @example
   * const printWidget = new Print();
   *
   * printWidget.on("submit", function(results){
   *   // The results are stored in the event object
   *   console.log("Results of submitting the print: ", results.link);
   * });
   */
  submit: SubmitEvent;
  /**
   * Fires when a print request has been completed and returns its results.
   * This event will fire whether an export succeeds or fails.
   *
   * @since 4.17
   * @example
   * const printWidget = new Print();
   *
   * printWidget.on("complete", function(results){
   *   // The results are stored in the results object
   *   console.log("Results of the print: ", results.link);
   * });
   */
  complete: CompleteEvent;
}

export interface SubmitEvent {
  /** An object representing the results of submitting the print. */
  link: FileLink;
}

export interface CompleteEvent {
  /** An object representing the results of the print. */
  link: FileLink;
}

/**
 * Provides the logic for the [Print](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print.html) widget and [component](https://developers.arcgis.com/javascript/latest/references/map-components/arcgis-print/).
 *
 * > [!WARNING]
 * >
 * > **Known Limitations**
 * >
 * > See [print](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-print.html) for a detailed list of known limitations.
 *
 * @since 4.2
 * @see [Print widget](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print.html) - _Deprecated since 4.33. Use the [Print component](https://developers.arcgis.com/javascript/latest/references/map-components/arcgis-print/) instead._
 * @see [Print component](https://developers.arcgis.com/javascript/latest/references/map-components/arcgis-print/)
 * @see [print](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-print.html)
 * @see [Programming patterns: Widget viewModel pattern](https://developers.arcgis.com/javascript/latest/programming-patterns/#widget-viewmodel-pattern)
 */
export default class PrintViewModel extends PrintViewModelSuperclass {
  constructor(properties?: PrintViewModelProperties);
  /**
   * Specify the print output file format(s) that the user can select based on the options available from the print service.
   * This property can take a string value or an array of string values.
   *
   * When this value is "all" (default value), all the print service formats are available to be used.
   * When an array of string values is used, only those values that match the options available from the print service will be used.
   * If none of the input string values match those available from the print service, `allowedFormats` will fallback to default behavior.
   *
   * @default "all"
   * @since 4.15
   * @see [TemplateOptions.format](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-TemplateOptions.html#format)
   * @example
   * const print = new Print({
   *   view: view,
   *   printServiceUrl: url
   * });
   *
   * print.viewModel.allowedFormats = ["jpg", "png8", "png32"];
   *
   * view.ui.add(print, {position: "top-right"});
   */
  accessor allowedFormats: Formats;
  /**
   * Specify the print output layout(s) that the user can select based on the options available from the print service.
   * This property can take a string value or an array of string values.
   *
   * When this value is "all" (default value), all the print service layouts are available to be used.
   * When an array of string values is used, only those values that match the options available from the print service will be used.
   * If none of the input string values match those available from the print service, `allowedLayouts` will fallback to default behavior.
   *
   * @default "all"
   * @since 4.15
   * @see [TemplateOptions.layout](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-TemplateOptions.html#format)
   * @example
   * const print = new Print({
   *   view: view,
   *   printServiceUrl: url
   * });
   *
   * print.viewModel.allowedLayouts = ["a3-landscape", "a3-portrait"];
   *
   * view.ui.add(print, {position: "top-right"});
   */
  accessor allowedLayouts: Layouts;
  /**
   * A collection of print templates defined on the Portal.
   *
   * Print templates are used to apply pre-defined values to existing print options.
   *
   * @since 4.33
   */
  get browseTemplates(): Collection<CustomTemplate>;
  /**
   * The [template](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-CustomTemplate.html) which defines the default print template.
   *
   * @since 4.33
   */
  get defaultTemplate(): CustomTemplate | null | undefined;
  /**
   * A collection of print templates defined on the Portal.
   *
   * Print templates are used to apply pre-defined values to existing print options.
   *
   * @since 4.18
   */
  get defaultTemplates(): Collection<CustomTemplate>;
  /** The effective URL of the REST endpoint of the Export Web Map Task. */
  get effectivePrintServiceUrl(): string | null | undefined;
  /**
   * Returns an array of objects of all print templates available on the custom print
   * service to see which templates were published with `customTextElements`. These
   * values can be overwritten in the UI, or programmatically using the
   * [templateCustomTextElements](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-PrintViewModel.html#templateCustomTextElements) property.
   *
   * The PrintViewModel calls the `Get Layout Templates Info` task on the GPServer
   * to discover available templates. If the `Get Layout Templates Info` task is named
   * differently on the custom print service, then no values will be returned, and it
   * will not be possible to support `customTextElements`. In this scenario, we recommend
   * republishing the print service to use the standard `Get Layout Templates Info` name.
   *
   * @since 4.22
   */
  get effectiveTemplateCustomTextElements(): TemplateCustomTextElements;
  /**
   * The [Error](https://developers.arcgis.com/javascript/latest/api-reference/esri-core-Error.html) that occurred during printing.
   *
   * @since 4.33
   */
  get error(): EsriError | null | undefined;
  /**
   * The collection of links exported from Print.
   *
   * @since 4.33
   */
  get exportedLinks(): Collection<FileLink>;
  set exportedLinks(value: ReadonlyArrayOrCollection<FileLinkProperties>);
  /**
   * This option allows passing extra parameters to the print (export webmap) requests.
   *
   * @since 4.20
   */
  accessor extraParameters: Record<string, any> | null | undefined;
  /**
   * Indicates whether or not to include [defaultTemplates](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-PrintViewModel.html#defaultTemplates).
   *
   * @default true
   * @since 4.18
   */
  accessor includeDefaultTemplates: boolean;
  /**
   * The [spatial reference](https://developers.arcgis.com/javascript/latest/api-reference/esri-geometry-SpatialReference.html) used to render
   * the printed map on the server.
   *
   * @since 4.33
   */
  get outSpatialReference(): SpatialReference | null | undefined;
  set outSpatialReference(value: SpatialReferenceProperties | null | undefined);
  /**
   * It is possible to search a specified portal instance's [locator services](https://enterprise.arcgis.com/en/portal/latest/administer/windows/configure-portal-to-geocode-addresses.htm).
   * Use this property to set this [ArcGIS Portal](https://enterprise.arcgis.com/en/portal/) instance to search.
   * This is especially helpful when working with a [custom print template](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-CustomTemplate.html).
   *
   * If this property is set, it is not necessary to set the [printServiceUrl](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-PrintViewModel.html#printServiceUrl) property.
   *
   * @since 4.18
   * @see [CustomTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-CustomTemplate.html)
   */
  get portal(): Portal;
  set portal(value: PortalProperties);
  /**
   * An array of portalItem Ids that are used to identify the print templates using layoutItem Id.
   *
   * @deprecated since version 5.0.
   * @since 4.33
   */
  get portalTemplateIds(): string[];
  /**
   * A collection of print templates defined on the Portal.
   *
   * Print templates are used to apply pre-defined values to existing print options.
   *
   * @since 4.33
   */
  get printServiceTemplates(): Collection<CustomTemplate>;
  /**
   * The URL of the REST endpoint of the Export Web Map Task.
   * If the [portal](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-PrintViewModel.html#portal) property is set, it is not necessary to set this property.
   */
  accessor printServiceUrl: string | null | undefined;
  /**
   * Print timeout value in milliseconds.
   *
   * @default 120000
   * @since 4.28
   */
  accessor printTimeout: number;
  /**
   * The initial state of the print area toggle in the UI.
   * When set to `true`, the print area toggle is enabled by default.
   * When set to `false`, the print area toggle is disabled by default.
   *
   * @default false
   * @since 4.30
   * @see [Print component](https://developers.arcgis.com/javascript/latest/references/map-components/arcgis-print/)
   */
  accessor showPrintAreaEnabled: boolean;
  /**
   * The view model's state.
   *
   * @default "disabled"
   */
  get state(): State;
  /**
   * An object containing an array of `customTextElements` name-value pair objects
   * for each print template in a custom print service. Use this property to update
   * the text for custom text elements on the page layout.
   *
   * The PrintViewModel calls the `Get Layout Templates Info` task on the GPServer
   * to discover possible `customTextElements` values for each template. The name of
   * the task must match `Get Layout Templates Info`, templates must be published
   * with `customTextElements`, and values must be strings. Values found there will be
   * populated under `Advanced options`. These values can be
   * overwritten in the UI, or programmatically using this property.
   * To list all print templates available on the print service to see
   * which templates were published with `customTextElements`, use the
   * [effectiveTemplateCustomTextElements](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-PrintViewModel.html#effectiveTemplateCustomTextElements) property.
   *
   * @since 4.22
   * @example
   * const printViewModel = new PrintViewModel({
   *    view: view,
   *    // specify your custom print service
   *    printServiceUrl: "",
   *    // `customTextElements` are defined per print template
   *    // this example has one template with `customTextElements`
   *    templateCustomTextElements: {
   *       // if there were more applicable templates, then we would
   *       // create another object with the template name containing
   *       // an array of more name-value pairs
   *       "Portrait_TextElements": [
   *           // the possible values are defined in the print service
   *           { "headquarters": "Tampa, Florida" },
   *           { "division": "NFC South" },
   *           { "founded": "1976" }
   *       ]
   *    }
   *  });
   */
  accessor templateCustomTextElements: TemplateCustomTextElements | null | undefined;
  /**
   * Defines the layout template options to generate the print page.
   *
   * @since 4.33
   */
  get templateOptions(): TemplateOptions;
  set templateOptions(value: TemplateOptionsProperties);
  /**
   * The service metadata that contains the [TemplateOptions.format](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-TemplateOptions.html#format)
   * and [TemplateOptions.layout](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-TemplateOptions.html#layout) information for the printout.
   *
   * @since 4.33
   * @example
   * const print = new Print({
   *   view: view,
   *   printServiceUrl: url
   * });
   *
   * view.ui.add(print, {position: "top-right"});
   *
   * console.log("PrintViewModel templatesInfo Formats: ", print.viewModel.templatesInfo.format.choiceList);
   * console.log("PrintViewModel templatesInfo Layouts: ", print.viewModel.templatesInfo.layout.choiceList);
   */
  get templatesInfo(): TemplatesInfo | null | undefined;
  /**
   * The time interval in milliseconds between each job status request sent to an asynchronous GP task.
   *
   * @default 1000
   */
  accessor updateDelay: number;
  /** The view from which Print will operate. */
  accessor view: MapView | null | undefined;
  /**
   * Adds a template to a portal.
   *
   * @param portalItem - The
   *        [PortalItem](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItem.html) used to create a print template.
   *        This template will be added to the `browseTemplates` collection.
   * @returns Resolves when the template is added.
   */
  addPortalTemplate(portalItem: PortalItem): Promise<void>;
  /**
   * Applies the specified print template to the `templateOptions` property.
   * This method updates the layout, custom text elements, and other template-specific
   * options based on the provided template. If the template is `"map-only"`, it sets
   * the layout to `"map-only"` and skips additional processing.
   *
   * If the provided template is invalid or not supported, the method falls back to
   * the default template (if available) or resets the `templateOptions` to their
   * initial state.
   *
   * @param template - The
   *        [CustomTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-CustomTemplate.html) will be applied.
   * @returns Resolves when the template is applied.
   */
  applyTemplate(template: CustomTemplate | "map-only" | null | undefined): Promise<void>;
  /**
   * Creates a new [FileLink](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-FileLink.html) object for the given file name.
   * This method generates a unique file name with the appropriate extension based on the
   * selected print template format and updates the internal file name map to track the
   * number of exports with the same name.
   *
   * @param fileName - The base name of the file to be exported (without extension).
   * @returns A `FileLink` object containing the file name,
   *         extension, and export count.
   */
  createExportedFileLink(fileName: string): FileLink;
  /**
   * Exports the current print template to a file.
   *
   * This method generates a file link and initiates the export process using the current
   * print template options. The returned object contains a `FileLink` instance and a promise
   * that resolves when the export is complete.
   *
   * @param fileName - The name of the file to export (without extension).
   * @returns An object containing:
   *         - `link`: A [FileLink](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-FileLink.html) object representing the exported file.
   *         - `promise`: A promise that resolves to the `FileLink` when the export is complete.
   */
  export(fileName: string): PrintExport;
  /**
   * Returns a CustomTemplate with the specified `id`. The associated properties are
   * useful for print considerations.
   *
   * @param id - The `id` of the CustomTemplate.
   * @returns Returns a CustomTemplate,
   * which contains both `layoutTemplateInfo` and `mapSurroundInfoOptions`.
   * @example this.viewModel.getLayoutTemplateById(this.templateOptions.id);
   */
  getLayoutTemplateById(id: string | null | undefined): CustomTemplate | null | undefined;
  /**
   * This method should be called to load the view model's printing resources.
   *
   * @returns When resolved, the view model has loaded the print service metadata necessary for printing.
   */
  load(): Promise<this>;
  /**
   * Prints (exports) the current MapView according to selected options.
   *
   * @param template - The
   *        [PrintTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-rest-support-PrintTemplate.html) is used to specify
   *        the layout template options which is then used by the PrintTask to
   *        generate the print page.
   * @returns Resolves to an object with the following properties:
   *
   * Property | Type     | Description
   * ---------|----------|-------------
   * url      | String | URL to the exported printout.
   */
  print(template: PrintTemplate): Promise<PrintResponse>;
  /**
   * Removes Template from `browseTemplates`.
   *
   * @param template - The
   *        [CustomTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Print-CustomTemplate.html) will be removed.
   * @returns Resolves when the template is removed.
   */
  removePortalTemplate(template: CustomTemplate): void;
  /**
   * Helper method to create print templates from a template options object.
   *
   * @param templateOptions
   */
  toPrintTemplate(templateOptions: TemplateOptions): PrintTemplate;
}
declare const PrintViewModelSuperclass: typeof EventedAccessor & typeof EsriPromiseMixin & typeof LoadableMixin