import type { ClonableMixin, ClonableMixinProperties } from "../../core/Clonable.js";
import type { JSONSupport, JSONSupportMixinProperties } from "../../core/JSONSupport.js";
import type { FieldFormatUnion } from "./fieldFormatUtils.js";
import type { NumberFieldFormatProperties } from "./NumberFieldFormat.js";
import type { DateTimeFieldFormatProperties } from "./DateTimeFieldFormat.js";

export interface FieldConfigurationProperties extends JSONSupportMixinProperties, ClonableMixinProperties, Partial<Pick<FieldConfiguration, "alias" | "name">> {
  /**
   * The format of the field. This can be either a [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-DateTimeFieldFormat.html) or [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-NumberFieldFormat.html) object. This is dependent upon the type of field.
   *
   * @see [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-DateTimeFieldFormat.html)
   * @see [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-NumberFieldFormat.html)
   * @see [FieldInfo#fieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-popup-FieldInfo.html#fieldFormat)
   * @example
   * const fieldConfig = new FieldConfiguration({
   *   "name": "install_date",
   *   "alias": "Date of Installation",
   *   "fieldFormat": { // Autocast to DateTimeFieldFormat
   *      "type": "date-time",
   *      "dateStyle": "short",
   *      "timeStyle": "medium"
   *   }
   * });
   */
  fieldFormat?: ((DateTimeFieldFormatProperties & { type: "date-time" }) | (NumberFieldFormatProperties & { type: "number" })) | null;
}

/**
 * The `FieldConfiguration` class defines how fields in a layer are displayed and formatted within widgets and UI components. It provides a standardized way to customize field presentation, including display names, `alias`, and formatting rules for numbers and dates. Using field configurations ensures consistent formatting across components that consume the layer's data.
 *
 * Previously, field information was defined using [FieldInfo](https://developers.arcgis.com/javascript/latest/api-reference/esri-popup-FieldInfo.html) objects. Although compatibility with [FieldInfo](https://developers.arcgis.com/javascript/latest/api-reference/esri-popup-FieldInfo.html) is maintained for existing applications, [FieldConfiguration](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FieldConfiguration.html) is the preferred pattern for new development and for updating existing code.
 *
 * Field configurations are typically assigned to a layer's [FeatureLayer#fieldConfigurations](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#fieldConfigurations) property before initializing components such as [FeatureTable](https://developers.arcgis.com/javascript/latest/references/map-components/arcgis-feature-table/) or [Popup](https://developers.arcgis.com/javascript/latest/references/map-components/arcgis-popup/) components. Configurations are created with the [FieldConfiguration](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FieldConfiguration.html) class, where the [fieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-FieldConfiguration.html#fieldFormat) property can be set to either a [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-DateTimeFieldFormat.html) or [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-NumberFieldFormat.html) object, depending on the field type.
 *
 * Note that field configurations affect only how field values are displayed in the UI. They do not modify the underlying data in the feature layer.
 *
 * > [!WARNING]
 * >
 * > **Known Limitations and Considerations:**
 * > Field configuration support is currently limited to feature service-based [FeatureLayer](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html) instances, including tables. Additional layer types and data sources, such as client-side graphics or feature collections, are not supported at this time. Support for additional layer types is planned for future releases.
 * > Field configurations are not supported when [FeatureLayer#featureReduction](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#featureReduction) (e.g., clustering) is enabled (e.g., clustering).
 * > Field configurations are not supported in expression or relationship contexts in Arcade expressions. For example, fields referenced as `expression/abc123` or `relationships/0/field` do not currently support field configurations.
 * > The [FieldInfo#format](https://developers.arcgis.com/javascript/latest/api-reference/esri-popup-FieldInfo.html#format) property is used for date and number formatting when applied to unsupported layer types or contexts.
 * > When displaying [date/time fields](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-DateTimeFieldFormat.html), set the [DateTimeFieldFormat#timeStyle](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-DateTimeFieldFormat.html#timeStyle) property to either `long` or `full` if the view’s [MapView#timeZone](https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#timeZone) is set to `unknown` and the field includes time information.
 *
 * @since 4.34
 * @see [FeatureLayer#fieldConfigurations](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#fieldConfigurations)
 * @see [FeatureTable component](https://developers.arcgis.com/javascript/latest/references/map-components/arcgis-feature-table/)
 * @see [PopupTemplate](https://developers.arcgis.com/javascript/latest/api-reference/esri-PopupTemplate.html)
 * @see [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-DateTimeFieldFormat.html)
 * @see [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-NumberFieldFormat.html)
 * @see [FieldInfo](https://developers.arcgis.com/javascript/latest/api-reference/esri-popup-FieldInfo.html)
 * @example
 * // Create a number field format
 * const numberFormat = new NumberFieldFormat ({
 *   minimumFractionDigits: 2,
 *   maximumFractionDigits: 4,
 *   useGrouping: "always"
 * });
 *
 * // Create a field configuration object containing the number format
 * const numFieldConfiguration = new FieldConfiguration ({
 *   name: "lat", // name of the field in the service
 *   fieldFormat: numberFormat,
 *   alias: "Latitude"
 * });
 *
 * // Create a date-time field format
 * const dateTimeFormat = new DateTimeFieldFormat ({
 *   dateStyle: "medium",
 *   timeStyle: "short",
 *   hour12: "never"
 * });
 *
 * // Create a field configuration object containing the date format
 * const dateFieldConfiguration = new FieldConfiguration ({
 *   name: "collectionDate", // name of the field in the service
 *   fieldFormat: dateTimeFormat,
 *   alias: "Date Collected"
 * });
 *
 * // Create a feature layer and pass in the field configurations
 * const featureLayer = new FeatureLayer ({
 *   url: "url to feature layer",
 *   outFields: ["*"],
 *   fieldConfigurations: [numFieldConfiguration, dateFieldConfiguration] // add as many field configurations as needed
 *
 * });
 * @example
 * // Adding a new field configuration
 * const addNewConfig = (layer, fieldName, alias,
 * fieldFormat) => {
 *   const existingConfig = layer.getFieldConfiguration(fieldName);
 *   if (!existingConfig) {
 *     const newConfig = new FieldConfiguration ({ name: fieldName, alias, fieldFormat });
 *     const newConfigs = clone(layer.fieldConfigurations);
 *     newConfigs.push(newConfig);
 *     layer.fieldConfigurations = newConfigs;
 *   }
 * };
 * @example
 * // Updating an existing field configuration
 * const updateConfig = (layer, fieldName, alias,
 * fieldFormat) => {
 *   const existingConfig = layer.getFieldConfiguration(fieldName);
 *   if (existingConfig) {
 *     const newConfig = existingConfig.clone();
 *     newConfig.alias = alias;
 *     newConfig.fieldFormat = fieldFormat;
 *
 *     const index = layer.fieldConfigurations.indexOf(existingConfig);
 *     const newConfigs = clone(layer.fieldConfigurations);
 *     newConfigs[index] = newConfig;
 *     layer.fieldConfigurations = newConfigs;
 *   }
 * };
 * @example
 * // Deleting an existing field configuration
 * const deleteConfig = (layer, fieldName) => {
 *   const existingConfig = layer.getFieldConfiguration(fieldName);
 *   if(existingConfig) {
 *     const index = layer.fieldConfigurations.indexOf(existingConfig);
 *     var newConfigs = clone(layer.fieldConfigurations);
 *     newConfigs.splice(index, 1);
 *     layer.fieldConfigurations = newConfigs;
 *  }
 * };
 */
