import { BaseSelfControl } from './BaseSelfControl';
import { ValidationEventArgs, ValidationChain } from '../chainOfResponsibility';
import { EnumValidateState } from '../enums';
import { IObject, IObjectJson } from './SelfObject';

export class SelfObjectArray<V extends IObject, J extends IObjectJson> extends BaseSelfControl<
  Array<V>,
  Array<J>,
  string,
  HTMLInputElement
> {


  public multiItemId?: number;
  public multiItemTimer?: NodeJS.Timeout;

  private validateNormal = (eventArgs: ValidationEventArgs) => {

  };
  private validateRequired = (eventArgs: ValidationEventArgs) => {
    if (this.required) {
      if (!this.value) {
        eventArgs.error = 'اطلاعاتی وارد نشده است';
        eventArgs.state = EnumValidateState.empty;
        eventArgs.cancel = true;
      }
    }
  };

  isValueEmpty = () => {
    return typeof this.#value === 'string' && this.#value !== '';
  }
  isValueNotEmpty = () => {
    return !this.isValueEmpty();
  }

  validate = () => {
    var validationChain = new ValidationChain();

    validationChain.validators.add(this.validateNormal);
    validationChain.validators.add(this.validateRequired);

    this.validation = validationChain.validate();
  };

  public cleaningClassInitializer = () => {
    this.hasChange = false;
    this.defaultValue = undefined;
    this.initializeProperties = false;
    this.initializeListener = false;
    this.validation = true;
    this.multiItemTimer && clearTimeout(this.multiItemTimer);
    delete this.multiItemId
    this.isTypedIncorrectChar = false;
  };

  public refreshHasChange = () => {
    if (this.showHasChangeFlag) {
      this.hasChange = this.defaultValue !== this.#value.join('');
    }
  };
  public restartDefaultValue = () => {
    this.defaultValue = this.#value.join('');
    this.refreshHasChange();
  };

  #value: Array<V>;
  public get value() {
    return this.#value;
  }
  public set value(value: Array<V>) { }

  public setValue = (value: Array<V>) => {
    this.#value = value;
    this.refreshHasChange();
  };
  public get ids() {
    return this.value.map(i => i.id);
  }

  public deserialize = (jsons: Array<J>) => {
    this.#value = jsons.map(i => this._deserialize(i));
    this.restartDefaultValue();
  };

  public useAsFilter: boolean = false;
  public timer?: NodeJS.Timeout | null;
  public triggerChangeFilters?: () => void;

  constructor(
    private _deserialize: (json?: J) => V,
    value: Array<V>
  ) {
    super();
    this.#value = value;
    this.restartDefaultValue();
  }

  static empty<V extends IObject, J extends IObjectJson>(deserialize: (json?: J) => V): SelfObjectArray<V, J> {
    return new SelfObjectArray(deserialize, []);
  }
}
