import { TabbingControl, IControlsElementType } from './TabbingControl';
import { ValidatingControl } from './ValidatingControl';
import { ChangingControl } from './ChangingControl';
import { MainStateManager } from '../MainStateManager';
import { Events } from './Events';
import { TouchingControl } from './TouchingControl';
import { IArmisaPageKey } from '../ArmisaImportPage';
import { MouseLocationProps, PopupPageData, TLocationPopup } from './Modal/ModalPopup';
import { StackIcon } from '../ModalOfStack/IconOfMenu';
import { MainStacksFactory } from '../ModalOfStack/Main';
import { UserOption } from '../User';
import { CaptionNaming, INaming } from '../NamingCaption';
import { IMainStateFactory } from '../Types';
import { ElementsOfFormFactory } from './ElementsOfFormFactory';


export class PropsOfPage {
  static buildNewTag(tag: any, listOfUserOptions?: IArmisaPageKey[]): PropsOfPage {
    const result = new PropsOfPage();
    result.tag = tag;
    result.listOfUserOptionsLoadBeforStart = listOfUserOptions;
    return result;
  }
  static buildNewCode(code: string): PropsOfPage {
    const result = new PropsOfPage();
    result.code = code;
    return result;
  }
  static buildNewHeadId(id: number): PropsOfPage {
    const result = new PropsOfPage();
    result.headId = id;
    return result;
  }
  static buildNewArticleId(id: number): PropsOfPage {
    const result = new PropsOfPage();
    result.articleId = id;
    return result;
  }
  public tag: any;
  public headId?: number;
  public articleId?: number;
  public code?: string;
  public listOfUserOptionsLoadBeforStart?: IArmisaPageKey[];
}


export class StackHeaderFields {
  constructor(
    public index: number,
    public fieldName: string,
    public caption?: string,
  ) { }

  static buildNew<T>(index: number, fieldName: keyof T, caption: string) {
    return new StackHeaderFields(index, fieldName as any, caption);
  }
};

export abstract class BasePageData {
  public accessOfAcceptKeyIsAccepted = true;
  public accessOfNewKeyIsAccepted = true;
  public accessOfViewKeyIsAccepted = true;
  public accessOfEditKeyIsAccepted = true;
  public accessOfDeleteKeyIsAccepted = true;
  public accessOfF9KeyIsAccepted = true;

  public isMainOfStacks?: boolean;
  public mainStacksFactory?: MainStacksFactory;

  public Eventing = new Events();

  public initializeFieldSetListener: boolean = false;
  public initializeFormListener: boolean = false;
  public initializeHook: boolean = false;
  public isInitializeHookForFirstTime: boolean = false;
  public onLoadStartMethod?: Function;
  public initializeStackMenuContainer: boolean = false;

  public formType: 'accepting' | 'modifing' = 'modifing';
  public selfState: any;
  public gridViewFactory: any;
  public gridViewTabIndex: number | undefined;
  public gridViewCurrentCellRef?: React.RefObject<IControlsElementType>;
  public gridViewRef?: React.RefObject<HTMLDivElement>;

  public isActive: boolean = true;

  public abstract TabbingControl: TabbingControl;
  public abstract ValidatingControl: ValidatingControl;
  public abstract TouchingControl: TouchingControl;
  public abstract ChangingControl: ChangingControl;
  protected abstract _modal?: BasePageData;
  protected abstract _popup?: BasePageData;
  public abstract modal: BasePageData | undefined;
  public abstract popup: PopupPageData | undefined;

  public id: string;
  public readonlyMode: boolean | undefined;
  public caption: string;
  public defaultCaptionOfPage?: string;
  public activeElementIndex: number = 0;
  public dontHandleActiveElementBySelef: boolean = false;
  public stackIcons?: StackIcon[];
  public props?: PropsOfPage;
  public component: any;
  public stackHeaderFields?: StackHeaderFields[] = undefined;
  public addStackHeadersField = (data: StackHeaderFields) => {
    if (!this.stackHeaderFields || data.index === 1) {
      this.stackHeaderFields = [];
    }
    const result = [...this.stackHeaderFields, data];
    this.stackHeaderFields = result.sort((i, j) => i < j ? -1 : i === j ? 0 : 1);
  }

