/**
 * Ragreen - Ad slot rendering
 * Fetches and renders ads for a given placement. Custom ads (admin-uploaded
 * image + link) render immediately with no extra setup. Google AdSense ads
 * only actually show anything once a real, approved AdSense client ID is
 * configured in Admin > Settings - until then the slot quietly renders
 * nothing rather than an error, since an unapproved/missing client ID is
 * an expected state during setup, not a bug.
 */

let _adsenseScriptLoaded = false;

function loadAdsenseScript(clientId) {
  if (_adsenseScriptLoaded || !clientId) return;
  _adsenseScriptLoaded = true;
  const script = document.createElement('script');
  script.async = true;
  script.src = `https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${encodeURIComponent(clientId)}`;
  script.crossOrigin = 'anonymous';
  document.head.appendChild(script);
}

/**
 * Renders every active ad for a placement into $container, one after
 * another. Container is left empty (not hidden) if there are no ads
 * configured for that placement, so callers don't need special-case CSS.
 */
function renderAdSlot(placementKey, containerSelector) {
  const $container = $(containerSelector);
  if (!$container.length) return;

  $.get(`${API_BASE}/ads/list.php`, { placement_key: placementKey }).done((res) => {
    const ads = res.data.ads;
    if (!ads.length) {
      $container.empty();
      return;
    }

    $container.html(ads.map((ad, i) => {
      const wrapId = `ad-slot-${placementKey}-${i}-${Math.random().toString(36).slice(2, 8)}`;
      if (ad.ad_type === 'custom') {
        return `
          <div class="ad-slot-wrap" style="width:${ad.width}px; max-width:100%;">
            <div class="ad-slot-label">Advertisement</div>
            <a href="${escapeAttr(ad.custom_link_url)}" target="_blank" rel="noopener sponsored">
              <img src="${ad.custom_image_url}" alt="${escapeAttr(ad.custom_alt_text || 'Advertisement')}"
                   width="${ad.width}" height="${ad.height}" style="display:block; width:100%; height:auto; border-radius:8px;">
            </a>
          </div>
        `;
      }
      // Google AdSense unit
      return `
        <div class="ad-slot-wrap" style="width:${ad.width}px; max-width:100%;" id="${wrapId}">
          <div class="ad-slot-label">Advertisement${ad.is_test_mode ? ' (test mode)' : ''}</div>
          <ins class="adsbygoogle" style="display:inline-block; width:${ad.width}px; height:${ad.height}px;"
               data-ad-client="${escapeAttr(ad.adsense_client_id || '')}"
               data-ad-slot="${escapeAttr(ad.google_ad_slot || '')}"
               ${ad.is_test_mode ? 'data-adtest="on"' : ''}></ins>
        </div>
      `;
    }).join(''));

    // Kick off AdSense for any google-type slots just rendered.
    const googleAds = ads.filter(a => a.ad_type === 'google' && a.adsense_client_id);
    if (googleAds.length) {
      loadAdsenseScript(googleAds[0].adsense_client_id);
      setTimeout(() => {
        try {
          $container.find('ins.adsbygoogle').each(function () {
            (window.adsbygoogle = window.adsbygoogle || []).push({});
            watchForUnfilledAd(this);
          });
        } catch (e) { /* AdSense not ready/approved yet - fail silently, not the user's problem */ }
      }, 300);
    }
  }).fail(() => $container.empty());
}

/**
 * Google marks each <ins> with data-ad-status="filled"/"unfilled" once the
 * ad request resolves. Until an AdSense account is fully approved (or if
 * an ad blocker strips the request entirely), that resolution may never
 * come back "filled" - left alone, that leaves a labeled "Advertisement"
 * box with visibly nothing in it, which reads as broken rather than just
 * "no ad this time." This collapses the whole wrapper (label included)
 * once it's clear nothing is going to render - either Google explicitly
 * says so, or a few seconds pass with no resolution at all.
 */
function watchForUnfilledAd(insEl) {
  const $wrap = $(insEl).closest('.ad-slot-wrap');
  let settled = false;

  const checkStatus = () => {
    const status = insEl.getAttribute('data-ad-status');
    if (status === 'unfilled') {
      $wrap.hide();
      settled = true;
    } else if (status === 'filled') {
      settled = true;
    }
    return settled;
  };

  if (checkStatus()) return;

  const observer = new MutationObserver(() => checkStatus());
  observer.observe(insEl, { attributes: true, attributeFilter: ['data-ad-status'] });

  // Fallback for when Google's script never responds at all (ad blocker,
  // network issue, account not yet approved) - data-ad-status never gets
  // set in that case, so the observer alone would wait forever.
  setTimeout(() => {
    observer.disconnect();
    if (!settled) $wrap.hide();
  }, 4000);
}

function escapeAttr(str) {
  return String(str || '').replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
