<template>
  <div v-if="isEnabled" :class="['header-ad-banner', { sticky: finalSticky } ]">
    <div ref="adContainer" class="ad-container" />
  </div>
</template>

<script setup>
import { computed, nextTick, onMounted, ref } from 'vue';

const adContainer = ref(null);

// Provider selection via env: 'adsense' or 'propeller'
const provider = (import.meta.env.VITE_AD_PROVIDER || 'propeller').toLowerCase();

// AdSense config (kept for compatibility)
const adClient = import.meta.env.VITE_ADSENSE_CLIENT || '';
const adSlot = import.meta.env.VITE_ADSENSE_HEADER_SLOT || '';

// Propeller config: you can set the script URL and the slot id via env
// Defaults set to the in-page push tag you provided (can be overridden via env)
const propScriptUrl = import.meta.env.VITE_PROP_SCRIPT_URL || 'https://nap5k.com/tag.min.js';
const propSlotId = import.meta.env.VITE_PROP_SLOT || '11023637';

// Show only if the selected provider has config
const isEnabled = computed(() => {
  if (provider === 'adsense') return Boolean(adClient && adSlot);
  if (provider === 'propeller') return Boolean(propScriptUrl && propSlotId);
  return false;
});

// Small sticky header option (thin sticky header)
const sticky = (import.meta.env.VITE_HEADER_STICKY || 'true') === 'true';

// Debug bypass: allow forcing ad load with ?ads_debug=1
const debugForceLoad = typeof window !== 'undefined' && new URLSearchParams(window.location.search).get('ads_debug') === '1';

// Auto load flag (env) - set to 'true' to load ads on mount without waiting for interaction
const autoLoad = (import.meta.env.VITE_PROP_AUTOLOAD || 'true') === 'true';

// A/B test config
const abRatio = Number(import.meta.env.VITE_AB_RATIO || '50'); // percent for variant B

function getStoredVariant() {
  try {
    const v = localStorage.getItem('ads_ab_variant');
    if (v === 'A' || v === 'B') return v;
  } catch (e) {}
  return null;
}

function assignVariant() {
  const existing = getStoredVariant();
  if (existing) return existing;
  const r = Math.random() * 100;
  const variant = r < abRatio ? 'B' : 'A';
  try {
    localStorage.setItem('ads_ab_variant', variant);
  } catch (e) {}
  window.dispatchEvent(new CustomEvent('ads:ab-assigned', { detail: { variant } }));
  return variant;
}

const variant = getStoredVariant() || assignVariant();
// finalSticky follows the variant: A = static, B = sticky
const finalSticky = variant === 'B' ? true : variant === 'A' ? false : sticky;

function hasConsent() {
  try {
    return localStorage.getItem('ads_consent') === 'true';
  } catch (e) {
    return false;
  }
}

function listenForConsentEvent() {
  function onConsent() {
    loadAdIfNeeded();
    window.removeEventListener('ads:consent-granted', onConsent);
  }
  window.addEventListener('ads:consent-granted', onConsent);
}

function ensureScriptLoaded(src, attrName) {
  if (document.querySelector(`script[data-ad-loader="${attrName}"]`)) return Promise.resolve();
  return new Promise((resolve, reject) => {
    const s = document.createElement('script');
    s.async = true;
    s.src = src;
    s.dataset.adLoader = attrName;
    s.onload = () => resolve();
    s.onerror = (e) => reject(e);
    document.head.appendChild(s);
  });
}

