/**
 * meSEO Site Tag — SMS / Text Marketing Detection
 * -------------------------------------------------
 * Standalone detection module for SMS opt-in flows that fall outside
 * the standard iframe postMessage path. Detects:
 *
 *   1. sms: protocol link clicks (user texting the business)
 *   2. Keyword opt-in CTAs in page text ("Text JOIN to 55555")
 *   3. TCPA consent checkbox detection (explicit consent to receive texts)
 *   4. Two-step email-then-SMS opt-in sequences
 *   5. Phone field completion tracking (tel: field filled before submit)
 *
 * Privacy: captures field types and keyword/shortcode only — never
 * field values, phone numbers, or personal identifiers.
 *
 * Loaded by the Site Tag alongside form-phone.js. Initialised via
 * window.meSEOSmsDetection.init(cfg) using the same config object as
 * form-phone.js (endpoint + siteId).
 */
(function () {
  "use strict";

  // Matches "Text JOIN to 55555", "Reply START to 12345", etc.
  var SMS_KEYWORD_RE = /(?:text|reply|send)\s+(\w+)\s+to\s+(\d{5,11})/gi;

  // Label text patterns indicating an SMS consent checkbox.
  var SMS_CONSENT_RE = /sms\s*updates|text\s*message|marketing\s*texts?|tcpa|text\s*alerts?|recurring.*text|sign.*up.*sms|opt[\s-]?in.*text/i;

  // Window between email form_submit and an SMS modal appearing (ms).
  var TWO_STEP_WINDOW_MS = 4000;

  function init(cfg) {
    if (!cfg || !cfg.endpoint) return;
    var endpoint = cfg.endpoint;

    function ctx() {
      try { return (window.meSEOAttribution && window.meSEOAttribution.getContext()) || {}; } catch (e) { return {}; }
    }

    function send(extra) {
      var c = ctx();
      var first = (c.touchpoints && c.touchpoints[0]) || null;
      var base = {
        siteId: cfg.siteId,
        visitorId: c.visitorId || null,
        sessionId: c.sessionId || null,
        pageUrl: window.location.href,
        firstTouchChannel: first ? first.channel : null,
        firstTouchSource: first ? first.source : null,
        lastTouchChannel: c.currentTouch ? c.currentTouch.channel : null,
        lastTouchSource: c.currentTouch ? c.currentTouch.source : null,
        touchpoints: c.touchpoints || [],
        timestamp: new Date().toISOString(),
      };
      for (var k in extra) {
        if (Object.prototype.hasOwnProperty.call(extra, k)) base[k] = extra[k];
      }
      var body = JSON.stringify(base);
      try {
        if (navigator.sendBeacon) {
          navigator.sendBeacon(endpoint, new Blob([body], { type: "application/json" }));
          return;
        }
      } catch (e) {}
      try {
        fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: body, keepalive: true, credentials: "omit" }).catch(function () {});
      } catch (e) {}
    }

    // ── 1. sms: protocol link clicks ─────────────────────────────────────
    // Distinct from tel: click (phone_call). A sms: click means the user
    // is initiating an outbound text TO the business — this is a soft
    // conversion signal (intent to contact, not yet completed).
    var smsFired = {};
    document.addEventListener("click", function (e) {
      try {
        var el = e.target;
        var a = el;
        while (a && a.tagName !== "A") a = a.parentElement;
        if (!a || !a.href) return;
        var href = a.href.toLowerCase();
        if (href.indexOf("sms:") !== 0 && href.indexOf("smsto:") !== 0) return;
        // Extract destination number (before any ?body= parameter)
        var raw = a.href.replace(/^sms(?:to)?:/i, "").split("?")[0].replace(/\D/g, "");
        if (!raw || raw.length < 5) return;
        // Dedup: one per number per 5-minute bucket
        var bucket = String(Math.floor(Date.now() / 300000));
        var key = "sms:" + raw + ":" + bucket;
        if (smsFired[key]) return;
        smsFired[key] = true;
        // Extract pre-filled body from ?body= parameter if present
        var bodyParam = "";
        var qIdx = a.href.indexOf("?");
        if (qIdx !== -1) {
          try {
            bodyParam = new URLSearchParams(a.href.slice(qIdx + 1)).get("body") || "";
          } catch (x) {}
        }
        send({
          conversionType: "sms_outbound_click",
          formProvider: "sms_link",
          detectionMethod: "sms_link_click",
          smsKeyword: bodyParam ? bodyParam.trim().slice(0, 50) : null,
          detectionLatencyMs: window.__meSEOPageLoadMs ? Date.now() - window.__meSEOPageLoadMs : null,
        });
      } catch (err) {}
    }, true);

    // ── 2. SMS keyword CTA detection ─────────────────────────────────────
    // Scans visible page text for patterns like "Text JOIN to 55555".
    // Fires once per unique keyword+shortcode combo per page load as a
    // Tier 2 intent signal (the user SAW the CTA, not necessarily acted).
    var seenKeywords = {};
    function scanKeywordCTAs(root) {
      try {
        var walker = document.createTreeWalker(root || document.body, 4 /* NodeFilter.SHOW_TEXT */);
        var node;
        while ((node = walker.nextNode())) {
          var text = node.nodeValue || "";
          if (text.length < 10 || text.length > 500) continue;
          SMS_KEYWORD_RE.lastIndex = 0;
          var match;
          while ((match = SMS_KEYWORD_RE.exec(text)) !== null) {
            var keyword = match[1].toUpperCase();
            var shortcode = match[2];
            var k = keyword + ":" + shortcode;
            if (seenKeywords[k]) continue;
            seenKeywords[k] = true;
            send({
              conversionType: "sms_keyword_displayed",
              formProvider: "sms_keyword",
              detectionMethod: "text_scan",
              smsKeyword: keyword,
              smsShortcode: shortcode,
              detectionLatencyMs: window.__meSEOPageLoadMs ? Date.now() - window.__meSEOPageLoadMs : null,
            });
          }
        }
      } catch (err) {}
    }
    // Initial scan after DOM is ready
    if (document.readyState === "loading") {
      document.addEventListener("DOMContentLoaded", function () { scanKeywordCTAs(document.body); });
    } else {
      scanKeywordCTAs(document.body);
    }
    // Also watch for dynamically injected CTAs (popups, lazy-loaded sections)
    try {
      var kwMo = new MutationObserver(function (muts) {
        for (var i = 0; i < muts.length; i++) {
          var added = muts[i].addedNodes;
          for (var j = 0; j < added.length; j++) {
            if (added[j].nodeType === 1) scanKeywordCTAs(added[j]);
          }
        }
      });
      kwMo.observe(document.body || document.documentElement, { childList: true, subtree: true });
    } catch (e) {}

    // ── 3. TCPA consent checkbox detection ───────────────────────────────
    // When a form containing a checked SMS-consent checkbox is submitted,
    // enrich the conversion with smsConsentMethod = 'explicit_checkbox'.
    // Does NOT fire a new conversion — it augments the existing form_submit
    // by emitting an additional sms_optin event only when consent is present.
    document.addEventListener("submit", function (e) {
      try {
        var form = e.target;
        if (!form || form.tagName !== "FORM") return;
        var checkboxes = form.querySelectorAll("input[type='checkbox']");
        for (var ci = 0; ci < checkboxes.length; ci++) {
          var cb = checkboxes[ci];
          if (!cb.checked) continue;
          // Check the label text adjacent to this checkbox
          var labelText = "";
          var lbl = form.querySelector("label[for='" + cb.id + "']");
          if (lbl) {
            labelText = lbl.textContent || "";
          } else if (cb.parentElement) {
            labelText = cb.parentElement.textContent || "";
          }
          if (SMS_CONSENT_RE.test(labelText)) {
            send({
              conversionType: "sms_optin",
              formProvider: "explicit_checkbox",
              detectionMethod: "consent_checkbox",
              smsConsentMethod: "explicit_checkbox",
              detectionLatencyMs: window.__meSEOPageLoadMs ? Date.now() - window.__meSEOPageLoadMs : null,
            });
            break;
          }
        }
      } catch (err) {}
    }, true);

    // ── 4. Phone field completion tracking ───────────────────────────────
    // When a tel: type input is filled and the user leaves the field, emit
    // a Tier 2 soft conversion signal. The value itself is never captured.
    // Only fires if the field contained a valid phone-length value (>=10 digits).
    var phoneFieldsFired = {};
    document.addEventListener("blur", function (e) {
      try {
        var el = e.target;
        if (!el || el.tagName !== "INPUT") return;
        var t = (el.type || "").toLowerCase();
        var n = (el.name || "").toLowerCase();
        var id = (el.id || "").toLowerCase();
        if (t !== "tel" && !n.includes("phone") && !id.includes("phone")) return;
        var digits = (el.value || "").replace(/\D/g, "");
        if (digits.length < 10) return;
        // Dedup: one per field ID+name per page load
        var fieldKey = (el.id || el.name || "unknown") + ":completed";
        if (phoneFieldsFired[fieldKey]) return;
        phoneFieldsFired[fieldKey] = true;
        send({
          conversionType: "phone_field_completed",
          formProvider: "form_field",
          detectionMethod: "field_blur",
          detectionLatencyMs: window.__meSEOPageLoadMs ? Date.now() - window.__meSEOPageLoadMs : null,
        });
      } catch (err) {}
    }, true);

    // ── 5. Two-step SMS opt-in sequence detection ─────────────────────────
    // Sequence: form_submit (email) -> modal/popup appears within TWO_STEP_WINDOW_MS
    // -> tel: field interaction in modal -> second submission.
    // Emits 'sms_optin_followup' linking the two conversions via smsConsentMethod.
    var lastFormSubmitAt = 0;
    var lastFormSubmitEl = null;
    document.addEventListener("submit", function (e) {
      try {
        var form = e.target;
        if (!form || form.tagName !== "FORM") return;
        // Check if this form has a tel: or phone field (SMS step)
        var hasTel = form.querySelector("input[type='tel'], input[name*='phone'], input[id*='phone']");
        if (hasTel) {
          // This is the SMS step in a two-step flow
          var timeSinceLast = Date.now() - lastFormSubmitAt;
          if (lastFormSubmitAt > 0 && timeSinceLast <= TWO_STEP_WINDOW_MS) {
            send({
              conversionType: "sms_optin_followup",
              formProvider: "two_step_form",
              detectionMethod: "two_step_sequence",
              smsConsentMethod: "two_step_followup",
              detectionLatencyMs: timeSinceLast,
            });
          }
          return;
        }
        // This is the first step (email/primary form)
        lastFormSubmitAt = Date.now();
        lastFormSubmitEl = form;
      } catch (err) {}
    }, true);
  }

  // Store page load time for detectionLatencyMs calculations
  window.__meSEOPageLoadMs = window.__meSEOPageLoadMs || Date.now();

  window.meSEOSmsDetection = { init: init };
})();
