/**
 * Various utils for working with [Popup](https://developers.arcgis.com/javascript/latest/references/core/widgets/Popup/) widget functionality.
 *
 * @since 4.16
 */
import type PopupTemplate from "../PopupTemplate.js";
import type EditFieldsInfo from "../layers/support/EditFieldsInfo.js";
import type FeatureReductionBinning from "../layers/support/FeatureReductionBinning.js";
import type FeatureReductionCluster from "../layers/support/FeatureReductionCluster.js";
import type Field from "../layers/support/Field.js";
import type FieldInfo from "../popup/FieldInfo.js";
import type FieldsContent from "../popup/content/FieldsContent.js";

/**
 * Creates a popup template given the specified [Config](https://developers.arcgis.com/javascript/latest/references/core/support/popupUtils/#Config) information.
 *
 * @param config - A configuration object containing properties for creating a [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 * @param options - Options for creating the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 * @returns The popup template, or `null` if no fields are set.
 * @since 4.16
 * @example
 * // Sets the configuration for the popup template.
 * // Each object in this array is autocast as an instance of esri/layers/support/Field
 * const fields = [{
 *   name: "NAME",
 *   alias: "Name",
 *   type: "string"
 * }, {
 *   name: "County",
 *   alias: "County",
 *   type: "string"
 * }, {
 *   name: "ALAND",
 *   alias: "Land",
 *   type: "double"
 * }];
 *
 * const config = {
 *   displayField: "County",
 *   fields: fields,
 *   title: "County land"
 * };
 *
 * // This sets the options to ignore all fields of "date" type and sets two visible fields
 * const templateOptions = {
 *   ignoreFieldTypes: ["date"],
 *   visibleFieldNames: new Set(["NAME", "ALAND"])
 * };
 *
 * const template = popupUtils.createPopupTemplate(config, templateOptions);
 * featureLayer.popupTemplate = template;
 */
export function createPopupTemplate(config: Config, options?: Partial<CreatePopupTemplateOptions>): PopupTemplate | null | undefined;

/**
 * Creates a default popup template to use for [FeatureReductionBinning](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FeatureReductionBinning/)
 * or [FeatureReductionCluster](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FeatureReductionCluster/) visualizations. The template will consist
 * of a list of all the aggregate fields defined in the featureReduction property of the layer.
 *
 * @param params - Parameters for creating a feature reduction popup template.
 * @returns The popup template, or `null` if no [AggregateFields](https://developers.arcgis.com/javascript/latest/references/core/layers/support/AggregateField/)
 *   are set on the feature reduction object.
 * @since 4.25
 * @example
 * const popupTemplate = popupUtils.createPopupTemplateForFeatureReduction(layer);
 * layer.featureReduction.popupTemplate = popupTemplate;
 */
export function createPopupTemplateForFeatureReduction(params: CreatePopupTemplateForFeatureReductionParameters): PopupTemplate | null | undefined;

/**
 * Creates [fields](https://developers.arcgis.com/javascript/latest/references/core/popup/content/FieldsContent/) content used for populating a [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 *
 * @param config - A configuration object containing properties for creating [FieldsContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/FieldsContent/).
 * @param options - Options for creating the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 * @returns The`fields` content used to populate the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/). This content contains an array of [FieldInfo](https://developers.arcgis.com/javascript/latest/references/core/popup/FieldInfo/).
 * @since 4.16
 * @example
 * // Sets the configuration for the popup template.
 * // Each object in this array is autocast as an instance of esri/layers/support/Field
 * const fields = [{
 *   name: "NAME",
 *   alias: "Name",
 *   type: "string"
 * }, {
 *   name: "County",
 *   alias: "County",
 *   type: "string"
 * }, {
 *   name: "ALAND",
 *   alias: "Land",
 *   type: "double"
 * }];
 *
 * // This sets the options to ignore all fields of "date" type and sets two visible fields
 * const templateOptions = {
 *   ignoreFieldTypes: ["date"],
 *   visibleFieldNames: new Set(["NAME", "ALAND"])
 * };
 *
 * // Set the FieldInfo
 * const fieldsConfig = {fields: fields};
 *
 * // Create the Fields Content
 * const fieldsContent = popupUtils.createFieldsContent(fieldsConfig, templateOptions);
 *
 * // Create the template and pass in the fields content
 * const template = {
 *   title: "County Land",
 *   outFields: ["*"],
 *   content: [fieldsContent]
 *   };
 *
 * // Set the feature layer's popup template
 * featureLayer.popupTemplate = template;
 */
export function createFieldsContent(config: FieldInfosConfig, options?: Partial<CreatePopupTemplateOptions>): FieldsContent;