  private _pageKey?: IArmisaPageKey = undefined;
  public get any(): any {
    return this;
  }

  public get pageKey() {
    return this._pageKey!;
  }
  public set pageKey(value: IArmisaPageKey) {
    this._pageKey = value;
    // this._userOptions = this.mainStateManager.Usering.userOptions?.filter((i: any) => i.form === this._pageKey);
  }
  private _userOptions?: UserOption[];
  public get userOptions() {
    return this._userOptions;
  }
  public set userOptions(value: UserOption[] | undefined) {
    this._userOptions = value;
  }
  public addUserOption = (userOption: UserOption) => {
    if (!this._userOptions) {
      this._userOptions = [];
      this._userOptions.push(userOption);
    } else {
      const finded = this._userOptions.find(i => i.form === userOption.form && i.key === userOption.key);
      if (finded) {
        finded.value = userOption.value;
        userOption = finded;
      } else {
        this._userOptions.push(userOption);
      }
    }

  }

  public getNaming = (value: string | CaptionNaming | INaming) => {
    if (typeof value === 'string') {
      return value;
    }

    if (value instanceof CaptionNaming) {
      // return (value as any)[this.mainStateManager.Languaging.languageSuffix];
    }

    if (Array.isArray(value) && value.length == 2) {
      return value[1];
    }

    const typeOfValue = typeof value === 'object';
    const fa = 'FA' in value;
    const en = 'EN' in value;

    if (typeOfValue && fa && en) {
      // return (value as any)[this.mainStateManager.Languaging.languageSuffix];
    }
  }

  public getUserOption = (key: string) => {
    return this._userOptions && this._userOptions.find(i => i.key === key)?.value;
  }

  public setUserOption = <V>(key: string, value: V, defaultValue: V, columnOfReports: IArmisaPageKey[], isSave?: boolean) => {
    if (!this._userOptions) {
      this._userOptions = [];
    }

    const finded = this._userOptions.find(i => i.key === key);

    const valueString = (value as any).toString();
    if (finded) {
      const defaultValueString = (defaultValue as any).toString();

      if (valueString === defaultValueString) {
        // this.mainStateManager.Usering.removeUserOption(finded.key, [finded.form, ...columnOfReports], true);
      } else {
        finded.value = valueString;
        if (isSave) {
          // this.mainStateManager.Usering.saveUserOption(finded.key, [finded.form, ...columnOfReports], valueString);
        }
      }
    } else {
      // this.mainStateManager.Usering.addUserOption(key, [this.pageKey, ...columnOfReports], valueString, isSave);
    }
  }



