import focusTrap from './Modal.FocusTrap';
let modalImpl = {
  isKeyDownEventListenerConfigured: false,
  pageElementReference: null,
  listOfWrapperElementsToFloatingUI: [],
  eventHandlerRef: null,

  init(modalObj) {
    this.modalroot = modalObj.modalrootNode;
    this.floatinguicontainerelement = modalObj.wrapperObjForFloatingUI;
    this.UID = modalObj.UID;
    this.functionReferenceToFocus = modalObj.focusDialogReference ? modalObj.focusDialogReference : false;
    this.functionReferenceToClose = modalObj.closeDialogReference;
    this.isCloseOnEscapeNeeded = modalObj.isCloseOnEscapeNeeded;
    this.isTrapFocusNeeded = modalObj.isTrapFocusNeeded;
    modalImpl.pageElementNode = modalObj.pageElementNode;
    this.name = modalObj.modalname;
    modalImpl.persistFloatingUIInfoInList();

    if (modalImpl.eventHandlerRef === null) {
      modalImpl.bindKeyDownEventToDocument();
    }

    modalImpl.applyFocusToFloatingDialogElement();
    modalImpl.persistPageElementReference();
    console.log('After mount/update', modalImpl.listOfWrapperElementsToFloatingUI);
  },

  persistFloatingUIInfoInList() {
    modalImpl.listOfWrapperElementsToFloatingUI.push({
      [this.UID]: {
        modalroot: this.modalroot,
        floatinguicontainerelement: this.floatinguicontainerelement,
        functionReferenceToFocus: this.functionReferenceToFocus,
        functionReferenceToClose: this.functionReferenceToClose,
        isOverlayNeeded: !!this.freezeLayer,
        modalName: this.name
      }
    });
  },

  bindKeyDownEventToDocument() {
    if (modalImpl.eventHandlerRef === null) {
      modalImpl.eventHandlerRef = modalImpl.handleKeyPressEvent.bind(modalImpl);
      document.addEventListener('keydown', modalImpl.eventHandlerRef, true);
      console.log('inside add event', modalImpl);
    }
  },

  checkStatusOfKeyDownEventBoundToDocument() {
    return modalImpl.isKeyDownEventListenerConfigured;
  },

  setKeyDownEventBoundToDocumentStatusToTrue() {
    modalImpl.isKeyDownEventListenerConfigured = true;
  },

  handleKeyPressEvent(event) {
    // console.log('inside event');
    if (event.eventPhase === 3 || modalImpl.listOfWrapperElementsToFloatingUI.length === 0) {
      return false;
    }

    let modalImplInstance = this;

    if (event.key === 'Escape' && modalImplInstance.isCloseOnEscapeNeeded) {
      let floatingDialogContinerClassName = modalImplInstance.getClassNameOfClosestContainerElement(event.target);
      console.log('inside escape handler', floatingDialogContinerClassName);
      let indexOfContainerElement = floatingDialogContinerClassName === undefined ? modalImpl.listOfWrapperElementsToFloatingUI.length - 1 : modalImplInstance.getIndexOfContainerElement(floatingDialogContinerClassName);

      if (floatingDialogContinerClassName === undefined) {
        floatingDialogContinerClassName = modalImplInstance.getClassNameOfContainerElement(indexOfContainerElement);
      }

      modalImplInstance.invokeCloseCallBackFunctionOfDialogElement(indexOfContainerElement, floatingDialogContinerClassName);
    } else if (event.key === 'Tab') {
      modalImplInstance.isTabKeyPressed = true;
      let floatingDialogContinerClassName = modalImplInstance.getClassNameOfClosestContainerElement(event.target);

      if (floatingDialogContinerClassName !== undefined) {
        let indexOfContainerElement = modalImplInstance.getIndexOfContainerElement(floatingDialogContinerClassName);

        if (modalImplInstance.isTrapFocusNeeded) {
          focusTrap(event, modalImpl.listOfWrapperElementsToFloatingUI[indexOfContainerElement][floatingDialogContinerClassName].floatinguicontainerelement);
        }
      }
    }
  },

  applyFocusToFloatingDialogElement() {
    if (this.functionReferenceToFocus) {
      let indexOfContainerElement = this.getIndexOfContainerElement(this.UID);
      let floatingContainerObj = modalImpl.listOfWrapperElementsToFloatingUI[indexOfContainerElement][this.UID]; // console.log(typeof floatingContainerObj.functionReferenceToFocus);

      floatingContainerObj.functionReferenceToFocus();
    }
  },

  getClassNameOfClosestContainerElement(elemObj) {
    if (elemObj.closest('div[class^=floatingcontainer_]') !== null) {
      return elemObj.closest('div[class^=floatingcontainer_]').className;
    }
  },

  getClassNameOfContainerElement(index) {
    let containerObj = modalImpl.listOfWrapperElementsToFloatingUI[index];
    return Object.keys(containerObj)[0];
  },

  getContainerElement(index) {
    let containerObj = modalImpl.listOfWrapperElementsToFloatingUI[index];
    return containerObj[Object.keys(containerObj)[0]];
  },

  getIndexOfContainerElement(valueToMatch) {
    let that = this;
    return modalImpl.listOfWrapperElementsToFloatingUI.findIndex(function (element) {
      return that.findIndexOfContainerElement(element, valueToMatch);
    });
  },

  findIndexOfContainerElement(element, floatingDialogContinerClassName) {
    return Object.keys(element)[0] == floatingDialogContinerClassName;
  },

  removeFloatingUIContainerElement(index, refClass) {
    if (Object.keys(modalImpl.listOfWrapperElementsToFloatingUI[index])[0] === refClass) {
      let floatingContainerObj = modalImpl.listOfWrapperElementsToFloatingUI[index][refClass];
      let floatingContainerElem = floatingContainerObj.floatinguicontainerelement;
      let modalRoot = floatingContainerObj.modalroot;
      modalRoot.removeChild(floatingContainerElem);
      modalImpl.listOfWrapperElementsToFloatingUI.splice(index, 1);

      if (modalImpl.listOfWrapperElementsToFloatingUI.length === 0) {
        this.resetModalBoxValues();
      } else {
        let topElem = this.getContainerElement(modalImpl.listOfWrapperElementsToFloatingUI.length - 1);
        topElem.functionReferenceToFocus && topElem.functionReferenceToFocus();
      }
    }

    console.log('After Cleanup', modalImpl.listOfWrapperElementsToFloatingUI.length, modalImpl.listOfWrapperElementsToFloatingUI);
  },

  invokeCloseCallBackFunctionOfDialogElement(indexOfDialogElement, refClass) {
    modalImpl.listOfWrapperElementsToFloatingUI[indexOfDialogElement][refClass].functionReferenceToClose();
  },

  getTopMostFloatingUIContainerElement(refClass) {
    let lengthOfUIContainerElement = modalImpl.listOfWrapperElementsToFloatingUI.length;
    return modalImpl.listOfWrapperElementsToFloatingUI[lengthOfUIContainerElement - 1][refClass].floatinguicontainerelement;
  },

  getFloatingUIContainerElement(index, refClass) {
    return modalImpl.listOfWrapperElementsToFloatingUI[index][refClass].floatinguicontainerelement;
  },

  persistPageElementReference() {
    if (typeof this.pageElementNode !== 'undefined' && modalImpl.pageElementReference !== null) {
      modalImpl.pageElementReference = this.pageElementNode;
    }
  },

  applyFocusToPageElementReference() {
    if (modalImpl.pageElementReference != null) {
      modalImpl.pageElementReference.current.focus();
    }
  },

  resetPageElementReference() {
    modalImpl.pageElementReference = null;
  },

  reseteventHandlerRef() {
    modalImpl.eventHandlerRef = null;
  },

  unbindKeyDownEventListener() {
    document.removeEventListener('keydown', modalImpl.eventHandlerRef, true);
  },

  resetWrapperElementsList() {
    //console.log(this);  
    modalImpl.listOfWrapperElementsToFloatingUI = [];
  },

  resetModalBoxValues() {
    modalImpl.resetWrapperElementsList();
    modalImpl.applyFocusToPageElementReference();
    modalImpl.resetPageElementReference();
    modalImpl.unbindKeyDownEventListener();
    modalImpl.reseteventHandlerRef();
  }

};
export default modalImpl;