/**
 * VisitorLens — Gate (Consent + URL Exclusion)
 * Shared module loaded before tracker.js and recorder.js.
 * Provides window.vlensGateCheck with methods both scripts use
 * to decide whether they should run.
 *
 * Requires vlensGate localized object from WordPress:
 *   vlensGate.consent_required  (bool)
 *   vlensGate.consent_mode      (string: none|cookieyes|complianz|cookiebot|custom)
 *   vlensGate.consent_cookie_name (string)
 *   vlensGate.exclude_urls      (array of pattern strings, supports * wildcard)
 */
(function () {
  'use strict';

  if (typeof vlensGate === 'undefined') {
    window.vlensGateCheck = { allowed: function () { return true; }, onConsent: function (cb) { cb(); } };
    return;
  }

  var cfg = vlensGate;

  /* ── URL Exclusion ── */

  /**
   * Match a URL path against a pattern with * wildcards.
   * e.g. "/checkout/*" matches "/checkout/step-1"
   */
  function matchPattern(pattern, path) {
    if (!pattern) return false;
    // Exact match
    if (pattern === path) return true;
    // Convert wildcard pattern to regex
    var escaped = pattern.replace(/[.+^${}()|[\]\\]/g, '\\$&');
    var regex = new RegExp('^' + escaped.replace(/\*/g, '.*') + '$');
    return regex.test(path);
  }

  function isUrlExcluded() {
    var patterns = cfg.exclude_urls;
    if (!patterns || !patterns.length) return false;
    var path = window.location.pathname + window.location.search;
    for (var i = 0; i < patterns.length; i++) {
      if (matchPattern(patterns[i], path)) return true;
    }
    return false;
  }

  /* ── Cookie Consent ── */

  function getCookie(name) {
    var match = document.cookie.match(new RegExp('(?:^|;\\s*)' + name.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '=([^;]*)'));
    return match ? decodeURIComponent(match[1]) : null;
  }

  /**
   * Check if consent has been given based on the configured mode.
   */
  function hasConsent() {
    if (!cfg.consent_required) return true;

    switch (cfg.consent_mode) {
      case 'none':
        return true;

      case 'cookieyes':
        // CookieYes stores consent as: cookieyes-consent=...analytics:yes...
        var cyVal = getCookie('cookieyes-consent');
        if (!cyVal) return false;
        return /analytics:yes/i.test(cyVal) || /statistics:yes/i.test(cyVal);

      case 'complianz':
        // Complianz: cmplz_consent_status or cmplz_statistics
        var cmplzStatus = getCookie('cmplz_consent_status') || getCookie('cmplz_statistics');
        if (!cmplzStatus) return false;
        return cmplzStatus === 'allow' || cmplzStatus === '1';

      case 'cookiebot':
        // Cookiebot JS API
        if (typeof window.Cookiebot !== 'undefined' && window.Cookiebot.consent) {
          return !!window.Cookiebot.consent.statistics;
        }
        // Fallback: CookieConsent cookie
        var cbVal = getCookie('CookieConsent');
        if (!cbVal) return false;
        return /statistics:true/i.test(cbVal);

      case 'custom':
        // Check for a custom cookie name — presence (any truthy value) = consent
        var customName = cfg.consent_cookie_name;
        if (!customName) return false;
        var customVal = getCookie(customName);
        return !!customVal && customVal !== '0' && customVal !== 'false' && customVal !== 'no';

      default:
        return true;
    }
  }

  /* ── Combined gate check ── */

  function allowed() {
    if (isUrlExcluded()) return false;
    if (!hasConsent()) return false;
    return true;
  }

  /* ── Consent listener (poll + events) ── */

  /**
   * Call `cb` as soon as consent is given. If consent is already given, fires immediately.
   * If consent is never given, `cb` is never called.
   * Uses a combination of polling (every 1.5s) and event listeners for known plugins.
   */
  function onConsent(cb) {
    if (!cfg.consent_required || hasConsent()) {
      cb();
      return;
    }

    var fired = false;
    function fire() {
      if (fired) return;
      if (!hasConsent()) return;
      fired = true;
      clearInterval(pollId);
      cb();
    }

    // Poll every 1.5s for cookie changes
    var pollId = setInterval(fire, 1500);

    // Listen for known consent events
    if (cfg.consent_mode === 'cookieyes') {
      document.addEventListener('cookieyes_consent_update', fire);
    }
    if (cfg.consent_mode === 'cookiebot') {
      window.addEventListener('CookiebotOnAccept', fire);
    }
    if (cfg.consent_mode === 'complianz') {
      document.addEventListener('cmplz_fire_categories', fire);
    }

    // Stop polling after 5 minutes to avoid leaking
    setTimeout(function () { clearInterval(pollId); }, 300000);
  }

  /* ── Public API ── */

  window.vlensGateCheck = {
    allowed:      allowed,
    hasConsent:   hasConsent,
    isUrlExcluded: isUrlExcluded,
    onConsent:    onConsent,
  };
})();
