/* global KEEP */

KEEP.initUtils = () => {

  KEEP.utils = {

    html_root_dom: document.querySelector('html'),
    pageContainer_dom: document.querySelector('.page-container'),
    pageTop_dom: document.querySelector('.page-main-content-top'),
    firstScreen_dom: document.querySelector('.first-screen-container'),
    scrollProgressBar_dom: document.querySelector('.scroll-progress-bar'),
    pjaxProgressBar_dom: document.querySelector('.pjax-progress-bar'),
    pjaxProgressIcon_dom: document.querySelector('.pjax-progress-icon'),
    back2TopButton_dom: document.querySelector('.tool-scroll-to-top'),

    innerHeight: window.innerHeight,
    pjaxProgressBarTimer: null,
    prevScrollValue: 0,
    fontSizeLevel: 0,

    isHasScrollProgressBar: KEEP.theme_config.style.scroll.progress_bar.enable === true,
    isHasScrollPercent: KEEP.theme_config.style.scroll.percent.enable === true,

    // Scroll Style Handle
    styleHandleWhenScroll() {
      const scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
      const scrollHeight = document.body.scrollHeight || document.documentElement.scrollHeight;
      const clientHeight = window.innerHeight || document.documentElement.clientHeight;

      const percent = Math.round(scrollTop / (scrollHeight - clientHeight) * 100);

      if (this.isHasScrollProgressBar) {
        const ProgressPercent = (scrollTop / (scrollHeight - clientHeight) * 100).toFixed(3);
        this.scrollProgressBar_dom.style.visibility = percent === 0 ? 'hidden' : 'visible';
        this.scrollProgressBar_dom.style.width = `${ProgressPercent}%`;
      }

      if (this.isHasScrollPercent) {
        const percent_dom = this.back2TopButton_dom.querySelector('.percent');
        if (percent === 0 || percent === undefined) {
          this.back2TopButton_dom.classList.remove('show');

        } else {
          this.back2TopButton_dom.classList.add('show');
          percent_dom.innerHTML = percent.toFixed(0);
        }
      }

      // hide header handle
      if (scrollTop > this.prevScrollValue && scrollTop > this.innerHeight) {
        this.pageTop_dom.classList.add('hide');
      } else {
        this.pageTop_dom.classList.remove('hide');
      }
      this.prevScrollValue = scrollTop;
    },

    // register window scroll event
    registerWindowScroll() {
      window.addEventListener('scroll', () => {
        // style handle when scroll
        if (this.isHasScrollPercent || this.isHasScrollProgressBar) {
          this.styleHandleWhenScroll();
        }

        // TOC scroll handle
        if (KEEP.theme_config.toc.enable && KEEP.utils.hasOwnProperty('findActiveIndexByTOC')) {
          KEEP.utils.findActiveIndexByTOC();
        }

        // header shrink
        KEEP.utils.headerShrink.headerShrink();
      });
    },

    // toggle show tools list
    toggleShowToolsList() {
      document.querySelector('.tool-toggle-show').addEventListener('click', () => {
        document.querySelector('.side-tools-list').classList.toggle('show');
      });
    },

    // global font adjust
    globalFontAdjust() {
      const fontSize = document.defaultView.getComputedStyle(document.body).fontSize;
      const fs = parseFloat(fontSize);

      const initFontSize = () => {
        const styleStatus = KEEP.getStyleStatus();
        if (styleStatus) {
          this.fontSizeLevel = styleStatus.fontSizeLevel;
          setFontSize(this.fontSizeLevel);
        }
      }

      const setFontSize = (fontSizeLevel) => {
        this.html_root_dom.style.fontSize = `${fs * (1 + fontSizeLevel * 0.05)}px`;
        KEEP.styleStatus.fontSizeLevel = fontSizeLevel;
        KEEP.setStyleStatus();
      }

      initFontSize();

      document.querySelector('.tool-font-adjust-plus').addEventListener('click', () => {
        if (this.fontSizeLevel === 5) return;
        this.fontSizeLevel++;
        setFontSize(this.fontSizeLevel);
      });

      document.querySelector('.tool-font-adjust-minus').addEventListener('click', () => {
        if (this.fontSizeLevel <= 0) return;
        this.fontSizeLevel--;
        setFontSize(this.fontSizeLevel);
      });
    },

    // toggle content area width
    contentAreaWidthAdjust() {
      const toolExpandDom = document.querySelector('.tool-expand-width');
      const headerContentDom = document.querySelector('.header-content');
      const mainContentDom = document.querySelector('.main-content');
      const iconDom = toolExpandDom.querySelector('i');

      const defaultMaxWidth = KEEP.theme_config.style.content_max_width || '1000px';
      const expandMaxWidth = '90%';
      let headerMaxWidth = defaultMaxWidth;

      let isExpand = false;

      if (KEEP.theme_config.style.first_screen.enable === true && window.location.pathname === '/') {
        headerMaxWidth = parseInt(defaultMaxWidth) * 1.2 + 'px';
      }

      const setPageWidth = (isExpand) => {
        KEEP.styleStatus.isExpandPageWidth = isExpand;
        KEEP.setStyleStatus();
        if (isExpand) {
          iconDom.classList.remove('fa-arrows-alt-h');
          iconDom.classList.add('fa-compress-arrows-alt');
          headerContentDom.style.maxWidth = expandMaxWidth;
          mainContentDom.style.maxWidth = expandMaxWidth;
        } else {
          iconDom.classList.remove('fa-compress-arrows-alt');
          iconDom.classList.add('fa-arrows-alt-h');
          headerContentDom.style.maxWidth = headerMaxWidth;
          mainContentDom.style.maxWidth = defaultMaxWidth;
        }
      }

      const initPageWidth = () => {
        const styleStatus = KEEP.getStyleStatus();
        if (styleStatus) {
          isExpand = styleStatus.isExpandPageWidth;
          setPageWidth(isExpand);
        }
      }

      initPageWidth();

      toolExpandDom.addEventListener('click', () => {
        isExpand = !isExpand;
        setPageWidth(isExpand)
      });


    },

    // go comment anchor
    goComment() {
      this.goComment_dom = document.querySelector('.go-comment');
      if (this.goComment_dom) {
        this.goComment_dom.addEventListener('click', () => {
          document.querySelector('#comment-anchor').scrollIntoView();
        });
      }

    },

    // get dom element height
    getElementHeight(selectors) {
      const dom = document.querySelector(selectors);
      return dom ? dom.getBoundingClientRect().height : 0;
    },

    // init first screen height
    initFirstScreenHeight() {
      this.firstScreen_dom && (this.firstScreen_dom.style.height = this.innerHeight + 'px');
    },

    // init page height handle
    initPageHeightHandle() {
      if (this.firstScreen_dom) return;
      const temp_h1 = this.getElementHeight('.page-main-content-top');
      const temp_h2 = this.getElementHeight('.page-main-content-middle');
      const temp_h3 = this.getElementHeight('.page-main-content-bottom');
      const allDomHeight = temp_h1 + temp_h2 + temp_h3;
      const innerHeight = window.innerHeight;
      const pb_dom = document.querySelector('.page-main-content-bottom');
      if (allDomHeight < innerHeight) {
        const marginTopValue = Math.floor(innerHeight - allDomHeight);
        if (marginTopValue > 0) {
          pb_dom.style.marginTop = `${marginTopValue - 2}px`;
        }
      }
    },

    // big image viewer
    imageViewer() {
      let isBigImage = false;

      const showHandle = (maskDom, isShow) => {
        document.body.style.overflow = isShow ? 'hidden' : 'auto';
        if (isShow) {
          maskDom.classList.add('active');
        } else {
          maskDom.classList.remove('active');
        }
      }

      const imageViewerDom = document.querySelector('.image-viewer-container');
      const targetImg = document.querySelector('.image-viewer-container img');
      imageViewerDom && imageViewerDom.addEventListener('click', () => {
        isBigImage = false;
        showHandle(imageViewerDom, isBigImage);
      });

      const imgDoms = document.querySelectorAll('.markdown-body img');

      if (imgDoms.length) {
        imgDoms.forEach(img => {
          img.addEventListener('click', () => {
            isBigImage = true;
            showHandle(imageViewerDom, isBigImage);
            targetImg.setAttribute('src', img.getAttribute('src'));
          });
        });
      } else {
        this.pageContainer_dom.removeChild(imageViewerDom);
      }
    },

    // set how long ago language
    setHowLongAgoLanguage(p1, p2) {
      return p2.replace(/%s/g, p1)
    },

    getHowLongAgo(timestamp) {
      const l = KEEP.language_ago;

      const __Y = Math.floor(timestamp / (60 * 60 * 24 * 30) / 12);
      const __M = Math.floor(timestamp / (60 * 60 * 24 * 30));
      const __W = Math.floor(timestamp / (60 * 60 * 24) / 7);
      const __d = Math.floor(timestamp / (60 * 60 * 24));
      const __h = Math.floor(timestamp / (60 * 60) % 24);
      const __m = Math.floor(timestamp / 60 % 60);
      const __s = Math.floor(timestamp % 60);

      if (__Y > 0) {
        return this.setHowLongAgoLanguage(__Y, l.year);

      } else if (__M > 0) {
        return this.setHowLongAgoLanguage(__M, l.month);

      } else if (__W > 0) {
        return this.setHowLongAgoLanguage(__W, l.week);

      } else if (__d > 0) {
        return this.setHowLongAgoLanguage(__d, l.day);

      } else if (__h > 0) {
        return this.setHowLongAgoLanguage(__h, l.hour);

      } else if (__m > 0) {
        return this.setHowLongAgoLanguage(__m, l.minute);

      } else if (__s > 0) {
        return this.setHowLongAgoLanguage(__s, l.second);
      }
    },

    setHowLongAgoInHome() {
      const post = document.querySelectorAll('.home-article-meta-info .home-article-date');
      post && post.forEach(v => {
        const nowDate = Date.now();
        const postDate = new Date(v.dataset.date.split(' GMT')[0]).getTime();
        v.innerHTML = this.getHowLongAgo(Math.floor((nowDate - postDate) / 1000));
      });
    },

    // loading progress bar start
    pjaxProgressBarStart() {
      this.pjaxProgressBarTimer && clearInterval(this.pjaxProgressBarTimer);
      if (this.isHasScrollProgressBar) {
        this.scrollProgressBar_dom.classList.add('hide');
      }

      this.pjaxProgressBar_dom.style.width = '0';
      this.pjaxProgressIcon_dom.classList.add('show');

      let width = 1;
      const maxWidth = 99;

      this.pjaxProgressBar_dom.classList.add('show');
      this.pjaxProgressBar_dom.style.width = width + '%';

      this.pjaxProgressBarTimer = setInterval(() => {
        width += 5;
        if (width > maxWidth) width = maxWidth;
        this.pjaxProgressBar_dom.style.width = width + '%';
      }, 100);
    },

    // loading progress bar end
    pjaxProgressBarEnd() {
      this.pjaxProgressBarTimer && clearInterval(this.pjaxProgressBarTimer);
      this.pjaxProgressBar_dom.style.width = '100%';

      const temp_1 = setTimeout(() => {
        this.pjaxProgressBar_dom.classList.remove('show');
        this.pjaxProgressIcon_dom.classList.remove('show');

        if (this.isHasScrollProgressBar) {
          this.scrollProgressBar_dom.classList.remove('hide');
        }

        const temp_2 = setTimeout(() => {
          this.pjaxProgressBar_dom.style.width = '0';
          clearTimeout(temp_1), clearTimeout(temp_2);
        }, 200);

      }, 200);
    }
  }

  // init scroll
  KEEP.utils.registerWindowScroll();

  // toggle show tools list
  KEEP.utils.toggleShowToolsList();

  // global font adjust
  KEEP.utils.globalFontAdjust();

  // adjust content area width
  KEEP.utils.contentAreaWidthAdjust();

  // go comment
  KEEP.utils.goComment();

  // init page height handle
  KEEP.utils.initPageHeightHandle();

  // init first screen height
  KEEP.utils.initFirstScreenHeight();

  // big image viewer handle
  KEEP.utils.imageViewer();

  // set how long age in home article block
  KEEP.utils.setHowLongAgoInHome();

}