/* global Vue, homepageBsaAds */
(() => {
  const isInViewport = (element, offset) => {
    const rect = element.getBoundingClientRect();
    return (
      (rect.top >= (offset - 500) && rect.top <= (window.innerHeight || document.documentElement.clientHeight))
      || (rect.bottom >= (offset - 500) && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight))
    );
  };

  const throttle = (fn, delay) => {
    let lastCalled = 0;
    return (...args) => {
      const now = new Date().getTime();
      if (now - lastCalled < delay) {
        return false;
      }
      lastCalled = now;
      return fn(...args);
    };
  };

  const popularLinksApp = {
    components: {
      submittedLinkCardComponent: window.submittedLinkCardComponent,
      namespacesToFollowComponent: window.namespacesToFollowComponent,
    },
    setup(props, context) {
      const PAGE_SIZE = 20;

      const currentPage = Vue.ref(0);

      const loadedSubmittedLinks = Vue.ref([]);
      const loadedSubmittedLinkVideos = [];
      const loadedVideosInViewPort = Vue.ref([]);

      const statusLoading = Vue.ref(true);
      const statusLoadingMore = Vue.ref(false);
      const statusItemCondensed = Vue.ref(false);
      const statusPopularRangeMenuExpanded = Vue.ref(false);

      const statusHasStories = Vue.computed(() => loadedSubmittedLinks.value.length > 0);

      const totalSubmittedLinks = Vue.ref(0);
      const fromIndex = Vue.computed(() => (currentPage.value === 0 ? 0 : (PAGE_SIZE * currentPage.value) + 1));

      const RANGE_FILTER = window.rangeFilter;

      const checkVideosInViewport = () => {
        const primaryNavigation = document.querySelector('.primary-navigation');
        const primaryNavigationHeight = primaryNavigation ? primaryNavigation.offsetHeight : 0;

        loadedSubmittedLinkVideos.forEach((video) => {
          const el = document.querySelector(`.links-results article[data-id="${video.submittedLinkId}"]`);

          if (el) {
            const iframe = el.querySelector('iframe');

            if (iframe && (iframe.classList.contains('vimeo-media') || iframe.classList.contains('youtube-media'))) {
              if (isInViewport(el, primaryNavigationHeight)) {
                loadedVideosInViewPort.value.push(video.submittedLinkId);
                if (iframe && iframe.getAttribute('src') !== `/media/${video.mediaId}`) {
                  iframe.setAttribute('src', `/media/${video.mediaId}`);
                }
              } else {
                el.style.border = '';
                loadedVideosInViewPort.value.splice(loadedVideosInViewPort.value.indexOf(video.submittedLinkId), 1);
                if (iframe && iframe.getAttribute('src') !== '') {
                  iframe.setAttribute('src', '');
                }
              }
            }
          }
        });
      };

      const fetchSubmittedLinks = (() => {
        fetch(`/popular/render?from=${fromIndex.value}&size=${PAGE_SIZE}&condensed=${statusItemCondensed.value}&range=${RANGE_FILTER}`)
          .then((resp) => resp.json())
          .then((results) => {
            if (results && results.status === 200) {
              if (results.items && results.items.length > 0) {
                results.items.forEach((item) => {
                  loadedSubmittedLinks.value.push(item);

                  if (item.mediaObject) {
                    loadedSubmittedLinkVideos.push({
                      submittedLinkId: item.submittedLinkId,
                      mediaId: item.mediaObject._id,
                    });
                  }
                });

                Vue.nextTick(() => {
                  checkVideosInViewport();
                });

                currentPage.value += 1;
              }

              totalSubmittedLinks.value = results.total ? results.total : 0;
            }

            statusLoading.value = false;
            statusLoadingMore.value = false;

            Vue.nextTick(() => {
              window.tiktokInit();
              window.twitterInit();
            });
          });
      });

      Vue.onMounted(() => {
        statusItemCondensed.value = localStorage.getItem('items:condensed') ? localStorage.getItem('items:condensed') === 'true' : false;

        fetchSubmittedLinks();

        window.addEventListener('scroll', throttle((event) => {
          const scrollPosition = window.innerHeight + window.scrollY;
          const scrollHeight = document.body.offsetHeight;

          checkVideosInViewport();

          if (fromIndex.value < totalSubmittedLinks.value && loadedSubmittedLinks.value.length > 0) {
            if (scrollPosition + 1000 > scrollHeight && !statusLoadingMore.value) {
              statusLoadingMore.value = true;

              fetchSubmittedLinks();
            }
          }
        }, 5));
      });

      const setDefaultValues = () => {
        loadedSubmittedLinks.value.length = 0;
        statusLoading.value = true;
        statusLoadingMore.value = false;
        currentPage.value = 0;
        statusPopularRangeMenuExpanded.value = false;
      };

      const handleToggleCondensedView = (e) => {
        statusItemCondensed.value = !statusItemCondensed.value;
        setDefaultValues();

        localStorage.setItem('items:condensed', statusItemCondensed.value);
        // add GA4 items condensed toggle event
        if (window.dataLayer) {
          window.dataLayer.push({
            event: 'ga4',
            event_name: 'items_condensed_toggle',
            username: window.digg.user.username,
            value: statusItemCondensed.value,
          });
        }
        fetchSubmittedLinks();

        e.preventDefault();
      };

      const handlePopularRangeMenuTrigger = () => {
        statusPopularRangeMenuExpanded.value = !statusPopularRangeMenuExpanded.value;
      };

      const handleOpenSigninModal = () => {
        window.dispatchEvent(new CustomEvent('signin-modal:open', { detail: { returnTo: '/for-you' } }));
      };

      return {
        statusLoading,
        statusLoadingMore,
        statusHasStories,
        statusItemCondensed,
        statusPopularRangeMenuExpanded,
        loadedSubmittedLinks,
        totalSubmittedLinks,
        RANGE_FILTER,
        PAGE_SIZE,
        bsaAdZones: homepageBsaAds.zones,
        handleToggleCondensedView,
        handlePopularRangeMenuTrigger,
        handleOpenSigninModal,
      };
    },
  };

  window.linksApp = Vue.createApp(popularLinksApp);
  window.linksApp.config.compilerOptions.isCustomElement = (tag) => tag.includes('digg-social-share');
  window.linksApp.mount('.links-wrapper');
})();