async function renderPropeller() {
  if (!adContainer.value) return;
  try {
    // Insert Propeller in-page push tag exactly as provided by PropellerAds.
    // Avoid duplicate insertion if same script+zone already present.
    if (document.querySelector(`script[src="${propScriptUrl}"][data-zone="${propSlotId}"]`)) {
      return;
    }

    // create placeholder first and insert into ad container
    const placeholder = document.createElement('div');
    placeholder.className = 'propeller-ad-placeholder';
    adContainer.value.appendChild(placeholder);

    const s = document.createElement('script');
    s.dataset.zone = propSlotId;
    s.src = propScriptUrl;
    s.async = true;
    s.onload = () => {
      console.log('Propeller script loaded:', propScriptUrl, 'zone:', propSlotId);
    };
    s.onerror = (e) => {
      console.warn('Propeller script failed to load:', propScriptUrl, e);
      try { window.dispatchEvent(new CustomEvent('ads:load-failed', { detail: { provider: 'propeller', zone: propSlotId, error: String(e) } })); } catch {}
    };

    // Append the script directly into the placeholder so the provider injects into it
    placeholder.appendChild(s);

    // Observe the document for injected ad nodes and relocate them into our placeholder
    const observeAndRelocate = () => {
      const parent = document.body;
      try {
        const observer = new MutationObserver(mutations => {
          for (const m of mutations) {
            for (const node of Array.from(m.addedNodes)) {
              try {
                // Handle text nodes that may contain raw script/HTML
                if (node.nodeType === Node.TEXT_NODE) {
                  const txt = (node.nodeValue || '').trim();
                  if (txt.includes('<script') || txt.length > 500) {
                    // remove large/raw script text nodes to avoid visible JS
                    node.parentNode && node.parentNode.removeChild(node);
                  }
                  continue;
                }

                if (!(node instanceof HTMLElement)) continue;

                // If element contains script tags, extract and execute them safely
                const innerScripts = Array.from(node.querySelectorAll('script'));
                if (innerScripts.length) {
                  for (const sc of innerScripts) {
                    try {
                      if (sc.src) {
                        const s2 = document.createElement('script');
                        s2.src = sc.src;
                        s2.async = true;
                        document.head.appendChild(s2);
                      } else if (sc.textContent) {
                        const s2 = document.createElement('script');
                        s2.textContent = sc.textContent;
                        document.head.appendChild(s2);
                      }
                    } catch (e) {
                      console.warn('execute inner script failed', e);
                    }
                    // remove the inline script node from original element to avoid visible code
                    sc.parentNode && sc.parentNode.removeChild(sc);
                  }
                }

                // If the added node is a script element itself, execute safely via head insertion
                if (node.tagName === 'SCRIPT') {
                  const src = node.getAttribute('src');
                  if (src) {
                    const s2 = document.createElement('script');
                    s2.src = src;
                    s2.async = true;
                    s2.onload = () => console.log('relocated script loaded', src);
                    s2.onerror = (e) => console.warn('relocated script failed', src, e);
                    document.head.appendChild(s2);
                    node.parentNode && node.parentNode.removeChild(node);
                    continue;
                  } else if (node.textContent) {
                    const s2 = document.createElement('script');
                    s2.textContent = node.textContent;
                    document.head.appendChild(s2);
                    node.parentNode && node.parentNode.removeChild(node);
                    continue;
                  }
                }

                // Detect iframe ad nodes or nodes with nap5k indicators
                const iframe = node.tagName === 'IFRAME' ? node : node.querySelector && node.querySelector('iframe');
                const src = iframe ? (iframe.getAttribute('src') || '') : '';
                const isAdNode = src.includes('nap5k') || (node.dataset && node.dataset.zone === propSlotId) || /nap5k|propel|propeller|inpage|push/i.test((node.className || '') + ' ' + (node.id || ''));
                if (isAdNode) {
                  try {
                    // If the detected node is a SCRIPT, execute it in head and do not append it to placeholder
                    if (node.tagName === 'SCRIPT') {
                      const src = node.getAttribute('src');
                      if (src) {
                        const s2 = document.createElement('script');
                        s2.src = src;
                        s2.async = true;
                        document.head.appendChild(s2);
                      } else if (node.textContent) {
                        const s2 = document.createElement('script');
                        s2.textContent = node.textContent;
                        document.head.appendChild(s2);
                      }
                      node.parentNode && node.parentNode.removeChild(node);
                      continue;
                    }

                    // move iframe/ad node into placeholder (prefer inline iframe if present)
                    placeholder.innerHTML = '';
                    if (iframe && iframe.parentNode) {
                      placeholder.appendChild(iframe);
                    } else if (node.tagName !== 'SCRIPT') {
                      placeholder.appendChild(node);
                    }

                    const moved = placeholder.firstElementChild;
                    if (moved) {
                      // Normalize size
                      moved.style.maxWidth = '100%';
                      moved.style.display = 'block';
                      // If provider inserted a fixed/absolute positioned element (overlays),
                      // force it to behave as inline block inside our header placeholder.
                      try {
                        const cs = getComputedStyle(moved);
                        if (cs.position === 'fixed' || cs.position === 'absolute') {
                          moved.style.setProperty('position', 'relative', 'important');
                          moved.style.setProperty('top', 'auto', 'important');
                          moved.style.setProperty('right', 'auto', 'important');
                          moved.style.setProperty('left', 'auto', 'important');
                          moved.style.setProperty('bottom', 'auto', 'important');
                          moved.style.setProperty('z-index', '1', 'important');
                          moved.style.setProperty('width', '100%', 'important');
                          moved.style.setProperty('max-width', '970px', 'important');
                        }
                        if (moved.tagName === 'IFRAME') {
                          moved.style.width = '100%';
                          moved.style.height = moved.style.height || '60px';
                        }
                      } catch (e) {
                        console.warn('style normalize failed', e);
                      }
                    }
                    observer.disconnect();
                    try { window.dispatchEvent(new CustomEvent('ads:relocated',{detail:{provider:'propeller',zone:propSlotId}})); } catch {}
                    return;
                  } catch (e) {
                    console.warn('Failed to relocate ad node', e);
                  }
                }
              } catch (e) {
                console.warn('mutation handler error', e);
              }
            }
          }
        });
        observer.observe(parent, { childList: true, subtree: true });

        // Check existing iframes right away
        const existing = Array.from(document.querySelectorAll('iframe')).find(f => (f.src || '').includes('nap5k'));
        if (existing) {
          placeholder.innerHTML = '';
          placeholder.appendChild(existing);
          observer.disconnect();
        }

        // Failsafe: stop observing after 6s
        setTimeout(() => observer.disconnect(), 6000);
      } catch (e) {
        console.warn('observeAndRelocate error', e);
      }
    };

    // Start observing shortly after script insertion to allow provider to run
    setTimeout(observeAndRelocate, 100);

    // Fallback: wenn nach Script‑Load innerhalb 3s kein Ad im Placeholder erscheint,
    // lade ein iframe‑Backup. Das erhöht die Chance, ein sichtbares Banner im Header zu zeigen.
    setTimeout(() => {
      try {
        const ph = adContainer.value.querySelector('.propeller-ad-placeholder');
        const hasChild = ph && ph.children && ph.children.length > 0;
        const height = ph ? parseInt(getComputedStyle(ph).height || '0', 10) : 0;
        if (!hasChild && (!height || height === 0)) {
          console.log('Ad placeholder empty — inserting iframe fallback');
          const iframe = document.createElement('iframe');
          iframe.width = '100%';
          iframe.height = '90';
          iframe.frameBorder = '0';
          iframe.scrolling = 'no';
          iframe.style.border = '0';
          iframe.title = 'Advertisement';
          // Fallback URL: attempt to call tag URL with slot param — may be accepted by provider
          iframe.src = `${propScriptUrl}?slot=${encodeURIComponent(propSlotId)}&responsive=1`;
          ph.innerHTML = '';
          ph.appendChild(iframe);
          try { window.dispatchEvent(new CustomEvent('ads:fallback-inserted',{detail:{provider:'propeller',zone:propSlotId}})); } catch {}
        }
      } catch (e) {
        console.warn('Fallback insertion failed', e);
      }
    }, 3000);
  } catch (err) {
    console.warn('Propeller ad load failed', err);
  }
}

