import type PortalFolder from "./PortalFolder.js";
import type PortalGroup from "./PortalGroup.js";
import type PortalItem from "./PortalItem.js";
import type Portal from "./Portal.js";
import type PortalQueryResult from "./PortalQueryResult.js";
import type { JSONSupport } from "../core/JSONSupport.js";
import type { PortalQueryParamsProperties } from "./PortalQueryParams.js";
import type { AddItemParameters, DeleteItemsResult, FetchItemsParameters, FetchItemsResult } from "./types.js";

export interface PortalUserProperties extends Partial<Pick<PortalUser, "access" | "culture" | "description" | "email" | "fullName" | "id" | "orgId" | "portal" | "preferredView" | "privileges" | "region" | "role" | "roleId" | "sourceJSON" | "units" | "username">> {
  /** The date the user was created. */
  created?: (Date | number | string) | null;
  /** The date the user was last modified. */
  modified?: (Date | number | string) | null;
}

/**
 * Represents a registered user of the [Portal](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-Portal.html). Personal details
 * of the user, such as email and groups, are returned only to the user or the administrator
 * of the user's organization. View the ArcGIS
 * [Portal API REST documentation for the user](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)
 */
export default class PortalUser extends JSONSupport {
  constructor(properties?: PortalUserProperties);
  /**
   * Indicates the level of access of the user. If private, the user descriptive information
   * will not be available to others nor will the username be searchable.
   */
  accessor access: "private" | "org" | "public" | null | undefined;
  /** The date the user was created. */
  get created(): Date | null | undefined;
  set created(value: (Date | number | string) | null | undefined);
  /** The culture information for the user. */
  accessor culture: string | null | undefined;
  /** A description of the user. */
  accessor description: string | null | undefined;
  /** The user's e-mail address. */
  accessor email: string | null | undefined;
  /** The user's full name. */
  accessor fullName: string | null | undefined;
  /**
   * The unique id for the user.
   *
   * @since 4.33
   */
  accessor id: string;
  /** The date the user was last modified. */
  get modified(): Date | null | undefined;
  set modified(value: (Date | number | string) | null | undefined);
  /** The ID of the organization the user belongs to. */
  accessor orgId: string | null | undefined;
  /** The portal associated with the user. */
  accessor portal: Portal;
  /** The user's preferred view for content, either web or GIS. */
  accessor preferredView: string | null | undefined;
  /** The user's privileges based on their user type or role in their organization. */
  accessor privileges: string[];
  /**
   * The user preferred region, used to set the featured maps on the home page,
   * content in the gallery, and the default extent of new maps in the Viewer.
   */
  accessor region: string | null | undefined;
  /**
   * Defines the user's role in the organization.
   * See [roleId](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalUser.html#roleId) for more details about when user has a custom role.
   */
  accessor role: "org_admin" | "org_publisher" | "org_user" | null | undefined;
  /**
   * The ID of the user's role.  Only set if the user is assigned a custom role.
   *
   * When present, the [role](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalUser.html#role) will indicate the "base" role of the custom role based on the privileges
   * the custom role contains. For example, if the custom role contains some publisher privileges, the
   * [role](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalUser.html#role) will be set to `org_publisher`.
   */
  accessor roleId: string | null | undefined;
  /**
   * The JSON used to create the property values when the `PortalUser` is created.
   * Although most commonly used properties are exposed on the `PortalUser` class directly,
   * this provides access to all information returned for the portal user. This property is
   * useful if working in an application built using an older version of the API which
   * requires access to a portal's user properties from a more recent version.
   *
   * @since 4.13
   * @see [ArcGIS REST API - User](https://developers.arcgis.com/rest/users-groups-and-items/user.htm)
   */
  accessor sourceJSON: any;
  /**
   * The URL to the thumbnail image for the user.
   *
   * @see [getThumbnailUrl()](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalUser.html#getThumbnailUrl)
   */
  get thumbnailUrl(): string | null;
  /** The user's personal units of measure setting. */
  accessor units: "english" | "metric" | null | undefined;
  /** The URL for the user's content. */
  get userContentUrl(): string | null;
  /** The username of the user. */
  accessor username: string;
  /**
   * Adds an item to the user's portal content.
   *
   * @param params - See the object specifications table below for the
   * parameters that may be passed as properties in this object.
   * @returns When resolved, returns the [PortalItem](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItem.html) to be
   * added to the user's content.
   */
  addItem(params: AddItemParameters): Promise<PortalItem>;
  /**
   * Deletes an item from the user's portal content.
   *
   * @param item - The portal item to remove.
   * @param permanentDelete - **Since 4.30.** When the [recycle bin is enabled](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-Portal.html#recycleBinEnabled) and the item to be deleted is an item type supported by the recycle bin, this parameter determines if the item should be permanently deleted. If `true`, the item will be permanently deleted. Otherwise, the item will be moved to the recycle bin. If the recycle bin is disabled, this parameter has no effect. If the item is not supported by the recycle bin, it will be permanently deleted regardless of the value of this parameter.
   * @returns Resolves when the item has been deleted from the user's content.
   * @example
   * // Delete an item from the user's content.
   * // This will recycle an item if the recycle bin is enabled and item is supported, or
   * // permanently delete it if the recycle bin is disabled or not supported.
   * const portalItem = new PortalItem({
   *   id: "affa021c51944b5694132b2d61fe1057"
   * });
   * portal.user.deleteItem(portalItem).then(() => {
   *   console.log("Item deleted from user's content.");
   * })
   * // If the item could not be deleted, an error will be returned.
   * .catch((error) => {
   *   console.error("Error deleting item: ", error);
   * });
   */
  deleteItem(item: PortalItem, permanentDelete?: boolean): Promise<void>;
  /**
   * Deletes items from the user's portal content.
   *
   * @param items - The portal items to remove.
   * @param permanentDelete - = false - **Since 4.30.** When the [recycle bin is enabled](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-Portal.html#recycleBinEnabled) and the items to be deleted are item types supported by the recycle bin, this parameter determines if the items should be permanently deleted. If `true`, the items will be permanently deleted. Otherwise, the items will be moved to the recycle bin. If the recycle bin is disabled, this parameter has no effect. If items are not supported by the recycle bin, they will be permanently deleted regardless of the value of this parameter.
   * @returns Resolves to an array of [DeleteItemsResult](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-types.html#DeleteItemsResult).
   * @since 4.8
   * @see [ArcGIS REST API delete items](https://developers.arcgis.com/rest/users-groups-and-items/delete-items.htm)
   * @example
   * // Delete items from the user's content.
   * // This will permanently delete items even if recycle bin is enabled.
   * let itemArray = [portalItem1, portalItem2, portalItem3];
   * portal.user.deleteItems(itemArray, true).then((deleteItemsResults) => {
   *   deleteItemsResults.forEach((deleteItemsResult) => {
   *     if (deleteItemsResult.success) {
   *       console.log(`${deleteItemsResult.item.title} deleted from user's content.`);
   *     } else {
   *       console.error(`Error deleting ${deleteItemsResult.item.title}: `, result.error);
   *     }
   *   });
   * });
   */
  deleteItems(items: PortalItem[], permanentDelete?: boolean): Promise<DeleteItemsResult[]>;
  /**
   * Fetches all of the user's folders used to organize portal content.
   *
   * @returns Resolves to an array of
   * [PortalFolder](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalFolder.html) objects representing each of the user's folders in the portal.
   * @example
   * // Once portal is loaded, user signed in
   * portal.load().then(() => {
   *   portalUser.fetchFolders().then((folders) => {
   *     folders.forEach((folder) => {
   *       console.log("User folder", folder.title);
   *     });
   *   });
   * });
   */
  fetchFolders(): Promise<PortalFolder[]>;
  /**
   * Fetches all the groups that the portal user has permission to access.
   *
   * @returns Resolves to an array of
   * [PortalGroup](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalGroup.html) objects representing each group that the user
   * can access.
   * @example
   * // Once portal is loaded, user signed in
   * portal.load().then(() => {
   *   // fetch all the groups user can access
   *   portal.user.fetchGroups().then((groups) => {
   *     groups.forEach((group) => {
   *       console.log(`${group.title} group`);
   *     });
   *   });
   * });
   */
  fetchGroups(): Promise<PortalGroup[]>;
  /**
   * Retrieves all the items in either the user's root folder or the specified folder.
   *
   * @param params - See the object specifications table below for the
   * parameters that may be passed as properties in this object.
   * @returns Resolves to a [FetchItemsResult](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-types.html#FetchItemsResult).
   * @example
   * // Retrieves items from the user's root folder.
   * portal.user.fetchItems().then((fetchItemsResult) => {
   *    console.log("Next start index: ", fetchItemsResult.nextStart);
   *    fetchItemsResult.items.forEach((item) => {
   *      console.log("Portal item title:", item.title);
   *    });
   * });
   * @example
   * // Retrieves items from the recycle bin which will include items from the user's root and subfolders.
   * portal.user.fetchItems( { inRecyclebin: true, includeSubfolderItems: true }).then((fetchItemsResult) => {
   *   console.log("next start index: ", fetchItemsResult.nextStart);
   *   fetchItemsResult.items.forEach((item) => {
   *     console.log("Portal item title:", item.title);
   *   });
   * });
   */
  fetchItems(params?: FetchItemsParameters): Promise<FetchItemsResult>;
  /**
   * Fetches the tag objects that have been created by the portal user.
   *
   * @returns Resolves to an array of objects with the following properties:
   * Property | Type | Description
   * ---------|------|------------
   * tag | string | The name of the tag.
   * count | number | The number of times the tag was used.
   * @since 4.14
   */
  fetchTags(): Promise<Array<{
      tag: string;
      count: number;
  }>>;
  /**
   * Get the URL to the thumbnail image for the user.
   *
   * Available width sizes: 150, 300 and 600.
   *
   * @param width - The desired image width.
   * @returns The URL to the thumbnail image.
   * @since 4.4
   */
  getThumbnailUrl(width?: number): string | null | undefined;
  /**
   * Executes a query against the user's favorite group to return an array of [PortalItem](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItem.html)
   * objects that match the input query.
   *
   * @param queryParams - The input query parameters
   * defined in [PortalQueryParams](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalQueryParams.html). This object may be
   * [autocast](https://developers.arcgis.com/javascript/latest/autocasting/).
   * @returns When resolved, resolves to an instance of [PortalQueryResult](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalQueryResult.html)
   * which contains a `results` array of [PortalItem](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-PortalItem.html) objects representing
   * all the items that match the input query.
   */
  queryFavorites(queryParams?: PortalQueryParamsProperties): Promise<PortalQueryResult<PortalItem>>;
  /**
   * Restores an item from the user's recycle bin to their content. This method only applies if the [recycle bin is enabled](https://developers.arcgis.com/javascript/latest/api-reference/esri-portal-Portal.html#recycleBinEnabled) on the organization.
   *
   * @param item - The portal item to restore.
   * @param folder - The folder to restore the item to. If not specified, the item will be restored to the root folder.
   * If an invalid folder is specified, an error will be returned and the item will not be restored.
   * @returns Resolves when the item has been restored to the user's content.
   * @since 4.30
   * @example
   * // Restore a recycled item to the root folder.
   * const portalItem = new PortalItem({
   *   id: "affa021c51944b5694132b2d61fe1057"
   * });
   * portal.user.restoreItem(portalItem).then(() => {
   *    console.log("Item restored to root folder.")
   * });
   * @example
   * // Restore a recycled item to a specified folder.
   * const portalItem = new PortalItem({
   *   id: "affa021c51944b5694132b2d61fe1057"
   * });
   * // This can be a PortalFolder object or a folder ID string.
   * const portalFolder = "6bbff8b7f2b54c628603135b72f9cb55";
   * portal.user.restoreItem(portalItem, portalFolder).then(() => {
   *    console.log("Item restored to folder with ID: '6bbff8b7f2b54c628603135b72f9cb55'.")
   * });
   */
  restoreItem(item: PortalItem, folder?: PortalFolder | string): Promise<void>;
}