// gallery.el -- Gallery page: search/filter, sort, nav scroll, Supabase voting.
// Compiled with: elc --target=js --bundle --minify --obfuscate
//
// Required globals: window.NEURON_CFG.supabase_url, window.NEURON_CFG.supabase_anon_key
// Required CDN: supabase-js@2

fn main() -> Void {
    native_js("(function() {
  // Nav scroll effect
  var nav = document.getElementById('nav');
  if (nav) window.addEventListener('scroll', function() {
    nav.classList.toggle('scrolled', window.scrollY > 10);
  }, { passive: true });

  // Hamburger
  var btn  = document.getElementById('nav-hamburger');
  var menu = document.getElementById('nav-mobile');
  if (btn && menu) {
    function navClose() { menu.classList.remove('open'); btn.setAttribute('aria-expanded','false'); }
    function navOpen()  { menu.classList.add('open');    btn.setAttribute('aria-expanded','true');  }
    btn.addEventListener('click', function(e) { e.stopPropagation(); menu.classList.contains('open') ? navClose() : navOpen(); });
    menu.querySelectorAll('a').forEach(function(a) { a.addEventListener('click', navClose); });
    document.addEventListener('click', function(e) { if (!nav.contains(e.target)) navClose(); });
    document.addEventListener('keydown', function(e) { if (e.key === 'Escape') navClose(); });
    window.addEventListener('resize', function() { if (window.innerWidth > 1060) navClose(); });
  }

  // Dropdown
  var ddBtn = document.querySelector('.nav-dropdown-btn');
  var dd    = document.querySelector('.nav-dropdown');
  if (ddBtn && dd) {
    ddBtn.addEventListener('click', function(e) {
      e.stopPropagation();
      var isOpen = dd.classList.contains('open');
      dd.classList.toggle('open');
      ddBtn.setAttribute('aria-expanded', isOpen ? 'false' : 'true');
    });
    dd.querySelectorAll('.nav-dropdown-item').forEach(function(a) { a.addEventListener('click', function() { dd.classList.remove('open'); }); });
    document.addEventListener('click', function() { dd.classList.remove('open'); });
  }

  // Search
  var searchEl  = document.getElementById('gal-search');
  var grid      = document.getElementById('gallery-grid');
  var noResults = document.getElementById('no-results');

  function filterCards() {
    var q = (searchEl ? searchEl.value : '').toLowerCase().trim();
    var cards = grid ? grid.querySelectorAll('.gal-card') : [];
    var visible = 0;
    cards.forEach(function(c) {
      var match = !q || c.textContent.toLowerCase().indexOf(q) !== -1;
      c.classList.toggle('hidden', !match);
      if (match) visible++;
    });
    if (noResults) noResults.style.display = visible === 0 && q ? 'block' : 'none';
  }

  if (searchEl) searchEl.addEventListener('input', filterCards);

  // Sort
  window.setSort = function(mode, btn) {
    document.querySelectorAll('.sort-btn').forEach(function(b) { b.classList.remove('active'); });
    btn.classList.add('active');
    if (!grid) return;
    var cards = Array.from(grid.querySelectorAll('.gal-card'));
    cards.sort(function(a, b) {
      if (mode === 'top') {
        return parseInt(b.getAttribute('data-score') || '0') - parseInt(a.getAttribute('data-score') || '0');
      } else {
        return parseInt(b.getAttribute('data-ts') || '0') - parseInt(a.getAttribute('data-ts') || '0');
      }
    });
    cards.forEach(function(c) { grid.appendChild(c); });
  };

  // Voting via Supabase
  var cfg   = window.NEURON_CFG || {};
  var sbUrl = cfg.supabase_url;
  var sbKey = cfg.supabase_anon_key;
  if (!sbUrl || !sbKey) return;
  var sb    = window.supabase.createClient(sbUrl, sbKey);
  var token = null;
  var votes = {};

  function getCtrl(sid) {
    var found = null;
    document.querySelectorAll('.vote-controls').forEach(function(c) {
      if (c.getAttribute('data-share-id') === sid) found = c;
    });
    return found;
  }

  function applyState(ctrl, state) {
    var sid     = ctrl.getAttribute('data-share-id');
    votes[sid]  = state.user_vote || 'none';
    var scoreEl = ctrl.querySelector('.vote-score');
    if (scoreEl && state.score != null) scoreEl.textContent = state.score;
    var upBtn = ctrl.querySelector('.vote-btn.vote-up');
    var dnBtn = ctrl.querySelector('.vote-btn.vote-down');
    if (upBtn) { upBtn.disabled = false; upBtn.classList.toggle('is-active', state.user_vote === 'up'); }
    if (dnBtn) { dnBtn.disabled = false; dnBtn.classList.toggle('is-active', state.user_vote === 'down'); }
  }

  function loadVoteState(sid) {
    var url = '/api/vote-state/' + sid;
    if (token) url += '?access_token=' + encodeURIComponent(token);
    fetch(url).then(function(r) { return r.json(); }).then(function(d) {
      var ctrl = getCtrl(sid);
      if (ctrl) applyState(ctrl, d);
    }).catch(function() {});
  }

  function loadAll() {
    document.querySelectorAll('.vote-controls').forEach(function(ctrl) {
      var id = ctrl.getAttribute('data-share-id');
      if (id) loadVoteState(id);
    });
  }

  function castVote(sid, direction) {
    if (!token) { showSignIn(); return; }
    var ctrl = getCtrl(sid);
    var btns = ctrl ? ctrl.querySelectorAll('.vote-btn') : [];
    btns.forEach(function(b) { b.disabled = true; b.classList.add('is-loading'); });
    fetch('/api/vote', {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({access_token: token, id: sid, direction: direction})
    }).then(function(r) { return r.json(); }).then(function(d) {
      if (ctrl && d.ok) applyState(ctrl, d);
      btns.forEach(function(b) { b.disabled = false; b.classList.remove('is-loading'); });
    }).catch(function() {
      btns.forEach(function(b) { b.disabled = false; b.classList.remove('is-loading'); });
    });
  }

  document.querySelectorAll('.vote-controls').forEach(function(ctrl) {
    ctrl.querySelectorAll('.vote-btn').forEach(function(btn) {
      btn.addEventListener('click', function() {
        var sid = ctrl.getAttribute('data-share-id');
        if (!token) { showSignIn(); return; }
        var dir = btn.getAttribute('data-direction');
        var cur = votes[sid] || 'none';
        castVote(sid, cur === dir ? 'none' : dir);
      });
    });
  });

  var modal   = document.getElementById('signin-modal');
  var cancelEl = document.getElementById('signin-cancel');
  var sendEl   = document.getElementById('signin-send');
  var emailEl  = document.getElementById('signin-email');
  var msgEl    = document.getElementById('signin-msg');

  function showSignIn() { if (modal) modal.classList.add('open'); if (emailEl) emailEl.focus(); }

  if (cancelEl) cancelEl.addEventListener('click', function() { modal.classList.remove('open'); });
  if (modal)    modal.addEventListener('click', function(e) { if (e.target === modal) modal.classList.remove('open'); });
  if (sendEl)   sendEl.addEventListener('click', function() {
    var email = emailEl ? emailEl.value.trim() : '';
    if (!email) { if (msgEl) msgEl.textContent = 'Please enter your email.'; return; }
    sendEl.disabled = true;
    if (msgEl) msgEl.textContent = 'Sending...';
    sb.auth.signInWithOtp({ email: email, options: { emailRedirectTo: window.location.href } })
      .then(function(r) {
        sendEl.disabled = false;
        if (msgEl) msgEl.textContent = r.error
          ? (r.error.message || 'Error. Try again.')
          : 'Check your email for a sign-in link.';
      });
  });
  if (emailEl) emailEl.addEventListener('keydown', function(e) { if (e.key === 'Enter' && sendEl) sendEl.click(); });

  sb.auth.onAuthStateChange(function(event, session) {
    token = session ? session.access_token : null;
    if (token && modal) modal.classList.remove('open');
    loadAll();
  });

  sb.auth.getSession().then(function(r) {
    token = r.data && r.data.session ? r.data.session.access_token : null;
    loadAll();
  });
})()")
}
