import type Extent from "../geometry/Extent.js";
import type PortalRating from "./PortalRating.js";
import type Portal from "./Portal.js";
import type PortalItemResource from "./PortalItemResource.js";
import type { JSONSupportMixin, JSONSupportMixinProperties } from "../core/JSONSupport.js";
import type { Loadable, LoadableMixinProperties } from "../core/Loadable.js";
import type { AbortOptions } from "../core/promiseUtils.js";
import type { FetchRelatedItemsParameters, ItemUpdateParameters, PortalItemResourceAddOrUpdateOptions } from "./types.js";
import type { FetchResourcesParameters, FetchResourcesResult } from "./support/resourceUtils.js";
import type { RequestOptions } from "../request/types.js";
import type { ExtentProperties } from "../geometry/Extent.js";
import type { PortalProperties } from "./Portal.js";

export interface PortalItemProperties extends LoadableMixinProperties, JSONSupportMixinProperties, Partial<Pick<PortalItem, "access" | "accessInformation" | "apiKey" | "avgRating" | "categories" | "classification" | "culture" | "description" | "groupCategories" | "id" | "licenseInfo" | "name" | "numComments" | "numRatings" | "numViews" | "owner" | "ownerFolder" | "screenshots" | "size" | "snippet" | "sourceJSON" | "tags" | "title" | "type" | "typeKeywords" | "url">> {
  /** The date the item was created. */
  created?: (Date | number | string) | null;
  /** The geographic extent, or bounding rectangle, of the item. */
  extent?: ExtentProperties | null;
  /** The date the item was last modified. */
  modified?: (Date | number | string) | null;
  /**
   * The portal that contains the item. It uses [Portal#getDefault()](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-Portal.html#getDefault).
   * This, in turn, obtains the URL from [ConfigWithPortalUrl](https://developers.arcgis.com/javascript/latest/api-reference/esri-config.html#ConfigWithPortalUrl).
   * It's suggested to use [ConfigWithPortalUrl](https://developers.arcgis.com/javascript/latest/api-reference/esri-config.html#ConfigWithPortalUrl) instead of this property.
   * If needing to work with multiple portal instances, either set the portal's [Portal#url](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-Portal.html#url)
   * directly within the PortalItem or create separate portal instances before passing them into the PortalItem.portal property.
   * Both examples are shown below.
   *
   * ```js
   * Layer.fromPortalItem({
   *   portalItem: {
   *     id: "e691172598f04ea8881cd2a4adaa45ba",
   *     // autocastable to Portal
   *     portal: {
   *       url: "https://thePortalUrl"
   *     }
   *   }
   * });
   * ```
   *
   * ```js
   *
   * let portalA = new Portal({
   *   url: "https://www.exampleA.com/arcgis" // First instance
   * });
   *
   * let portalB = new Portal({
   *   url: "https://www.exampleB.com/arcgis" // Second instance
   * });
   *
   * let item = new PortalItem({
   *   id: "e691172598f04ea8881cd2a4adaa45ba",
   *   portal: portalA // This loads the first portal instance set above
   * });
   *
   * item.load();
   * ```
   */
  portal?: PortalProperties;
}

export interface ApplicationProxy {
  /** The proxy ID registered in ArcGIS Online or ArcGIS Enterprise Portal. */
  proxyId: string;
  /** The proxy URL for the source URL. */
  proxyUrl: string;
  /** The URL of the premium map service layer. */
  sourceUrl: string;
}

/**
 * An item (a unit of content) in the Portal. Each item has a unique identifier and a
 * well known URL that is independent of the user owning the item. An item may have
 * associated binary or textual data which is available via the item data resource.
 * View the ArcGIS portal API REST documentation for the
 * [item](https://developers.arcgis.com/rest/users-groups-and-items/working-with-users-groups-and-items.htm)
 * for more details.
 *
 * @since 4.0
 * @see [ArcGIS Organization portals](https://developers.arcgis.com/javascript/latest/arcgis-organization-portals/)
 * @see [Portal](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-Portal.html)
 * @see [PortalItemResource](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItemResource.html)
 * @see [Sample - Load a basic WebScene](https://developers.arcgis.com/javascript/latest/sample-code/webscene-basic/)
 */
