/* ═══════════════════════════════════════════════════
   SORV.SPACE — mobile.js  (v2 — fixed)
   Fixes:
     1. Admin button in bottom nav reads from DOM
        (checks if #tab-admin exists in the page,
         which PHP only renders when $isAdmin = true)
     2. Lightbox slide navigation — tracks an index
        against the live card list, prev/next/swipe
        all work correctly
═══════════════════════════════════════════════════ */

(function () {
  'use strict';

  const isMobile      = () => window.innerWidth <= 768;
  const isTouchDevice = () => window.matchMedia('(pointer: coarse)').matches;

  /* ─────────────────────────────────────────────────
     HELPER — detect admin from DOM.
     PHP only renders #tab-admin when $isAdmin = true,
     so its presence in the DOM is the reliable check.
  ───────────────────────────────────────────────── */
  const isAdminPage = () => !!document.getElementById('tab-admin');

  /* ═══════════════════════════════════════════════
     1. BOTTOM NAVIGATION
     Admin tab is appended only when #tab-admin
     exists in the PHP-rendered page.
  ═══════════════════════════════════════════════ */
  function injectBottomNav() {
    const adminTab = isAdminPage() ? `
      <li>
        <button class="bnav-btn" data-tab="admin" aria-label="Admin">
          <svg viewBox="0 0 24 24"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>
          <span>Admin</span>
          <span class="bnav-dot"></span>
        </button>
      </li>` : '';

    const nav = document.createElement('nav');
    nav.id = 'bottom-nav';
    nav.setAttribute('aria-label', 'Main navigation');
    nav.innerHTML = `
      <ul>
        <li>
          <button class="bnav-btn active" data-tab="home" aria-label="Home">
            <svg viewBox="0 0 24 24"><path d="M3 9.5L12 3l9 6.5V20a1 1 0 01-1 1H5a1 1 0 01-1-1V9.5z"/><path d="M9 21V12h6v9"/></svg>
            <span>Home</span>
            <span class="bnav-dot"></span>
          </button>
        </li>
        <li>
          <button class="bnav-btn" data-tab="photos" aria-label="Photos">
            <svg viewBox="0 0 24 24"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="M21 15l-5-5L5 21"/></svg>
            <span>Photos</span>
            <span class="bnav-dot"></span>
          </button>
        </li>
        <li>
          <button class="bnav-btn" data-tab="reels" aria-label="Reels">
            <svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M10 8l6 4-6 4V8z"/></svg>
            <span>Reels</span>
            <span class="bnav-dot"></span>
          </button>
        </li>
        <li>
          <button class="bnav-btn" data-tab="about" aria-label="About">
            <svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 3.6-7 8-7s8 3 8 7"/></svg>
            <span>About</span>
            <span class="bnav-dot"></span>
          </button>
        </li>
        ${adminTab}
      </ul>
    `;
    document.body.appendChild(nav);

    function setActive(tab) {
      nav.querySelectorAll('.bnav-btn').forEach(b =>
        b.classList.toggle('active', b.dataset.tab === tab)
      );
    }

    nav.addEventListener('click', e => {
      const btn = e.target.closest('.bnav-btn');
      if (!btn) return;
      const tab = btn.dataset.tab;
      setActive(tab);
      // Delegate to existing top-nav link so main.js goTab() fires
      const topLink = document.querySelector(`.nav-link[data-tab="${tab}"]`);
      if (topLink) {
        topLink.click();
      } else {
        // Admin tab has no top-nav link — switch pane directly
        document.querySelectorAll('.tab-pane').forEach(p => p.classList.remove('active'));
        document.getElementById('tab-' + tab)?.classList.add('active');
      }
      if (navigator.vibrate) navigator.vibrate(8);
      window.scrollTo({ top: 0, behavior: 'smooth' });
    });

    // Keep bottom nav in sync when top nav links are clicked
    document.addEventListener('click', e => {
      const link = e.target.closest('[data-tab]');
      if (!link || link.closest('#bottom-nav')) return;
      setActive(link.dataset.tab);
    });

    return nav;
  }

  /* ═══════════════════════════════════════════════
     2. FAB UPLOAD — admin only
  ═══════════════════════════════════════════════ */
  function injectFAB() {
    if (!isAdminPage()) return;

    const fab = document.createElement('button');
    fab.id = 'fab-upload';
    fab.setAttribute('aria-label', 'Upload media');
    fab.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"><path d="M12 5v14M5 12l7-7 7 7"/></svg>`;
    fab.style.cssText = [
      'display:none',
      'position:fixed',
      'bottom:calc(72px + env(safe-area-inset-bottom,0px) + 1rem)',
      'right:1.2rem',
      'z-index:590',
      'width:52px',
      'height:52px',
      'border-radius:50%',
      'background:#c8a86b',
      'color:#070605',
      'border:none',
      'box-shadow:0 6px 24px rgba(200,168,107,.38)',
      'align-items:center',
      'justify-content:center',
      'cursor:pointer',
    ].join(';');
    document.body.appendChild(fab);

    document.addEventListener('click', e => {
      const link = e.target.closest('[data-tab]');
      if (!link) return;
      fab.style.display = link.dataset.tab === 'admin' ? 'flex' : 'none';
    });

    fab.addEventListener('click', () => {
      document.getElementById('file-input')?.click();
      if (navigator.vibrate) navigator.vibrate(12);
    });
  }

  /* ═══════════════════════════════════════════════
     3. LIGHTBOX GALLERY — index tracking + slides

     gallery[]    — array of item objects built from
                    whichever grid the tapped card is in.
     currentIndex — which item is currently open.

     Cards get their item data stamped as data-* attrs
     via window.SORV_registerItem() (called from main.js)
     or via the MutationObserver fallback below.
  ═══════════════════════════════════════════════ */
  let gallery      = [];
  let currentIndex = -1;

  /* Called from main.js after creating each card:
       window.SORV_registerItem(card, item);
     This keeps full item metadata on the element.   */
  window.SORV_registerItem = (card, item) => {
    if (!card || !item) return;
    card.dataset.mediaUrl  = item.media_url      || '';
    card.dataset.thumb     = item.thumbnail_url  || item.media_url || '';
    card.dataset.title     = item.title          || '';
    card.dataset.date      = item.date           || '';
    card.dataset.mediaType = item.media_type     || 'photo';
    card.dataset.id        = String(item.id      || '');
    card.dataset.likes     = String(item.likes   || 0);
  };

  /* MutationObserver fallback — stamps data-lb-index
     on every card as grids are dynamically populated. */
  function observeGrids() {
    const mo = new MutationObserver(() => {
      document.querySelectorAll('[id$="-grid"]').forEach(grid => {
        grid.querySelectorAll('.m-card').forEach((card, i) => {
          card.dataset.lbIndex = i;
          // Fallback: use img src if main.js didn't call SORV_registerItem
          if (!card.dataset.mediaUrl) {
            const img = card.querySelector('img');
            if (img) { card.dataset.mediaUrl = img.src; card.dataset.thumb = img.src; }
          }
        });
      });
    });
    mo.observe(document.getElementById('main-content') || document.body, {
      childList: true, subtree: true,
    });
  }

  /* Intercept card clicks (capture phase = before main.js).
     Builds the gallery from the clicked card's parent grid,
     then opens lightbox at the correct index.             */
  function patchCardClicks() {
    document.addEventListener('click', e => {
      const card = e.target.closest('.m-card');
      if (!card) return;

      const grid = card.closest('[id$="-grid"]');
      if (!grid) return;

      // Build gallery from all cards currently in this grid
      const cards = Array.from(grid.querySelectorAll('.m-card'));
      gallery = cards.map(c => ({
        media_url:  c.dataset.mediaUrl  || c.querySelector('img')?.src || '',
        thumbnail:  c.dataset.thumb     || c.querySelector('img')?.src || '',
        title:      c.dataset.title     || '',
        date:       c.dataset.date      || '',
        media_type: c.dataset.mediaType || 'photo',
        id:         c.dataset.id        || '',
        likes:      c.dataset.likes     || '0',
      }));

      const idx = cards.indexOf(card);
      openLbAt(idx);

      // Stop main.js's own openLb from double-firing
      e.stopImmediatePropagation();
    }, true /* capture */);
  }

  /* Open lightbox at index */
  function openLbAt(index) {
    if (!gallery.length) return;
    index = Math.max(0, Math.min(index, gallery.length - 1));
    currentIndex = index;
    const item = gallery[index];

    const lb    = document.getElementById('lightbox');
    const stage = document.getElementById('lb-stage');
    if (!lb || !stage) return;

    // Render media with slide-in animation
    stage.innerHTML = (item.media_type === 'reel' || item.media_type === 'video')
      ? `<video src="${item.media_url}" autoplay controls playsinline style="max-width:100%;max-height:68svh;"></video>`
      : `<img src="${item.media_url || item.thumbnail}" alt="${item.title}" style="max-width:100%;max-height:68svh;object-fit:contain;">`;

    // Footer info
    const get = id => document.getElementById(id);
    if (get('lb-title')) get('lb-title').textContent = item.title || '';
    if (get('lb-date'))  get('lb-date').textContent  = item.date  || '';
    if (get('lb-likes')) get('lb-likes').textContent = item.likes || '0';
    if (get('lb-download')) get('lb-download').href  = item.media_url || item.thumbnail || '#';

    updateSlideButtons();
    updateCounterPill();

    lb.hidden = false;
    lb.setAttribute('aria-label', `Image ${index + 1} of ${gallery.length}${item.title ? ': ' + item.title : ''}`);
  }

  function updateSlideButtons() {
    const prev = document.getElementById('lb-prev');
    const next = document.getElementById('lb-next');
    if (!prev || !next) return;
    const atStart = currentIndex <= 0;
    const atEnd   = currentIndex >= gallery.length - 1;
    prev.style.opacity       = atStart ? '0.2' : '1';
    next.style.opacity       = atEnd   ? '0.2' : '1';
    prev.style.pointerEvents = atStart ? 'none' : '';
    next.style.pointerEvents = atEnd   ? 'none' : '';
  }

  function updateCounterPill() {
    let pill = document.getElementById('lb-counter');
    if (!pill) {
      pill = document.createElement('div');
      pill.id = 'lb-counter';
      pill.style.cssText = [
        'position:fixed',
        'top:1.1rem',
        'right:4.5rem',
        'z-index:3',
        'background:rgba(7,6,5,.65)',
        'border:.5px solid rgba(200,168,107,.2)',
        'color:#9b9186',
        'font-family:"DM Sans",sans-serif',
        'font-size:.6rem',
        'letter-spacing:.15em',
        'padding:.3rem .7rem',
        'backdrop-filter:blur(6px)',
        'pointer-events:none',
      ].join(';');
      document.getElementById('lightbox')?.appendChild(pill);
    }
    pill.textContent = gallery.length > 1 ? `${currentIndex + 1} / ${gallery.length}` : '';
  }

  /* Wire prev / next buttons and keyboard */
  function wireSlideButtons() {
    document.getElementById('lb-prev')?.addEventListener('click', () => {
      if (currentIndex > 0) openLbAt(currentIndex - 1);
    });
    document.getElementById('lb-next')?.addEventListener('click', () => {
      if (currentIndex < gallery.length - 1) openLbAt(currentIndex + 1);
    });

    // Keyboard (desktop)
    document.addEventListener('keydown', e => {
      const lb = document.getElementById('lightbox');
      if (!lb || lb.hidden) return;
      if (e.key === 'ArrowLeft'  && currentIndex > 0)                  openLbAt(currentIndex - 1);
      if (e.key === 'ArrowRight' && currentIndex < gallery.length - 1) openLbAt(currentIndex + 1);
      if (e.key === 'Escape') closeLightbox();
    });

    // Close button
    document.getElementById('lb-x')?.addEventListener('click', closeLightbox);

    // Click-outside on the dark bg
    document.getElementById('lb-bg')?.addEventListener('click', closeLightbox);
  }

  function closeLightbox() {
    const lb    = document.getElementById('lightbox');
    const stage = document.getElementById('lb-stage');
    if (lb)    lb.hidden = true;
    if (stage) stage.innerHTML = '';
    currentIndex = -1;
    const pill = document.getElementById('lb-counter');
    if (pill) pill.textContent = '';
  }

  /* ═══════════════════════════════════════════════
     4. TOUCH SWIPE — lightbox close + slide
  ═══════════════════════════════════════════════ */
  function setupLightboxSwipe() {
    const lb = document.getElementById('lightbox');
    if (!lb) return;

    let sx = 0, sy = 0, active = false;

    lb.addEventListener('touchstart', e => {
      if (e.touches.length !== 1) return; // ignore pinch
      sx = e.touches[0].clientX;
      sy = e.touches[0].clientY;
      active = true;
    }, { passive: true });

    lb.addEventListener('touchend', e => {
      if (!active || e.touches.length > 0) return;
      active = false;
      const dx = e.changedTouches[0].clientX - sx;
      const dy = e.changedTouches[0].clientY - sy;
      const adx = Math.abs(dx), ady = Math.abs(dy);

      if (ady > 75 && ady > adx) { closeLightbox(); return; } // swipe down → close
      if (adx > 55 && adx > ady) {
        if (dx < 0 && currentIndex < gallery.length - 1) openLbAt(currentIndex + 1); // left → next
        if (dx > 0 && currentIndex > 0)                  openLbAt(currentIndex - 1); // right → prev
      }
    }, { passive: true });

    setupPinchZoom(document.getElementById('lb-stage'));
  }

  /* ═══════════════════════════════════════════════
     5. PINCH-ZOOM
  ═══════════════════════════════════════════════ */
  function setupPinchZoom(container) {
    if (!container) return;
    let initDist = 0, curScale = 1, baseScale = 1;

    container.addEventListener('touchstart', e => {
      if (e.touches.length === 2) {
        initDist  = Math.hypot(e.touches[1].clientX - e.touches[0].clientX, e.touches[1].clientY - e.touches[0].clientY);
        baseScale = curScale;
      }
    }, { passive: true });

    container.addEventListener('touchmove', e => {
      if (e.touches.length !== 2) return;
      const d = Math.hypot(e.touches[1].clientX - e.touches[0].clientX, e.touches[1].clientY - e.touches[0].clientY);
      curScale = Math.min(4, Math.max(1, baseScale * (d / initDist)));
      const el = container.querySelector('img,video');
      if (el) { el.style.transform = `scale(${curScale}) translate3d(0,0,0)`; el.style.transition = 'none'; }
    }, { passive: true });

    container.addEventListener('touchend', e => {
      if (e.touches.length < 2 && curScale < 1.1) {
        curScale = 1;
        const el = container.querySelector('img,video');
        if (el) { el.style.transform = ''; el.style.transition = ''; }
      }
    }, { passive: true });

    // Double-tap zoom
    let lastTap = 0;
    container.addEventListener('touchend', e => {
      const now = Date.now();
      if (now - lastTap < 280 && e.touches.length === 0) {
        const el = container.querySelector('img,video');
        if (!el) return;
        curScale = curScale > 1 ? 1 : 2.5;
        el.style.transform = curScale > 1 ? 'scale(2.5) translate3d(0,0,0)' : '';
        el.style.transition = 'transform .3s ease';
      }
      lastTap = now;
    }, { passive: true });
  }

  /* ═══════════════════════════════════════════════
     6. PULL-TO-REFRESH
  ═══════════════════════════════════════════════ */
  function setupPullToRefresh() {
    const el = document.createElement('div');
    el.id = 'ptr-indicator';
    el.innerHTML = `<svg viewBox="0 0 24 24" fill="none" stroke="#c8a86b" stroke-width="2" stroke-linecap="round"><path d="M4 4v6h6M20 20v-6h-6"/><path d="M20.49 9A9 9 0 005.64 5.64M3.51 15a9 9 0 0014.85 3.36"/></svg>`;
    document.body.appendChild(el);

    let sy = 0, pulling = false;
    document.addEventListener('touchstart', e => { if (window.scrollY === 0) { sy = e.touches[0].clientY; pulling = true; } }, { passive: true });
    document.addEventListener('touchmove',  e => { if (pulling && e.touches[0].clientY - sy > 30) el.classList.add('visible'); }, { passive: true });
    document.addEventListener('touchend',   e => {
      if (!pulling) return; pulling = false;
      const dy = e.changedTouches[0].clientY - sy;
      el.classList.remove('visible');
      if (dy > 90) { if (navigator.vibrate) navigator.vibrate([15,30,15]); window.location.reload(); }
    }, { passive: true });
  }

  /* ═══════════════════════════════════════════════
     7. REELS HORIZONTAL SCROLL SNAP
  ═══════════════════════════════════════════════ */
  function setupReelsScroll() {
    const grid = document.getElementById('reels-grid');
    if (!grid || !isMobile()) return;
    grid.setAttribute('data-mobile-scroll', 'true');
  }

  /* ═══════════════════════════════════════════════
     8. TAP FEEDBACK
  ═══════════════════════════════════════════════ */
  function setupTapFeedback() {
    document.addEventListener('touchstart', e => {
      const card = e.target.closest('.m-card,.r-card,.btn-primary,.btn-outline-hero,.btn-outline-gold,.f-btn,.bnav-btn');
      if (!card) return;
      card.classList.add('tap-flash');
      setTimeout(() => card.classList.remove('tap-flash'), 150);
    }, { passive: true });
  }

  /* ═══════════════════════════════════════════════
     9. LAZY IMAGE LOADING
  ═══════════════════════════════════════════════ */
  function setupLazyImages() {
    if (!('IntersectionObserver' in window)) return;
    const io = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (!entry.isIntersecting) return;
        const img = entry.target;
        if (img.dataset.src) { img.src = img.dataset.src; img.removeAttribute('data-src'); img.classList.remove('m-skel'); }
        io.unobserve(img);
      });
    }, { rootMargin: '150px' });
    const observe = () => document.querySelectorAll('img[data-src]').forEach(i => io.observe(i));
    observe();
    new MutationObserver(observe).observe(document.getElementById('main-content') || document.body, { childList: true, subtree: true });
  }

  /* ═══════════════════════════════════════════════
     10. HERO COUNTER ANIMATION
  ═══════════════════════════════════════════════ */
  function animateCounters() {
    const counters = document.querySelectorAll('.stat-n[data-target]');
    if (!counters.length) return;
    const io = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (!entry.isIntersecting) return;
        const el = entry.target, target = parseInt(el.dataset.target, 10) || 0;
        const step = target / (1400 / 16);
        let cur = 0;
        const tick = () => { cur = Math.min(cur + step, target); el.textContent = Math.floor(cur); if (cur < target) requestAnimationFrame(tick); };
        tick(); io.unobserve(el);
      });
    });
    counters.forEach(c => io.observe(c));
  }

  /* ═══════════════════════════════════════════════
     11. PREVENT DOUBLE-TAP ZOOM
  ═══════════════════════════════════════════════ */
  function preventDoubleTapZoom() {
    const sel = 'button,a,.m-card,.r-card,.f-btn,.bnav-btn';
    document.querySelectorAll(sel).forEach(el => { el.style.touchAction = 'manipulation'; });
    document.addEventListener('click', e => { const el = e.target.closest(sel); if (el) el.style.touchAction = 'manipulation'; });
  }

  if ('scrollRestoration' in history) history.scrollRestoration = 'manual';

  /* ═══════════════════════════════════════════════
     INIT
  ═══════════════════════════════════════════════ */
  function init() {
    // These run for all visitors (desktop keyboard arrows also benefit)
    wireSlideButtons();
    patchCardClicks();
    observeGrids();
    setupLazyImages();
    animateCounters();

    if (isTouchDevice() || isMobile()) {
      injectBottomNav();
      injectFAB();
      setupLightboxSwipe();
      setupPullToRefresh();
      setupTapFeedback();
      preventDoubleTapZoom();
      document.addEventListener('click', e => {
        if (e.target.closest('[data-tab="reels"]')) setTimeout(setupReelsScroll, 400);
      });
    }
  }

  document.readyState === 'loading'
    ? document.addEventListener('DOMContentLoaded', init)
    : init();

})();