<?php
/*
 * Template Name: Journal
 *
 * @package far_loop
 */
get_header();

// Prepara datos para AJAX
$ajax_url = admin_url('admin-ajax.php');
$ajax_nonce = wp_create_nonce('journal_load_posts');
$per_page = 36;
?>





<!-- Contenedor grid -->
<div class="u_pt-3 u_pt-md-6 archive-grid-container">
  <div class="l_container u_mv-5">

    <h3 class="section-heading delta"><span class="u_text-underline"><?php the_title(); ?></span></h3>

    <div class="archive-grid" id="journalGrid"></div>
    <div id="load-more-trigger" style="height: 48px;"></div>
  </div>
</div>






<script>
(function(){
  const AJAX_URL   = <?php echo json_encode( admin_url('admin-ajax.php') ); ?>;
  const AJAX_NONCE = <?php echo json_encode( wp_create_nonce('journal_load_posts') ); ?>;
  const PER_PAGE   = 36;

  const GRID_SEL   = '.archive-grid';
  const TRIGGER_ID = 'load-more-trigger';

  const grid    = document.querySelector(GRID_SEL);
  const trigger = document.getElementById(TRIGGER_ID);

  if (!grid) return;

  let page = 1;
  let loading = false;
  let done = false;

  // Para no disparar infinitamente en cadena
  const CHAIN_FILL_THRESHOLD = 1200; // px por debajo del viewport
  const SCROLL_NEAR_END      = 1600; // px para precargar
  const SCROLL_STEP          = 200;  // cada 200px de scroll pedimos más
  let lastScrollTriggerY = 0;
  let ticking = false;

  function remainingToEnd(){
    const docH = Math.max(
      document.body.scrollHeight, document.documentElement.scrollHeight,
      document.body.offsetHeight, document.documentElement.offsetHeight,
      document.body.clientHeight, document.documentElement.clientHeight
    );
    const scY = window.scrollY || window.pageYOffset || 0;
    return docH - (scY + window.innerHeight);
  }

  function fetchPosts(){
    const params = new URLSearchParams({
      action      : 'load_journal_posts',
      _ajax_nonce : AJAX_NONCE,
      page        : String(page),
      ppp         : String(PER_PAGE)
    });
    return fetch(AJAX_URL + '?' + params.toString(), { credentials: 'same-origin' })
      .then(r => {
        if (!r.ok) throw new Error('Network error');
        return r.text();
      });
  }

  function appendHTML(html){
    const tmp = document.createElement('div');
    tmp.innerHTML = html;
    const items = Array.from(tmp.children);
    if (!items.length) return 0;
    grid.append(...items);
    return items.length;
  }

  function loadMore(chain=false){
    if (loading || done) return;
    loading = true;

    fetchPosts()
      .then(html => {
        const clean = (html || '').trim();
        if (!clean) {
          done = true;
          if (observer) observer.disconnect();
          return;
        }
        const added = appendHTML(clean);
        if (added > 0) page += 1;
      })
      .catch(err => {
        console.error('[Journal] AJAX error:', err);
      })
      .finally(() => {
        loading = false;
        // Si venimos en modo cadena, seguimos mientras falte contenido visible
        if (chain && !done && remainingToEnd() < CHAIN_FILL_THRESHOLD) {
          // micro cola para que el layout se asiente
          setTimeout(() => loadMore(true), 30);
        }
      });
  }

  // IntersectionObserver como red de seguridad
  const observer = trigger ? new IntersectionObserver((entries) => {
    if (entries[0].isIntersecting && !loading && !done) {
      loadMore(false);
    }
  }, { rootMargin: '1000px 0px' }) : null;

  if (observer && trigger) observer.observe(trigger);

  // Scroll: encadenamos cada 200px, y también si estamos cerca del final
  function onScroll(){
    if (ticking) return;
    ticking = true;
    requestAnimationFrame(() => {
      if (!done && !loading) {
        const scY = window.scrollY || window.pageYOffset || 0;

        // cada 200px de avance, dispara
        if (scY - lastScrollTriggerY >= SCROLL_STEP) {
          lastScrollTriggerY = scY;
          loadMore(false);
        }

        // si ya estamos cerca del final, asegúrate de pedir más
        if (remainingToEnd() < SCROLL_NEAR_END) {
          loadMore(false);
        }
      }
      ticking = false;
    });
  }
  window.addEventListener('scroll', onScroll, { passive: true });

  // Resize: si el viewport crece y nos quedamos cortos, rellena en cadena
  window.addEventListener('resize', () => {
    if (!done && !loading && remainingToEnd() < CHAIN_FILL_THRESHOLD) {
      loadMore(true);
    }
  }, { passive: true });

  // Primera carga + rellenar hasta que sobrepase el viewport
  document.addEventListener('DOMContentLoaded', () => {
    loadMore(true);
  });
})();
</script>

<?php get_footer(); ?>