import type BaseContent from "./Content.js";
import type { PopupTemplateContentCreator, PopupTemplateContentDestroyer } from "../types.js";
import type { ContentProperties as BaseContentProperties } from "./Content.js";

export interface CustomContentProperties extends BaseContentProperties, Partial<Pick<CustomContent, "creator" | "destroyer" | "outFields">> {}

/**
 * A `CustomContent` popup element is used to provide a way to customize the [popup's](https://developers.arcgis.com/javascript/latest/references/core/widgets/Popup/) content.
 * This content can be a combination of elements such as `String`,
 * [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement),
 * [Widget](https://developers.arcgis.com/javascript/latest/references/core/widgets/Widget/),
 * or `Promise`.
 *
 * @since 4.16
 * @see [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/)
 * @see [Content](https://developers.arcgis.com/javascript/latest/references/core/popup/content/Content/)
 * @see [Sample - Intro to PopupTemplate](https://developers.arcgis.com/javascript/latest/sample-code/intro-popuptemplate/)
 * @see [Sample - Custom popup content elements](https://developers.arcgis.com/javascript/latest/sample-code/popup-customcontent/)
 * @example
 * // Create the custom content for the CustomContent popup element
 * // Creates some custom content
 * let customContentWidget = new CustomContent({
 *   outFields: ["*"],
 *   creator: (event) => {
 *     // creator function returns either string, HTMLElement, Widget, or Promise
 *   }
 * });
 */
export default class CustomContent extends BaseContent {
  constructor(properties?: CustomContentProperties);
  /**
   * The function that is called to create the custom content element. Make
   * certain that `outFields` is specified within this custom content.
   *
   * @see [outFields](https://developers.arcgis.com/javascript/latest/references/core/popup/content/CustomContent/#outFields)
   * @example
   * // This custom content contains a widget
   * let customContentWidget = new CustomContent({
   *   outFields: ["*"],
   *   creator: () => {
   *     home = new Home({
   *       view: view
   *     });
   *   return home;
   *   }
   * });
   * @example
   * // This custom content returns a promise
   * let customContentWidget = new CustomContent({
   *   outFields: ["*"],
   *   creator: () => {
   *       const image = document.createElement("img");
   *       image.src = "<url to image>";
   *       image.width = 100;
   *       return image;
   *   }
   * });
   * @example
   * // This custom content contains the resulting promise from the query
   * const customContentQuery = new CustomContent({
   *  outFields: ["*"],
   *  creator: (event) => {
   *    const queryObject = new Query({
   *      geometry: event.graphic.geometry,
   *      outFields: ["*"],
   *      spatialRelationship: "intersects",
   *      returnGeometry: true
   *    });
   *    return query.executeForCount(queryUrl, queryObject).then((count) => {
   *      return `There are ${count} features that intersect with ${event.graphic.attributes["field_name"]}.`;
   *    },
   *    (error) => {
   *      console.log(error);
   *    });
   *  }
   * });
   */
  accessor creator: PopupTemplateContentCreator | null | undefined;
  /**
   * The called function to cleanup custom content when it is no longer necessary.
   *
   * @example
   * // Destroy the custom content
   * let customContent = new CustomContent({
   *   ...
   *   destroyer: () => {
   *     // destroy custom content here
   *   }
   * });
   */
  accessor destroyer: PopupTemplateContentDestroyer | null | undefined;
  /**
   * An array of field names used in the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
   * Use this property to indicate what fields are required
   * to fully render the template's custom content. This is important if setting
   * [content](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/#content) via a function since any fields needed for successful
   * rendering should be specified here.
   *
   * To fetch the values from all fields, use `["*"]`.
   */
  accessor outFields: string[] | null | undefined;
  /**
   * The type of popup element displayed.
   *
   * @default "custom"
   * @see [TextContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/TextContent/)
   * @see [FieldsContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/FieldsContent/)
   * @see [MediaContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/MediaContent/)
   * @see [AttachmentsContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/AttachmentsContent/)
   * @see [CustomContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/CustomContent/)
   * @see [ExpressionContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/ExpressionContent/)
   * @see [RelationshipContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/RelationshipContent/)
   * @see [UtilityNetworkAssociationsContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/UtilityNetworkAssociationsContent/)
   */
  get type(): "custom";
  /**
   * Creates a deep clone of the CustomContent class.
   *
   * @returns A deep clone of the CustomContent instance.
   */
  clone(): CustomContent;
}