import { BaseSelfControl } from './BaseSelfControl';
import { EnumValidateState } from '../enums';
import { ValidationChain, ValidationEventArgs } from '../chainOfResponsibility';
import { ISpecifierCheckTreeView, IStructrulCodeTreeViewJson } from '../ComponentFactory/StructructrulCode/StructrulCodeTreeViewCode';

export class SelfCheckedIDs extends BaseSelfControl<
  number[],
  number[],
  string,
  HTMLDivElement
> {
  public onlyLastLevel: boolean = false;
  private validateNormal(eventArgs: ValidationEventArgs) { }
  private validateRequired = (eventArgs: ValidationEventArgs) => {
    if (this.required) {
      if (!this.value || this.value.length === 0) {
        eventArgs.cancel = true;
        eventArgs.state = EnumValidateState.empty;
        eventArgs.error = 'هیچ کدی انتخاب نشده است';
      }
    }
  };

  isValueEmpty = () => {
    return this.#value instanceof Array && this.#value.length > 0;
  }
  isValueNotEmpty = () => {
    return !this.isValueEmpty();
  }

  public 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.initializeListener = false;
    this.initializeProperties = false;
    this.validation = true;
  };

  public checkStates: ISpecifierCheckTreeView[] = [];
  public refreshHasChange = () => {
    if (this.showHasChangeFlag) {
      this.hasChange = this.defaultValue !== this.#value.toString();
    }
  };
  public restartDefaultValue = () => {
    this.defaultValue = this.value.toString();
    this.refreshHasChange();
  };

  #value: number[];
  public get value() {
    return this.#value;
  }
  public set value(value: number[]) { }

  public setValue = (ids: number[]) => {
    this.#value = ids;
    this.refreshHasChange();
  };
  public setcheckStates = (
    ids: number[],
    states: ISpecifierCheckTreeView[]
  ) => {
    this.#value = ids;
    this.checkStates = states;
    this.refreshHasChange();
  };

  public deserialize = (value: number[], checkStates: ISpecifierCheckTreeView[]) => {
    this.setcheckStates(value, checkStates);
    this.restartDefaultValue();
  };

  constructor() {
    super();
    this.#value = [];
    this.restartDefaultValue();
  }

  static empty(): SelfCheckedIDs {
    return new SelfCheckedIDs();
  }
  static deserialize(value?: IStructrulCodeTreeViewJson[]): SelfCheckedIDs {
    if (value) {
      const des = new SelfCheckedIDs();
      value.forEach((i) => {
        const selfCheckTree: ISpecifierCheckTreeView = {
          id: i.id,
          isFromChild: i.isFromChild ? i.isFromChild : false,
          isFromParent: false,
          code: i,
        };

        if (!selfCheckTree.isFromChild) {
          des.#value.push(i.id);
        }
        des.checkStates.push({
          id: i.id,
          isFromParent: false,
          isFromChild: selfCheckTree.isFromChild,
          code: i,
        });
      });
      return des;
    } else {
      return SelfCheckedIDs.empty();
    }
  }
}