/**
 * Creates an array of [FieldInfo](https://developers.arcgis.com/javascript/latest/references/core/popup/FieldInfo/) used for populating [FieldsContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/FieldsContent/).
 *
 * @param config - A configuration object containing properties for creating [FieldInfo](https://developers.arcgis.com/javascript/latest/references/core/popup/FieldInfo/).
 * @param options - Options for creating the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 * @returns An array of [FieldInfo](https://developers.arcgis.com/javascript/latest/references/core/popup/FieldInfo/) content used to populate the [FieldsContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/FieldsContent/),
 * which in turn is used to populate the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 * By default, system [fields](https://developers.arcgis.com/javascript/latest/references/core/popup/FieldInfo/),
 * e.g. `Shape__Area` and `Shape__Length`, `OID`, etc, do not display.
 * @since 4.16
 * @example
 * // Sets the configuration for the popup template.
 * // Each object in this array is autocast as an instance of esri/layers/support/Field
 * const fields = [{
 *   name: "NAME",
 *   alias: "Name",
 *   type: "string"
 * }, {
 *   name: "County",
 *   alias: "County",
 *   type: "string"
 * }, {
 *   name: "ALAND",
 *   alias: "Land",
 *   type: "double"
 * }];
 *
 * // This sets the options to ignore all fields of "date" type and sets two visible fields
 * const templateOptions = {
 *   ignoreFieldTypes: ["date"],
 *   visibleFieldNames: new Set(["NAME", "ALAND"])
 * };
 *
 * // Set the FieldInfo
 * const fieldsConfig = {fields: fields};
 *
 * // Create the FieldInfos
 * const fieldInfos = popupUtils.createFieldInfos(fieldsConfig, templateOptions);
 *
 * // Sets the FieldsContent
 * const fieldsContent = new FieldsContent({
 *   fieldInfos: fieldInfos
 * });
 *
 * // Create the template and pass in the fields content
 * const template = {
 *   title: "County Land",
 *   outFields: ["*"],
 *   content: [fieldsContent]
 *   };
 *
 * // Set the feature layer's popup template
 * featureLayer.popupTemplate = template;
 */
export function createFieldInfos(config: FieldInfosConfig, options?: Partial<CreatePopupTemplateOptions>): FieldInfo[];

/**
 * A configuration object containing field properties for creating [FieldsContent](https://developers.arcgis.com/javascript/latest/references/core/popup/content/FieldsContent/) for a [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 *
 * @example
 * // Sets the configuration for the popup template.
 * // Each object in this array is autocast as an instance of esri/layers/support/Field
 * const fieldsConfig = [{
 *   name: "NAME",
 *   alias: "Name",
 *   type: "string"
 * }, {
 *   name: "County",
 *   alias: "County",
 *   type: "string"
 * }, {
 *   name: "ALAND",
 *   alias: "Land",
 *   type: "double"
 * }];
 */
export interface FieldInfosConfig {
  /** The fields that record who adds or edits data in the feature service and when the edit is made. */
  editFieldsInfo?: EditFieldsInfo | null;
  /** The fields displayed within the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/). */
  fields?: Field[] | null;
  /** The object id field. */
  objectIdField?: string | null;
}

/**
 * A configuration object containing properties for creating a [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 *
 * @example
 * // Sets the configuration for the popup template.
 * // Each object in this array is autocast as an instance of esri/layers/support/Field
 * const fields = [{
 *   name: "NAME",
 *   alias: "Name",
 *   type: "string"
 * }, {
 *   name: "County",
 *   alias: "County",
 *   type: "string"
 * }, {
 *   name: "ALAND",
 *   alias: "Land",
 *   type: "double"
 * }];
 *
 * const config = {
 *   displayField: "County",
 *   fields: fields,
 *   title: "County land"
 * };
 */
export interface Config extends FieldInfosConfig {
  /** The display field. */
  displayField?: string | null;
  /** The title for the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/). */
  title?: string | null;
}

export interface CreatePopupTemplateForFeatureReductionParameters {
  /** The FeatureReduction object for which to create a default popup template. */
  featureReduction: FeatureReductionBinning | FeatureReductionCluster;
  /**
   * The fields of the layer aggregated during the feature reduction process. These should
   *   correspond to any fields used in the definition of the aggregate fields of the feature reduction instance provided to this function.
   */
  fields?: Field[] | null;
  /** The title to display in the popup template. */
  title?: string;
}

/**
 * Options for creating the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/).
 *
 * @example
 * // This sets the options to ignore all fields of "date" type and sets two visible fields
 * const templateOptions = {
 *   ignoreFieldTypes: ["date"],
 *   visibleFieldNames: new Set(["NAME", "ALAND"])
 * };
 */
export interface CreatePopupTemplateOptions {
  /** An array of field types to ignore when creating the popup. System fields such as `Shape_Area` and `Shape_length`, in addition to `geometry`, `blob`, `raster`, `guid` and `xml` field types are automatically ignored. */
  ignoreFieldTypes?: Field["type"][] | null;
  /** An array of field names set to be visible within the [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/). */
  visibleFieldNames?: Set<string> | null;
}