import { IResultOfValidate } from '../Page/ValidatingControl';
import { IControlSimulateKey } from '../Page/Events';

export abstract class BaseSelfControl<T, J, D, H> {
  public propertyName?: string;
  public onChangePropertyName: string | undefined;
  public keyOfJSON?: string;
  public keyOfResultValue?: string;
  public controlRef?: React.RefObject<H>;
  public required: boolean = false;
  public showHasChangeFlag?: boolean;
  public tabIndex?: number;
  public changeHeadOfStack?: number;

  public timerOfIncorrectChar?: NodeJS.Timeout;
  public isTypedIncorrectChar?: boolean = false;
  public filteredChar?: string;

  #hidden: boolean = false;
  public get hidden() {
    return this.#hidden;
  }
  public set hidden(value: boolean) {
    const oldValue = value;
    this.#hidden = value;
    if (!this.#hidden && this.#hidden !== oldValue && typeof this.validation !== 'boolean') {
      this.validate();
    }
  }


  public abstract value: T;
  public validation: IResultOfValidate = true;
  public abstract validate: () => void;
  public abstract isValueEmpty: () => boolean;
  public abstract isValueNotEmpty: () => boolean;
  public restartValidation = () => {
    this.validation = true;
  };

  public abstract cleaningClassInitializer: () => void;

  public defaultValue?: D;
  public abstract refreshHasChange: () => void;
  public abstract restartDefaultValue: () => void;
  public abstract setValue: (value: T) => void;
  public abstract deserialize: (value: J, information: any) => void;

  public initializeProperties: boolean = false;
  public initializeListener: boolean = false;

  public caption?: string;
  public captionAddress?: string;
  public onErrorSimulateKey?: IControlSimulateKey;

  private _hasChange = false;
  public get hasChange(): boolean {
    return this._hasChange;
  }
  public set hasChange(value: boolean) {
    this._hasChange = value;
  }
}