  constructor(public mainStateManager: MainStateManager) {
    this.id = Math.random().toString() + '-' + new Date().getMilliseconds().toString();
    this.caption = '';
    this.component = undefined;

    // this.mainStateManager.Eventing.on(this.id, 'addNewModal', (parentPage: BasePageData, modalPage: BasePageData) => {
    //   this.isActive = modalPage === this;

    //   if (this.isActive) {
    //     this.Eventing.trigger('form.getActive');
    //   } else {
    //     this.Eventing.trigger('form.disabled');
    //   }
    // }
    // );

    // this.mainStateManager.Eventing.on(this.id, 'addNewModalPage', (parentPage: BasePageData, modalPage: BasePageData) => {
    //   this.isActive = modalPage === this;

    //   if (this.isActive) {
    //     this.Eventing.trigger('form.getActive');
    //   } else {
    //     this.Eventing.trigger('form.disabled');
    //   }
    // }
    // );

    // this.mainStateManager.Eventing.on(this.id, 'addNewPopup', (parentPage: BasePageData, popupPage: BasePageData) => {
    //   this.isActive = popupPage === this;

    //   if (this.isActive) {
    //     this.Eventing.trigger('form.getActive');
    //   } else {
    //     this.Eventing.trigger('form.disabled');
    //   }
    // }
    // );

    // this.mainStateManager.Eventing.on(this.id, 'addNewPopupPage', (parentPage: BasePageData, popupPage: BasePageData) => {
    //   this.isActive = popupPage === this;

    //   if (this.isActive) {
    //     this.Eventing.trigger('form.getActive');
    //   } else {
    //     this.Eventing.trigger('form.disabled');
    //   }
    // }
    // );

    // this.mainStateManager.Eventing.on(this.id, 'closeModal', (activePage?: BasePageData) => {
    //   this.isActive = activePage === this;

    //   if (this.isActive) {
    //     this.Eventing.trigger('form.getActive');
    //   }
    // }
    // );

    // this.mainStateManager.Eventing.on(this.id, 'closePopup', (activePage?: BasePageData) => {
    //   this.isActive = activePage === this;

    //   if (this.isActive) {
    //     this.Eventing.trigger('form.getActive');
    //   }
    // }
    // );

    // this.mainStateManager.Eventing.on(this.id, 'showWaitingModal', () => {
    //   if (this.isActive) {
    //     this.isActive = false;

    //     this.Eventing.trigger('form.disabled');
    //   }
    // });
    // this.mainStateManager.Eventing.on(this.id, 'closeWaitingModal', (activePage?: BasePageData) => {
    //   if (!this.modal) {
    //     this.isActive = activePage === this;

    //     if (this.isActive) {
    //       this.Eventing.trigger('form.getActive');
    //     }
    //   }
    // }
    // );

    // this.mainStateManager.Eventing.on(this.id, 'addNewTab', (activePage: BasePageData) => {
    //   this.isActive = this === activePage;
    //   if (this.isActive) {
    //     this.Eventing.trigger('form.getActive');
    //   } else {
    //     this.Eventing.trigger('form.disabled');
    //   }
    // }
    // );

    // this.mainStateManager.Eventing.on(this.id, 'closeTab', (activePage?: BasePageData) => {
    //   this.isActive = this === activePage;
    //   if (this.isActive) {
    //     this.Eventing.trigger('form.getActive');
    //   }
    // }
    // );
    // this.mainStateManager.Eventing.on(this.id, 'selectTab', (activePage: BasePageData) => {
    //   if (this.mainStateManager.Tabing.tabs.find(i => i.id === this.id)) {
    //     this.isActive = this === activePage;
    //     if (this.isActive) {
    //       this.Eventing.trigger('form.getActive');
    //     }
    //   }
    // }
    // );
  }

  public updateFocuseState = (controlIndex?: number) => {

  }

  public updateFocuseStateOld = (controlIndex?: number) => {
    if (this.dontHandleActiveElementBySelef) {
      return;
    }
    if (typeof controlIndex === 'number') {
      this.activeElementIndex = controlIndex;
    }

    if (this.isActive) {
      if (this.activeElementIndex === this.gridViewTabIndex) {
        if (
          this.gridViewCurrentCellRef &&
          this.gridViewCurrentCellRef.current
        ) {
          this.gridViewCurrentCellRef.current.focus();
        } else {
          this.TabbingControl.focuseToThisElement(this.activeElementIndex);
        }
      } else {
        this.TabbingControl.focuseToThisElement(this.activeElementIndex);
      }
    }
  };

  public abstract get hasChange(): boolean;
  abstract updateHasChange: () => void;

  onClickCancelButton() { }
  onClickHelpButton() { }

  setHelpElementRef() { }

  // showModalWaiting = () => {
  //   this.mainStateManager.Modaling.showWaitingModal(this);
  // };
  // closeModalWaiting = () => {
  //   this.mainStateManager.Modaling.closeWaitingModal(this);
  // };

  public abstract selectThisPage: () => void;
  public abstract closeThisPage: () => void;

  public abstract showModal: (component: JSX.Element) => void;
  public abstract showModalPage: (
    pageKey: IArmisaPageKey | undefined,
    props: PropsOfPage,
    isMainOfStacks?: boolean
  ) => void;

  public abstract showPopup: (component: JSX.Element, mouseLocation?: MouseLocationProps | React.MouseEvent, location?: TLocationPopup, byArrow?: boolean) => void;
  public abstract showPopupPage: (
    pageKey: IArmisaPageKey | undefined,
    props: PropsOfPage
  ) => void;

  public abstract closeModal: () => void;
  public abstract closePopup: () => void;


}
