import { VegaSlimmer } from '../../../../vega-slimmer/vega-slimmer-core';
import { ImmutableMap } from '../../../../helpers/immutable/immutable-map';
import { VegaForm } from '../../vega-form';
import { FormControlOption, FormValidateResult } from '../../types';
import { ChildNodesNotifyObserverSlimmer } from '../../../../helpers/event-manager/slimmers/child-nodes-notify-observer-slimmer';
/**
 * The form field controller for vega form to manage the form field states.
 */
export declare class VegaFormFieldController extends VegaSlimmer {
  host: VegaForm['host'];
  isValid: VegaForm['isValid'];
  isTouched: VegaForm['isTouched'];
  protected childNotifyObserver: ChildNodesNotifyObserverSlimmer<unknown>;
  protected childNodeValueChangeObserver: ChildNodesNotifyObserverSlimmer<unknown>;
  private formFieldPendingValidObserver;
  private formFieldDisconnectedObserver;
  private _invalidFieldPathMap;
  /**
   * The form field element pending async valid map
   */
  private _pendingValidFieldPathMap;
  /**
   * Component lifecycle - [connectedCallback]
   */
  connectedCallback(): void;
  /**
   * When the vegaForm is deleted, it is necessary to notify the parent's vegaForm to update its isValid status.
   */
  disconnectedCallback(): void;
  /**
   * @inheritDoc
   */
  getValue<T>(option?: FormControlOption): Promise<T>;
  /**
   * @inheritDoc
   */
  setValue<T>(value: T, option?: FormControlOption): Promise<void>;
  /**
   * @inheritDoc
   */
  valid(showError?: boolean | 'rule'): Promise<FormValidateResult>;
  /**
   * The getter for the {@link _invalidFieldPathMap}
   *
   * @returns {ImmutableMap<HTMLElement, string>} The map of invalid field elements and their paths
   */
  get invalidFieldPathMap(): ImmutableMap<HTMLElement, string>;
  /**
   * The getter for the {@link _pendingValidFieldPathMap}
   *
   * @returns {ImmutableMap<HTMLElement, string>} The map of pending valid field elements and their paths
   */
  get pendingValidFieldPathMap(): ImmutableMap<HTMLElement, string>;
  /**
   * Set the isTouched property of the form.
   *
   * @param {boolean} isTouched - The new value for isTouched.
   */
  setIsTouched(isTouched: boolean): void;
  /**
   * It returns the value of data-vega-form that the given element is associated with.
   *
   * @param {HTMLElement} element - The element that is being validated.
   * @returns {string} The name of the field.
   */
  getFormFieldName(element: HTMLElement): string;
  /**
   * Check if the given element is part of the current form.
   *
   * @param {HTMLElement} element - The element to check.
   * @returns {boolean} True if the element is part of the current form, false otherwise.
   */
  isElementInCurrentForm(element: HTMLElement): boolean;
  /**
   * Navigate the immediate child node under current vega form element with the following strategy
   *  - if a matched vega field element found, will pass it to the visitor method passed in
   *  - if a non-matched node found, it will call itself recursively and pass the node as the second parameter
   * Once the navigation is finished, it will wait for all the pending visitor/self-invocation promise finished before return
   *
   * @param  {(element: HTMLElement, isForm: boolean) => Promise<void>} visitor async callback method that will be invoked if a matched vega field element found
   * @param {FormControlOption} [option] form control option to skip disabled/invisible components
   * @param {HTMLElement} [startElementNode=this.host] the element to start the navigation, default to current vega form host
   * @returns {Promise<void>} return void wrapped with promise to notify the navigation is done
   */
  navigateVegaFormChildren(visitor: (element: HTMLElement, isForm: boolean) => Promise<void>, option?: FormControlOption, startElementNode?: HTMLElement): Promise<void>;
  /**
   * Update the {@link isValid} property value based on the size of {@link invalidFieldPathMap}
   * If the number of invalid elements is zero, then the form is valid.
   */
  private updateIsValidFlag;
  /**
   * Registers an observer with the ChangeManager that will be notified when a form field's pending validation state changes.
   */
  private registerFormFieldPendingValid;
  /**
   * Can accept handler for FORM_FIELD_PENDING_VALID_CHANGE.
   *
   * @param {PendingValidPayload} payload - The payload containing the host element that triggered the pending valid change event.
   * @returns {boolean} True if the host element is part of the current form, false otherwise.
   */
  private canAcceptFormFieldPendingValid;
  /**
   * Handles the pending valid state change for a form field.
   *
   * @param {PendingValidPayload} payload - The payload containing the host element and its pending valid state.
   */
  private handleFieldPendingValid;
  /**
   * This function registers an observer with the ChangeManager that will be notified when an element
   * delete operation is triggered
   */
  private initFormFieldDisconnectedObserver;
  /**
   * If the deleted element is a child or grandchild of current vegaForm, the isValid of all these vegaForms will be updated.
   *
   * @param {DisconnectedElementOperationPayload} payload -  the delete element and vegaForm array.
   * @returns {boolean} A boolean value.
   */
  private canAcceptFormFieldDisconnectedOperation;
  /**
   * Get the fieldName of the deleted element in the current vegaForm, delete it from the invalidFieldPathSet array, and update isValid at the same time.
   *
   * @param {DisconnectedElementOperationPayload} payload - the delete element and vegaForm array.
   */
  private updateInvalidFieldPath;
  /**
   * Return true if the HTMLElement has data-vega-form property, and it's not disabled and not invisible if these two properties have to be checked.
   *
   * @param {HTMLElement} element - The HTMLElement to check.
   * @param {boolean} skipDisabled - If true, then disabled form fields will be skipped.
   * @param {boolean} skipInvisible - If true, only visible elements will be visited.
   * @returns {boolean} a boolean value.
   */
  private shouldVisitElement;
  /**
   * If the element is valid, remove it from the set of
   *    invalid elements. If the element is invalid,
   *    add it to the set of invalid elements.
   *
   * @param {NotifyObserverPayload<boolean>} payload - CustomEvent<boolean> the vegaValidate subject notify from child elements
   */
  private updateInternalValidStatus;
  /**
   * It retrieves the value of a form field element.
   *
   * @param {HTMLElement} element - The form field element.
   * @returns {unknown} The value of the form field element.
   */
  private getFormFieldValue;
  /**
   * It handles the validation of a child form field element.
   *
   * @param {HTMLElement} element - The form field element to validate.
   * @param {boolean | 'rule'} showError - Whether to show error messages.
   * @returns {Promise<EvaluateResultBase>} The validation result.
   */
  private handleChildFormFieldElementValid;
}
