import { BasePageData } from './BasePageData';
import { BaseSelfControl } from '../SelfModels/BaseSelfControl';
import { IMainStateFactory } from '../Types';
import { ElementsOfFormFactory } from './ElementsOfFormFactory';
export type IControlsElementType = HTMLElement;

export class TabingValuesClass {
  constructor(
    public propertyName: string,
    public control: IControlsElementType,
    public tabIndex: number,
    public isStatusbarOfStackControl: boolean,
  ) { }
}

export class TabbingControl {
  public controls: TabingValuesClass[] = [];
  constructor(public pageData: BasePageData) { }

  addControl = (
    propertyName: string,
    value: IControlsElementType,
    tabIndex: number,
    isStatusbarOfStackControl: boolean
  ) => {
    const control = this.controls.find((i) => i.propertyName === propertyName);
    if (control) {
      return;
    }

    const newControl = new TabingValuesClass(propertyName, value, tabIndex, isStatusbarOfStackControl);
    this.controls.push(newControl);
    this.controls.sort((a, b) => a.tabIndex - b.tabIndex);

    if (this.pageData.mainStacksFactory && this.pageData.mainStacksFactory.currentStack) {
      this.pageData.mainStacksFactory.currentStack.pageData.Eventing.trigger('form.control.new.add', newControl);
    } else {
      this.pageData.Eventing.trigger('form.control.new.add', newControl);
    }
  };

  removeControl = <S>(propertyName: keyof S) => {
    this.controls = this.controls.filter((i) => i.propertyName !== propertyName);
  };

  removeAllControls = () => {
    this.controls = [];
  };

  focuseToThisElement(index: number): void;
  focuseToThisElement<T extends {
    pageData: BasePageData;
  }>(fieldName: keyof T): void;
  focuseToThisElement(parameter1: any) {
    if (typeof parameter1 === 'number') {
      const current = this.controls.find((i) => i.tabIndex === parameter1);
      if (current) {
        current.control.focus();
      }
    } else if (typeof parameter1 === 'string') {
      const current = this.controls.find((i) => i.propertyName === parameter1);
      if (current) {
        this.pageData.updateFocuseState(current.tabIndex);
      }
    }
  }

  updateCurrentIndexByFocusForm(element: EventTarget) {
    if (this.pageData.selfState && this.pageData.selfState.elementsOfForm instanceof ElementsOfFormFactory) {
      this.pageData.selfState.elementsOfForm.updateCurrentIndexByFocusForm(element);
    } else {
      const current = this.controls.find((i) => i.control === element);
      if (current) {
        this.pageData.updateFocuseState(current.tabIndex);
      }
    }
  }

  gotoNextElementByEnter() {
    if (this.controls.length) {
      const currentItem = this.controls.find((i) => i.tabIndex === this.pageData.activeElementIndex);
      if (currentItem) {
        if (!this.pageData.selfState) {
          return;
        }
        const property = this.pageData.selfState[currentItem.propertyName];
        if (property instanceof BaseSelfControl) {
          property.validate();
          if (property.validation instanceof Array) {
            if (property.onErrorSimulateKey) {
              this.pageData.selfState.codeSimulateKeyDown(property.onErrorSimulateKey, currentItem.propertyName);
            } else {
              this.pageData.Eventing.trigger('form.controlValueNotValid', property.validation);
            }
            return;
          }
        }
      }
    }
    this.gotoNextElement();
  }

  getCurrentItem = () => {
    if (this.controls.length) {
      return this.controls.find(
        (i) => i.tabIndex === this.pageData.activeElementIndex
      );
    }
    return undefined;
  }
  gotoNextElementOfStatusBar = () => {
    const statusBarControl = this.controls.filter(i => i.isStatusbarOfStackControl);
    if (statusBarControl.length) {
      let nextItem;
      const currentIndex = this.pageData.activeElementIndex;
      if (typeof currentIndex === 'number') {
        nextItem =
          statusBarControl.find(
            (i) =>
              i.tabIndex > currentIndex &&
              i.control.tabIndex >= 0 &&
              !(i.control as HTMLInputElement).disabled &&
              !(i.control as HTMLInputElement).hidden
          ) || statusBarControl[0];
      } else {
        nextItem = statusBarControl[0];
      }

      this.pageData.activeElementIndex = nextItem.tabIndex;
      nextItem.control.focus();
      this.pageData.Eventing.trigger('form.change');
    }
  }
  gotoPreviousElementOfStatusBar = () => {
    const reverse = [...this.controls.filter(i => i.isStatusbarOfStackControl)].reverse();
    if (reverse.length) {
      let previousItem;
      const currentIndex = this.pageData.activeElementIndex;
      if (typeof currentIndex === 'number') {
        previousItem =
          reverse.find(
            (i) =>
              i.tabIndex < currentIndex &&
              i.control.tabIndex >= 0 &&
              !(i.control as HTMLInputElement).disabled &&
              !(i.control as HTMLInputElement).hidden
          ) || reverse[0];
      } else {
        previousItem = reverse[0];
      }

      this.pageData.activeElementIndex = previousItem.tabIndex;
      previousItem.control.focus();
    }
  }

  gotoNextElement() {
  }
  gotoPreviousElement() {

  }
}