export default class PortalItem extends PortalItemSuperclass {
  /**
   * @example
   * // Typical usage
   * let item = new PortalItem({
   *   id: "affa021c51944b5694132b2d61fe1057"
   * });
   * item.load();
   */
  constructor(properties?: PortalItemProperties);
  /** Indicates the level of access to this item: `private`, `shared`, `org`, or `public`. */
  accessor access: "private" | "shared" | "org" | "public";
  /** Information on the source of the item and its copyright status. */
  accessor accessInformation: string | null | undefined;
  /**
   * An authorization string used to access the portal item.
   * Set this property when the portal item is secured and configured with API key authentication.
   * This property will append the API key to all requests made to the portal item resources.
   * [API keys](https://developers.arcgis.com/documentation/security-and-authentication/api-key-authentication/) are generated and managed in the portal.
   * An API key is tied explicitly to an ArcGIS account; it is also used to monitor service usage.
   *
   * @since 4.20
   * @see [Item access privileges](https://developers.arcgis.com/documentation/security-and-authentication/api-key-authentication/api-key-credentials/#item-access-privileges)
   * @example
   * const portalItem = new PortalItem({
   *   id: "caa9bd9da1f4487cb4989824053bb847",
   *   // Set an API key to access a secure portal item configured with API key authentication.
   *   apiKey: "APIKEY"
   * });
   */
  accessor apiKey: string | null | undefined;
  /**
   * Contains an array of objects containing proxy information for premium platform services.
   * This is most widely seen in registered applications that work with premium and subscriber
   * services, e.g. routing and analysis services.
   *
   * @since 4.8
   */
  get applicationProxies(): ApplicationProxy[] | null | undefined;
  /** Average rating. Uses a weighted average called "Bayesian average." */
  accessor avgRating: number | null | undefined;
  /**
   * An array of organization categories that are set on the item.
   *
   * @since 4.8
   */
  accessor categories: string[] | null | undefined;
  /**
   * The classification information for the item.
   *
   * @since 4.31
   */
  accessor classification: Record<string, any> | null | undefined;
  /** The date the item was created. */
  get created(): Date | null | undefined;
  set created(value: (Date | number | string) | null | undefined);
  /** The item's locale information (language and country). */
  accessor culture: string | null | undefined;
  /** The detailed description of the item. */
  accessor description: string | null | undefined;
  /** The geographic extent, or bounding rectangle, of the item. */
  get extent(): Extent | null | undefined;
  set extent(value: ExtentProperties | null | undefined);
  /**
   * An array of group categories set on the item. This varies slightly
   * from `categories` as it only returns categories in the group content
   * returned from [PortalGroup#queryItems()](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalGroup.html#queryItems).
   *
   * @since 4.8
   */
  accessor groupCategories: string[] | null | undefined;
  /**
   * The unique id for the item. You can typically find the id for an item in its url.
   *
   * @example
   * // to access the portal item at this url
   * // http://www.arcgis.com/home/item.html?id=d7892b3c13b44391992ecd42bfa92d01
   * let item = new PortalItem({
   *   id: "d7892b3c13b44391992ecd42bfa92d01"
   * });
   */
  accessor id: string | null | undefined;
  /**
   * Indicates whether a layer can be created from this item using [Layer#fromPortalItem()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-Layer.html#fromPortalItem).
   *
   * @example
   * if (item.isLayer) {
   *   Layer.fromPortalItem({
   *     portalItem: item
   *   }).then(addLayerToMap);
   * }
   */
  get isLayer(): boolean;
  /**
   * Indicates whether this item and the user whose credential was used to fetch this item belong
   * to the same ArcGIS Enterprise Portal or ArcGIS Online Organization.
   *
   * @default false
   * @since 4.26
   */
  get isOrgItem(): boolean;
  /**
   * Indicates whether an item can be updated and deleted.
   *
   * Possible Value | Description
   * ---------------|------------
   * admin | The item can be updated or deleted.
   * update | The item can be updated, but not deleted.
   * null | The item cannot be updated nor deleted.
   */
  get itemControl(): "admin" | "update" | "null" | null | undefined;
  /**
   * The URL to the [Item page](https://doc.arcgis.com/en/arcgis-online/manage-data/item-details.htm) on the portal.
   *
   * @since 4.25
   */
  get itemPageUrl(): string | null | undefined;
  /** The URL to the item. */
  get itemUrl(): string | null | undefined;
  /** Information on license or restrictions related to the item. */
  accessor licenseInfo: string | null | undefined;
  /**
   * Indicates whether the item's resources have loaded from the portal. When `true`,
   * all the properties of the object can be accessed.
   *
   * @default false
   */
  get loaded(): boolean;
  /** The date the item was last modified. */
  get modified(): Date | null | undefined;
  set modified(value: (Date | number | string) | null | undefined);
  /** The name of the item. */
  accessor name: string | null | undefined;
  /** Number of comments on the item. */
  accessor numComments: number | null | undefined;
  /** Number of ratings on the item. */
  accessor numRatings: number | null | undefined;
  /** Number of views on the item. */
  accessor numViews: number | null | undefined;
  /** The username of the user who owns this item. */
  accessor owner: string | null | undefined;
  /**
   * The ID of the folder in which the owner has stored the item.
   * This is only returned to the item owner or the org administrator.
   *
   * @since 4.12
   */
  accessor ownerFolder: string | null | undefined;
  /**
   * The portal that contains the item. It uses [Portal#getDefault()](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-Portal.html#getDefault).
   * This, in turn, obtains the URL from [ConfigWithPortalUrl](https://developers.arcgis.com/javascript/latest/api-reference/esri-config.html#ConfigWithPortalUrl).
   * It's suggested to use [ConfigWithPortalUrl](https://developers.arcgis.com/javascript/latest/api-reference/esri-config.html#ConfigWithPortalUrl) instead of this property.
   * If needing to work with multiple portal instances, either set the portal's [Portal#url](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-Portal.html#url)
   * directly within the PortalItem or create separate portal instances before passing them into the PortalItem.portal property.
   * Both examples are shown below.
   *
   * ```js
   * Layer.fromPortalItem({
   *   portalItem: {
   *     id: "e691172598f04ea8881cd2a4adaa45ba",
   *     // autocastable to Portal
   *     portal: {
   *       url: "https://thePortalUrl"
   *     }
   *   }
   * });
   * ```
   *
   * ```js
   *
   * let portalA = new Portal({
   *   url: "https://www.exampleA.com/arcgis" // First instance
   * });
   *
   * let portalB = new Portal({
   *   url: "https://www.exampleB.com/arcgis" // Second instance
   * });
   *
   * let item = new PortalItem({
   *   id: "e691172598f04ea8881cd2a4adaa45ba",
   *   portal: portalA // This loads the first portal instance set above
   * });
   *
   * item.load();
   * ```
   */
  get portal(): Portal;
  set portal(value: PortalProperties);
  /**
   * An array of string URLs. These URLs should point to
   * screenshots (i.e. screen captures) associated with an application.
   *
   * An example value could be something similar to
   * `"screenshots/Basic.png"`.
   *
   * @since 4.8
   */
  accessor screenshots: string[] | null | undefined;
  /** The size of the item (in bytes). */
  accessor size: number | null | undefined;
  /** A summary description of the item. */
  accessor snippet: string | null | undefined;
  /**
   * The JSON used to create the property values when the `PortalItem` is loaded.
   * Although most commonly used properties are exposed on the `PortalItem` class directly,
   * this provides access to all information returned by the portal item. This property is
   * useful if working in an application built using an older version of the API which
   * requires access to a portal's item properties from a more recent version.
   *
   * @since 4.13
   * @see [ArcGIS REST API - Item](https://developers.arcgis.com/rest/users-groups-and-items/item.htm)
   */
  accessor sourceJSON: any;
  /** User defined tags that describe the item. */
  accessor tags: string[] | null | undefined;
  /**
   * The URL to the thumbnail used for the item.
   *
   * @see [getThumbnailUrl()](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItem.html#getThumbnailUrl)
   */
  get thumbnailUrl(): string | null | undefined;
  /**
   * The title for the item. This is the name that is displayed to users and
   * used to refer to the item. Every item must have a title.
   */
  accessor title: string | null | undefined;
  /**
   * The GIS content type of this item. Example types include Web Map, Map Service, Shapefile, and Web Mapping Application.
   * See the [ArcGIS REST API Items and Items Types Reference](https://developers.arcgis.com/rest/users-groups-and-items/items-and-item-types.htm) to get an understanding of the item type hierarchy.
   *
   * @example portalItem.type = "Web Map";
   * @example portalItem.type = "Web Mapping Application";
   */
  accessor type: string | null | undefined;
  /** Type keywords that describe the type of content of this item. */
  accessor typeKeywords: string[];
  /**
   * The service URL of this item. Only certain layer item types such as
   * "Feature Service", "Map Service", "Image Service", "Scene Service",
   * "WMS" and "KML" have service URLs.
   */
  accessor url: string | null | undefined;
  /**
   * Adds a rating to an accessible item.
   *
   * @param rating - Rating to set for the item. Rating must be a number between 1.0 and 5.0.
   * @returns When resolved, a [PortalRating](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalRating.html) is returned.
   */
  addRating(rating: number | PortalRating): Promise<PortalRating | null | undefined>;
  /**
   * Adds a new [resource](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItemResource.html) to the portal item.
   *
   * @param resource - The resource to add to the portal item.
   * @param content - The resource content.
   * @param options - An object wih the following properties.
   * @returns When resolved, returns the [PortalItemResource](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItemResource.html).
   * @since 4.16
   * @see [ArcGIS REST API - Add Resources](https://developers.arcgis.com/rest/users-groups-and-items/add-resources.htm)
   * @example
   * // The following snippet assumes you have an existing portal item instance
   * // that you are allowed to modify
   *
   * // An example of an object that we would like to store as a resource
   * const definition = { type: "world", description: "A world definition" };
   *
   * const resource = new PortalItemResource({ path: "definitions/world.json" });
   *
   * // Resource content is always passed as a blob. Define a blob that contains our definition
   * // in JSON encoding
   * const content = new Blob([JSON.stringify(definition)], { type: "application/json" });
   *
   * portalItem.addResource(resource, content)
   *   .then(function () {
   *     console.log("Successfully added resource", resource.url);
   *   })
   *   .catch(function (error) {
   *     console.error("Failed to add resource", error);
   *   });
   */
  addResource(resource: PortalItemResource, content: Blob, options?: PortalItemResourceAddOrUpdateOptions): Promise<PortalItemResource>;
  /**
   * Creates a clone of this object. It is a deep clone except for the `portal` property.
   *
   * @returns A clone of the [PortalItem](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItem.html) instance that
   *   invoked this method.
   * @since 4.12
   */
  clone(): PortalItem;
  /**
   * Deletes a rating for the specified item.
   *
   * @returns Resolved when the rating successfully deletes.
   */
  deleteRating(): Promise<void>;
  /**
   * Destroys the portal item, and any associated resources, including its associated [portal](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItem.html#portal).
   * These can no longer be used once the portal item has been destroyed. To prevent these objects from being destroyed,
   * remove them from the portal item before calling `destroy()`.
   *
   * ```
   * // unset the portal from the portal item so that it is not destroyed
   * const portal = portalItem.portal;
   * portalItem.portal = null;
   *
   * // destroy the portal item and any remaining associated resources
   * portalItem.destroy();
   * ```
   *
   * @since 4.17
   * @see [Basemap#destroy()](https://developers.arcgis.com/javascript/latest/api-reference/esri-Basemap.html#destroy)
   * @see [Map#destroy()](https://developers.arcgis.com/javascript/latest/api-reference/esri-Map.html#destroy)
   * @see [WebMap#destroy()](https://developers.arcgis.com/javascript/latest/api-reference/esri-WebMap.html#destroy)
   * @see [WebScene#destroy()](https://developers.arcgis.com/javascript/latest/api-reference/esri-WebScene.html#destroy)
   * @see [Ground#destroy()](https://developers.arcgis.com/javascript/latest/api-reference/esri-Ground.html#destroy)
   * @see [Layer#destroy()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-Layer.html#destroy)
   */
  destroy(): void;
  /**
   * Requests a PortalItem in the format specified in `responseType`.
   *
   * @param responseType - = json - The format of the response.
   * @param options - An object with the following properties.
   * @returns When resolved, returns the requested data.
   */
  fetchData<T>(responseType?: RequestOptions["responseType"], options?: AbortOptions | null | undefined): Promise<T>;
  /**
   * Returns the rating (if any) given to the item.
   *
   * @param options - An object with the following properties.
   * @returns When resolved, a [PortalRating](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalRating.html) is returned.
   */
  fetchRating(options?: AbortOptions): Promise<PortalRating | null | undefined>;
  /**
   * Gets all the related items of a certain relationship type for the portal item.
   * An optional direction can be specified if the direction of the relationship
   * is ambiguous. Otherwise, the service will try to infer it.
   *
   * @param params - See the object specifications table below for the
   * parameters that may be passed as properties in this object.
   * @param options - An object with the following properties.
   * @returns When resolved, resolves to an array of the related [PortalItem](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItem.html).
   * @example
   * let queryParam = {
   *    relationshipType: "Service2Data"
   * };
   *
   * portalItem.fetchRelatedItems(queryParam).then(function(results){
   *    console.log("related portal item", results);
   * });
   */
  fetchRelatedItems(params: FetchRelatedItemsParameters, options?: AbortOptions | null | undefined): Promise<PortalItem[]>;
  /**
   * Retrieves references to all the [portal item resources](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItemResource.html).
   *
   * @param params - The fetch parameters used to retrieve [portal item resources](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItemResource.html).
   * @param options - Additional options with the following properties.
   * @returns Resolves with an object containing the [item resources](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItemResource.html).
   * @since 4.16
   * @see [ArcGIS REST API- Item Resources](https://developers.arcgis.com/rest/users-groups-and-items/item-resources.htm)
   * @example
   * portalItem.fetchResources().then(function(result) {
   *    console.log("next start index: ", result.nextStart);
   *
   *    result.resources.forEach(function(item) {
   *      console.log("resource:", item.resource.path, "size:", item.size);
   *    });
   * });
   */
  fetchResources(params?: FetchResourcesParameters, options?: AbortOptions | null | undefined): Promise<FetchResourcesResult>;
  /**
   * Get the URL to the thumbnail image for the item.
   *
   * Available width sizes: 200, 400, 800 and 2400.
   *
   * @param width - The desired image width.
   * @returns The URL to the thumbnail image.
   * @since 4.4
   */
  getThumbnailUrl(width?: number): string | null | undefined;
  /**
   * Reloads a loaded item's properties from the portal.
   *
   * @returns Resolves when the portal item's properties have been reloaded.
   * @since 4.14
   */
  reload(): Promise<PortalItem>;
  /**
   * Removes all the [resources](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItemResource.html) from the portal item.
   *
   * @param options - An object with the following properties.
   * @returns Resolves when all the [resources](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItemResource.html) have been removed successfully.
   * @since 4.16
   * @see [ArcGIS REST API - Remove Resources](https://developers.arcgis.com/rest/users-groups-and-items/remove-resources.htm)
   */
  removeAllResources(options?: AbortOptions): Promise<void>;
  /**
   * Removes a [resource](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItemResource.html) from the portal item.
   *
   * @param resource - The resource to remove from the portal item.
   * @param options - An object wih the following properties.
   * @returns Resolves when the remove operation has completed.
   * @since 4.16
   * @see [ArcGIS REST API - Remove Resources](https://developers.arcgis.com/rest/users-groups-and-items/remove-resources.htm)
   */
  removeResource(resource: PortalItemResource, options?: AbortOptions): Promise<void>;
  /**
   * Updates the item's properties to the portal, and optionally its data.
   *
   * @param params - See the object specifications table below for the
   * parameters that may be passed as properties in this object.
   * @returns Resolves when the portal item's properties have been updated.
   */
  update(params?: ItemUpdateParameters): Promise<PortalItem>;
  /**
   * Updates the item's thumbnail on the portal.
   *
   * @param params - See the object specification table below for the
   * parameters that may be passed as properties in this object.
   * @returns Resolves when the portal item's thumbnail has been updated.
   * @since 4.5
   */
  updateThumbnail(params: PortalItemUpdateThumbnailParameters): Promise<PortalItem>;
}
declare const PortalItemSuperclass: typeof Loadable & typeof JSONSupportMixin

export interface PortalItemUpdateThumbnailParameters {
  /** The file name used for the thumbnail in [thumbnailUrl](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItem.html#thumbnailUrl). */
  filename?: string | null;
  /**
   * A URL, Data URI, Blob, or File.
   * The accepted formats are `GIF`, `JPG`, and `PNG`.
   */
  thumbnail: Blob | string;
}