/**
 * MailForge Onsite-Tracking-Snippet (Phase 3+4)
 *
 * Einbindung auf der Brand-Zielseite (vor schließendem </body>):
 *   <script src="https://mailforge.example.de/mf-track.js" data-brand="its" defer></script>
 *
 * Was getrackt wird:
 *   - pageview           (automatisch beim DOMContentLoaded)
 *   - scroll_depth       (25/50/75/100% Schwellen)
 *   - time_on_page       (beim beforeunload / visibilitychange hidden)
 *   - product_view       (manuell via data-mf-event="product_view" data-mf-product-id="...")
 *   - add_to_cart        (data-mf-event="add_to_cart" data-mf-value="2990")
 *   - quote_form         (Form-Submit auf <form data-mf-event="quote_form">)
 *   - custom             (data-mf-event="custom" data-mf-name="...")
 *
 * Consent / Opt-Out (in dieser Reihenfolge):
 *   1. localStorage.getItem('mf_track_optout') === '1' → no-op
 *   2. Cookie mf_track_optout=1 → no-op
 *   3. navigator.doNotTrack === '1' → no-op
 *   4. window.mfConsent === false → no-op
 *   5. TCFv2 __tcfapi mit vendor[MailForge] = false → no-op (best-effort, kein eigener Vendor-ID-Lookup)
 *
 * Quelle des Attribution-Contexts (recipientId/campaignId/variantId):
 *   1. Cookie mf_attr={"r":...,"c":...,"v":...} (vom Click-Redirect gesetzt)
 *   2. URL-Param ?mf_rcp=... (Fallback wenn Cookie fehlt)
 *   3. Wenn beides fehlt → kein Tracking (Events brauchen einen Recipient)
 *
 * Sende-Strategie:
 *   - navigator.sendBeacon() für unload-Events (kein Block)
 *   - fetch(..., { keepalive: true }) für Inline-Events
 *   - Bei sendBeacon-Fehler: silent fail, kein Retry (Best-Effort)
 *
 * Vanilla JS, kein Build-Step — funktioniert in jedem modernen Browser.
 */
