import './style.css';

/**
 * Adds a lightweight progressive "Load More" experience without introducing
 * AJAX complexity in the first Post Grid release cycle.
 */
const initPostGrid = (wrap) => {
  if (!wrap || wrap.dataset.pagination === 'none') {
    return;
  }

  const cards = Array.from(wrap.querySelectorAll('.calio-post-grid-card'));
  const button = wrap.querySelector('.calio-post-grid-load-more');
  const pagination = wrap.querySelector('.calio-post-grid-pagination');
  const status = wrap.querySelector('.calio-post-grid-status');
  const mode = wrap.dataset.pagination || 'none';
  const initialItems = Number.parseInt(wrap.dataset.initialItems || '6', 10);
  const pageSize = Number.parseInt(wrap.dataset.pageSize || '6', 10);
  const loadMoreStep = Number.parseInt(wrap.dataset.loadMoreStep || '3', 10);
  const totalItems = Number.parseInt(wrap.dataset.totalItems || String(cards.length), 10);
  const showingTemplate =
    status?.dataset.showingTemplate || 'Showing {visible} of {total} posts';

  if (!status || cards.length === 0) {
    return;
  }

  let visibleItems = initialItems;
  let currentPage = 1;
  const totalPages = Math.max(1, Math.ceil(totalItems / Math.max(1, pageSize)));

  const updateStatus = (visibleCount) => {
    status.textContent =
      visibleCount >= totalItems && mode === 'load_more'
        ? status.dataset.allLoadedText || ''
        : showingTemplate
            .replace('{visible}', String(Math.min(visibleCount, totalItems)))
            .replace('{total}', String(totalItems));
  };

  const setPage = (page) => {
    currentPage = Math.min(Math.max(page, 1), totalPages);
    const start = (currentPage - 1) * pageSize;
    const end = start + pageSize;

    cards.forEach((card, index) => {
      card.hidden = index < start || index >= end;
    });

    updateStatus(Math.min(end, totalItems));
    renderPagination();
  };

  const renderPagination = () => {
    if (!pagination) {
      return;
    }

    const prevText = pagination.dataset.prevText || 'Previous';
    const nextText = pagination.dataset.nextText || 'Next';
    pagination.replaceChildren();

    const prevButton = document.createElement('button');
    prevButton.className = 'calio-post-grid-page-nav';
    prevButton.type = 'button';
    prevButton.dataset.pageNav = 'prev';
    prevButton.disabled = currentPage === 1;
    prevButton.textContent = prevText;
    pagination.appendChild(prevButton);

    for (let page = 1; page <= totalPages; page += 1) {
      const pageButton = document.createElement('button');
      pageButton.className = `calio-post-grid-page-number${page === currentPage ? ' is-current' : ''}`;
      pageButton.type = 'button';
      pageButton.dataset.page = String(page);
      pageButton.setAttribute('aria-current', page === currentPage ? 'page' : 'false');
      pageButton.textContent = String(page);
      pagination.appendChild(pageButton);
    }

    const nextButton = document.createElement('button');
    nextButton.className = 'calio-post-grid-page-nav';
    nextButton.type = 'button';
    nextButton.dataset.pageNav = 'next';
    nextButton.disabled = currentPage === totalPages;
    nextButton.textContent = nextText;
    pagination.appendChild(nextButton);
  };

  const updateState = () => {
    cards.forEach((card, index) => {
      card.hidden = index >= visibleItems;
    });

    updateStatus(Math.min(visibleItems, totalItems));

    if (button && visibleItems >= totalItems) {
      button.hidden = true;
    }
  };

  if (mode === 'load_more') {
    if (!button || cards.length <= initialItems) {
      return;
    }

    button.addEventListener('click', () => {
      visibleItems = Math.min(visibleItems + loadMoreStep, totalItems);
      updateState();
    });

    updateState();
    return;
  }

  if (mode === 'numbers') {
    if (!pagination || cards.length <= pageSize) {
      return;
    }

    pagination.addEventListener('click', (event) => {
      const target = event.target;
      if (!(target instanceof HTMLButtonElement)) {
        return;
      }

      if (target.dataset.page) {
        setPage(Number.parseInt(target.dataset.page, 10));
      }

      if (target.dataset.pageNav === 'prev') {
        setPage(currentPage - 1);
      }

      if (target.dataset.pageNav === 'next') {
        setPage(currentPage + 1);
      }
    });

    setPage(1);
  }
};

const initPostGridScope = (scope = document) => {
  const root = scope instanceof HTMLElement || scope instanceof Document ? scope : document;
  root.querySelectorAll('.calio-post-grid-wrap').forEach(initPostGrid);
};

document.addEventListener('DOMContentLoaded', () => {
  initPostGridScope(document);
});

let calioPostGridHookBound = false;
const bindElementorPostGrid = () => {
  if (calioPostGridHookBound) {
    return true;
  }

  if (!window.elementorFrontend?.hooks) {
    return false;
  }

  window.elementorFrontend.hooks.addAction('frontend/element_ready/calio-post-grid.default', ($scope) => {
    const root = $scope?.[0] || document;
    initPostGridScope(root);
  });

  calioPostGridHookBound = true;
  return true;
};

window.addEventListener('elementor/frontend/init', bindElementorPostGrid);
if (!bindElementorPostGrid()) {
  let attempts = 0;
  const timer = window.setInterval(() => {
    attempts += 1;
    if (bindElementorPostGrid() || attempts >= 40) {
      window.clearInterval(timer);
    }
  }, 250);
}