async function renderAdSense() {
  if (!adContainer.value) return;
  try {
    await ensureScriptLoaded(`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${adClient}`, 'adsense');
    const ins = document.createElement('ins');
    ins.className = 'adsbygoogle';
    ins.style.display = 'block';
    ins.style.width = '100%';
    ins.style.height = '50px';
    ins.setAttribute('data-ad-client', adClient);
    ins.setAttribute('data-ad-slot', adSlot);
    adContainer.value.innerHTML = '';
    adContainer.value.appendChild(ins);
    (window.adsbygoogle = window.adsbygoogle || []).push({});
  } catch (err) {
    console.warn('AdSense load failed', err);
  }
}

let adLoaded = false;
async function loadAdIfNeeded() {
  if (adLoaded || !isEnabled.value) return;
  adLoaded = true;
  try {
    if (adContainer.value) adContainer.value.dataset.abVariant = variant;
    window.dispatchEvent(new CustomEvent('ads:load-start', { detail: { provider, variant } }));
  } catch (e) {}
  if (provider === 'propeller') await renderPropeller();
  else if (provider === 'adsense') await renderAdSense();
  try { window.dispatchEvent(new CustomEvent('ads:loaded', { detail: { provider, variant } })); } catch (e) {}
}

onMounted(async () => {
  if (!isEnabled.value) return;

  // If consent present, autoLoad, or debugForceLoad => load immediately
  if (hasConsent() || autoLoad || debugForceLoad) {
    await nextTick();
    await loadAdIfNeeded();
    return;
  }

  // Otherwise, wait for either a user interaction or consent event
  const onFirstInteraction = async () => {
    window.removeEventListener('pointerdown', onFirstInteraction);
    window.removeEventListener('scroll', onFirstInteraction);
    await loadAdIfNeeded();
  };

  window.addEventListener('pointerdown', onFirstInteraction, { once: true });
  window.addEventListener('scroll', onFirstInteraction, { once: true });
  listenForConsentEvent();
});
</script>

<style scoped>
.header-ad-banner {
  width: 100%;
  max-height: 90px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px 12px;
  box-sizing: border-box;
}

.header-ad-banner.sticky {
  position: sticky;
  top: 0;
  z-index: 600;
  background: rgba(255,255,255,0.98);
  backdrop-filter: blur(4px);
  border-bottom: 1px solid rgba(0,0,0,0.04);
}

.ad-container {
  width: 100%;
  max-width: 980px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.ad-container iframe,
.ad-container ins {
  width: 100%;
  max-width: 970px;
  height: 60px;
}

@media (max-width: 720px) {
  .ad-container iframe,
  .ad-container ins {
    height: 50px;
    max-width: 320px;
  }
}
</style>
