import AppBasePage from '../pages/v10/app-base.js'
const waitTime  = 1000;

export default class WaitActions {
  static async waitForAllLoaders (timeout, onlyVisibleInViewport=false) {
    let start = new Date().getTime();

    try {
      await this.waitForPageLoaders(timeout, true, onlyVisibleInViewport);
      // calculate remaining time after first wait for page loader
      let passedTime = new Date().getTime() - start;
      let interstart = new Date().getTime();
      timeout = timeout - passedTime;
      if (timeout < 100) {
          timeout = 100;
      }
      await this.waitForGenericLoaders(timeout, false, onlyVisibleInViewport);
      passedTime = new Date().getTime() - interstart;
      timeout = timeout - passedTime;
      if (timeout < 100) {
          timeout = 100;
      }
      await this.waitForBlockLoaders(timeout, false, onlyVisibleInViewport);
    } catch (error) {
      let passedTime = new Date().getTime() - start;
      error.message = error.message + '. Total wait time for all loaders was ' + passedTime + 'ms';
      throw error;
    }

  }

  static async waitForGenericLoaders (timeout, extraWait = true, onlyVisibleInViewport=false) {
      let appBasePage = new AppBasePage();
      let start = new Date().getTime();
      let loaders = await $(appBasePage.genericLoaders);
      if (extraWait) {
        try{
          await expect(loaders).toBeDisplayed({wait:waitTime, message:'Loaders not displayed'});
        }catch(error){}
      }
      let passedTime = new Date().getTime() - start;

      try {
          await (loaders).forEach(element => {
              let interstart = new Date().getTime();
              if (element.isDisplayed()){
                  element.scrollIntoView();
              }
              if (onlyVisibleInViewport){
                expect(element).not.toBeDisplayedInViewport({timeout:timeout, interval:100})
                //browser.waitUntil(!( element.isDisplayedInViewport()),{timeout:timeout, interval:100});
              } else {
                element.waitForDisplayed({timeout:timeout, reverse:true, interval:100});
              }
              
              passedTime = new Date().getTime() - interstart;
              timeout -= passedTime;
              if (timeout < 100) {
                  timeout = 100;
              }
          });
      } catch (error) {
          // Only fail test for timeout
          if (error.message.includes(' still displayed after ')) {
              throw error;
          }
      }
  }

  static async waitForBlockLoaders (timeout = defaultTimeout, extraWait = true, onlyVisibleInViewport=false) {
      let appBasePage = new AppBasePage();
      let start = new Date().getTime();
      let loaders = await $(appBasePage.blockLoader);
      if (extraWait) {
        try{
          await expect(loaders).toBeDisplayed({wait:waitTime, message:'Loaders not displayed'});
        }catch(error){}
      }
      let passedTime = new Date().getTime() - start;

      try {
          await (loaders).forEach(element => {
              let interstart = new Date().getTime();
              if ( element.isDisplayed()){
                 element.scrollIntoView();
              }
              if (onlyVisibleInViewport){
                expect(element).not.toBeDisplayedInViewport({timeout:timeout, interval:100})
                //browser.waitUntil(!(  element.isDisplayedInViewport()),{timeout:timeout, interval:100});
              } else {
                element.waitForDisplayed({timeout:timeout, reverse:true, interval:100});
              }
              passedTime = new Date().getTime() - interstart;
              timeout -= passedTime;
              if (timeout < 100) {
                  timeout = 100;
              }
          });
      } catch (error) {
          // Only fail test for timeout
          if (error.message.includes(' still displayed after ')) {
              throw error;
          }
      }
  }

  static async waitForPageLoaders (timeout, extraWait = true, onlyVisibleInViewport=false) {
      let appBasePage = new AppBasePage();
      let start = new Date().getTime();
      let element = await $(appBasePage.pageLoaders);
      if (extraWait) {
        try{
          await expect(element).toBeDisplayed({wait:waitTime, message:'Loaders not displayed'});
        }catch(error){}
      }
      let passedTime = new Date().getTime() - start;
      let to = timeout;

      try {
          to -= passedTime;
          if (to < 100) {
              to = 100;
          }
          if (await element.isDisplayed()){
            await element.scrollIntoView();
          }
          if (onlyVisibleInViewport){
            await expect(element).not.toBeDisplayedInViewport({timeout:timeout, interval:100})
            //await browser.waitUntil(!(await element.isDisplayedInViewport()),{timeout:timeout, interval:100});
          } else {
            await element.waitForDisplayed({timeout:timeout, reverse:true, interval:100});
          }
      } catch (error) {
          // Only fail test for timeout
          if (error.message.includes(' still displayed after ')) {
              throw error;
          }
      }
  }
}