(function () {
  'use strict';

  // ─── Konfiguration: aus <script>-Tag-Attributen lesen ────────────────────
  var currentScript = document.currentScript || (function () {
    var scripts = document.getElementsByTagName('script');
    return scripts[scripts.length - 1];
  })();
  if (!currentScript) return;

  var brandSlug = currentScript.getAttribute('data-brand') || '';
  // Endpoint-Origin aus src ableiten (gleiche Origin wie das Script selbst)
  var scriptSrc = currentScript.getAttribute('src') || '';
  var endpointOrigin = '';
  try {
    endpointOrigin = scriptSrc ? new URL(scriptSrc, location.href).origin : location.origin;
  } catch (e) {
    return; // ohne valide Endpoint-Origin geht nichts
  }
  var endpoint = endpointOrigin + '/api/track/behavior';

  // ─── Consent-Check ───────────────────────────────────────────────────────
  function hasOptedOut() {
    try {
      if (localStorage.getItem('mf_track_optout') === '1') return true;
    } catch (e) {
      // localStorage blockiert (Inkognito, Cookies disabled) — egal, fallback
    }
    if (document.cookie && document.cookie.indexOf('mf_track_optout=1') !== -1) return true;
    if (navigator.doNotTrack === '1' || navigator.doNotTrack === 'yes') return true;
    if (window.mfConsent === false) return true;
    return false;
  }
  if (hasOptedOut()) return;

  // ─── Attribution-Context lesen ───────────────────────────────────────────
  function getAttrContext() {
    // Cookie
    var m = document.cookie.match(/(?:^|;\s*)mf_attr=([^;]+)/);
    if (m) {
      try {
        var decoded = decodeURIComponent(m[1]);
        var parsed = JSON.parse(decoded);
        if (parsed && parsed.r) {
          return { recipientId: parsed.r, campaignId: parsed.c || null, variantId: parsed.v || null };
        }
      } catch (e) { /* ignore */ }
    }
    // URL-Param Fallback
    try {
      var url = new URL(location.href);
      var r = url.searchParams.get('mf_rcp');
      var c = url.searchParams.get('mf_cmp');
      var v = url.searchParams.get('mf_v');
      if (r) return { recipientId: r, campaignId: c, variantId: v };
    } catch (e) { /* ignore */ }
    return null;
  }

  var ctx = getAttrContext();
  if (!ctx) return; // Keine Attribution → kein Tracking

  // ─── Event-Send-Funktionen ───────────────────────────────────────────────
  function send(type, extra) {
    var body = {
      recipientId: ctx.recipientId,
      campaignId: ctx.campaignId,
      variantId: ctx.variantId,
      type: type,
      url: location.href,
      brand: brandSlug || undefined,
    };
    if (extra) {
      for (var k in extra) {
        if (Object.prototype.hasOwnProperty.call(extra, k)) body[k] = extra[k];
      }
    }
    try {
      var json = JSON.stringify(body);
      // sendBeacon erfordert Blob mit explizitem MIME-Type
      var blob = new Blob([json], { type: 'application/json' });
      if (navigator.sendBeacon && navigator.sendBeacon(endpoint, blob)) return;
    } catch (e) { /* fallthrough */ }
    // Fallback: fetch mit keepalive
    try {
      fetch(endpoint, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
        keepalive: true,
        mode: 'cors',
        credentials: 'omit',
      }).catch(function () { /* swallow */ });
    } catch (e) { /* swallow */ }
  }

  // ─── Auto-Events ─────────────────────────────────────────────────────────
  var startTs = Date.now();
  var maxScroll = 0;
  var scrollMarks = { 25: false, 50: false, 75: false, 100: false };

  function onScroll() {
    var docHeight = Math.max(
      document.body.scrollHeight,
      document.documentElement.scrollHeight,
      document.body.offsetHeight,
      document.documentElement.offsetHeight,
    );
    var winHeight = window.innerHeight;
    var scrollTop = window.scrollY || document.documentElement.scrollTop;
    var pct = docHeight > winHeight ? Math.round(((scrollTop + winHeight) / docHeight) * 100) : 100;
    if (pct > maxScroll) maxScroll = pct;
    // Schwellen-Events emittieren
    [25, 50, 75, 100].forEach(function (mark) {
      if (!scrollMarks[mark] && maxScroll >= mark) {
        scrollMarks[mark] = true;
        send('scroll_depth', { scrollPct: mark });
      }
    });
  }

  function onVisibilityHidden() {
    var durationMs = Date.now() - startTs;
    // Nur senden wenn Seite ≥ 3s besucht wurde (sonst zu viel Lärm)
    if (durationMs >= 3000) {
      send('time_on_page', { durationMs: durationMs });
    }
  }

  // pageview sofort
  function emitPageview() {
    send('pageview');
  }

  // ─── Markup-Events: data-mf-event auf Buttons/Links/Forms ────────────────
  function onClickCapture(e) {
    var el = e.target.closest('[data-mf-event]');
    if (!el) return;
    var evt = el.getAttribute('data-mf-event');
    if (!evt) return;
    var extra = {};
    var pid = el.getAttribute('data-mf-product-id');
    var val = el.getAttribute('data-mf-value');
    var name = el.getAttribute('data-mf-name');
    if (pid) extra.productId = pid;
    if (val) {
      var n = parseInt(val, 10);
      if (Number.isFinite(n)) extra.value = n;
    }
    if (name) extra.meta = { name: name };
    send(evt, extra);
  }

  function onSubmitCapture(e) {
    var form = e.target;
    if (!(form instanceof HTMLFormElement)) return;
    if (!form.hasAttribute('data-mf-event')) return;
    var evt = form.getAttribute('data-mf-event') || 'quote_form';
    send(evt, { url: form.action || location.href });
  }

  // ─── JSON-LD Heuristik für Product-View ──────────────────────────────────
  function detectProductSchema() {
    try {
      var scripts = document.querySelectorAll('script[type="application/ld+json"]');
      for (var i = 0; i < scripts.length; i++) {
        try {
          var data = JSON.parse(scripts[i].textContent || '');
          var arr = Array.isArray(data) ? data : [data];
          for (var j = 0; j < arr.length; j++) {
            var item = arr[j];
            if (item && (item['@type'] === 'Product' || item['@type'] === 'product')) {
              send('product_view', {
                productId: item.sku || item.productID || item.identifier || undefined,
                meta: { name: item.name },
              });
              return; // Nur einmal pro Pageview
            }
          }
        } catch (e) { /* malformed JSON-LD, skip */ }
      }
    } catch (e) { /* defensive */ }
  }

  // ─── Bootstrap ───────────────────────────────────────────────────────────
  function init() {
    emitPageview();
    detectProductSchema();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('beforeunload', onVisibilityHidden, { capture: false });
    document.addEventListener('visibilitychange', function () {
      if (document.visibilityState === 'hidden') onVisibilityHidden();
    });
    document.addEventListener('click', onClickCapture, true);
    document.addEventListener('submit', onSubmitCapture, true);
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }

  // Public API für manuelles Tracking
  window.mfTrack = function (type, extra) { send(type, extra); };
})();
