import type { ClonableMixin } from "../../core/Clonable.js";
import type { JSONSupport } from "../../core/JSONSupport.js";
import type { FieldFormatUnion } from "./types.js";
import type { NumberFieldFormatProperties } from "./NumberFieldFormat.js";
import type { DateTimeFieldFormatProperties } from "./DateTimeFieldFormat.js";

export interface FieldConfigurationProperties extends Partial<Pick<FieldConfiguration, "alias" | "name">> {
  /**
   * The format of the field. This can be either a [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/DateTimeFieldFormat/) or [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/NumberFieldFormat/) object. This is dependent upon the type of field.
   *
   * @see [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/DateTimeFieldFormat/)
   * @see [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/NumberFieldFormat/)
   * @see [FieldInfo.fieldFormat](https://developers.arcgis.com/javascript/latest/references/core/popup/FieldInfo/#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/references/core/popup/FieldInfo/) objects. Although compatibility with [FieldInfo](https://developers.arcgis.com/javascript/latest/references/core/popup/FieldInfo/) is maintained for existing applications, [FieldConfiguration](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FieldConfiguration/) 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/references/core/layers/FeatureLayer/#fieldConfigurations) property before initializing components such as [FeatureTable](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-feature-table/) or [Popup](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-popup/) components. Configurations are created with the [FieldConfiguration](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FieldConfiguration/) class, where the [fieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/FieldConfiguration/#fieldFormat) property can be set to either a [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/DateTimeFieldFormat/) or [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/NumberFieldFormat/) 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/references/core/layers/FeatureLayer/) 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 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/references/core/popup/FieldInfo/#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/references/core/layers/support/DateTimeFieldFormat/), set the [DateTimeFieldFormat.timeStyle](https://developers.arcgis.com/javascript/latest/references/core/layers/support/DateTimeFieldFormat/#timeStyle) property to either `long` or `full` if the view’s [MapView.timeZone](https://developers.arcgis.com/javascript/latest/references/core/views/MapView/#timeZone) is set to `unknown` and the field includes time information.
 *
 * @since 4.34
 * @see [FeatureLayer.fieldConfigurations](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/#fieldConfigurations)
 * @see [FeatureTable component](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-feature-table/)
 * @see [PopupTemplate](https://developers.arcgis.com/javascript/latest/references/core/PopupTemplate/)
 * @see [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/DateTimeFieldFormat/)
 * @see [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/NumberFieldFormat/)
 * @see [FieldInfo](https://developers.arcgis.com/javascript/latest/references/core/popup/FieldInfo/)
 * @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/references/core/layers/support/Field/#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/references/core/layers/FeatureLayer/#getFieldAlias)
   */
  accessor alias: string | null | undefined;
  /**
   * The format of the field. This can be either a [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/DateTimeFieldFormat/) or [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/NumberFieldFormat/) object. This is dependent upon the type of field.
   *
   * @see [DateTimeFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/DateTimeFieldFormat/)
   * @see [NumberFieldFormat](https://developers.arcgis.com/javascript/latest/references/core/layers/support/NumberFieldFormat/)
   * @see [FieldInfo.fieldFormat](https://developers.arcgis.com/javascript/latest/references/core/popup/FieldInfo/#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