export default class FieldConfiguration extends FieldConfigurationSuperclass {
  constructor(properties?: FieldConfigurationProperties);
  /**
   * The alias (or display name) for the field. This is used in place of the field name when displaying the field in a widget or UI component. If not specified, the field's [Field#alias](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-Field.html#alias) is used. If the layer does not define an alias for the field, the field name itself is used.
   *
   * @see [FeatureLayer#getFieldAlias()](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-FeatureLayer.html#getFieldAlias)
   */
  accessor alias: string | null | undefined;
  /**
   * The format of the field. This can be either a [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-DateTimeFieldFormat.html) or [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-NumberFieldFormat.html) object. This is dependent upon the type of field.
   *
   * @see [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-DateTimeFieldFormat.html)
   * @see [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-layers-support-NumberFieldFormat.html)
   * @see [FieldInfo#fieldFormat](https://developers.arcgis.com/javascript/latest/api-reference/esri-popup-FieldInfo.html#fieldFormat)
   * @example
   * const fieldConfig = new FieldConfiguration({
   *   "name": "install_date",
   *   "alias": "Date of Installation",
   *   "fieldFormat": { // Autocast to DateTimeFieldFormat
   *      "type": "date-time",
   *      "dateStyle": "short",
   *      "timeStyle": "medium"
   *   }
   * });
   */
  get fieldFormat(): FieldFormatUnion | null | undefined;
  set fieldFormat(value: ((DateTimeFieldFormatProperties & { type: "date-time" }) | (NumberFieldFormatProperties & { type: "number" })) | null | undefined);
  /** The name of the field as defined by the feature layer. */
  accessor name: string;
}
declare const FieldConfigurationSuperclass: typeof JSONSupport & typeof ClonableMixin