const MULTI_LABEL_PUBLIC_SUFFIXES = new Set([
  'ac.uk', 'co.uk', 'gov.uk', 'ltd.uk', 'net.uk', 'org.uk', 'plc.uk', 'sch.uk',
  'com.au', 'net.au', 'org.au', 'edu.au', 'gov.au',
  'com.br', 'net.br', 'org.br',
  'com.cn', 'net.cn', 'org.cn',
  'com.tw', 'net.tw', 'org.tw',
  'com.sg', 'net.sg', 'org.sg',
  'co.nz', 'net.nz', 'org.nz', 'gov.nz',
  'co.jp', 'ne.jp', 'or.jp', 'go.jp',
  'co.kr', 'ne.kr', 'or.kr', 'go.kr',
  'co.in', 'firm.in', 'gen.in', 'ind.in', 'net.in', 'org.in',
  'com.mx', 'net.mx', 'org.mx',
  'co.za', 'net.za', 'org.za',
  'com.tr', 'net.tr', 'org.tr'
]);

function deriveCookieDomain(hostname) {
  if (!hostname) return hostname;

  const lowerHost = hostname.toLowerCase();
  const isIPv4 = /^\d{1,3}(\.\d{1,3}){3}$/.test(lowerHost);
  const isIPv6 = lowerHost.includes(':');

  if (lowerHost === 'localhost' || isIPv4 || isIPv6) {
    return lowerHost;
  }

  const parts = lowerHost.split('.');
  if (parts.length < 2) {
    return lowerHost;
  }

  const lastTwo = parts.slice(-2).join('.');
  if (MULTI_LABEL_PUBLIC_SUFFIXES.has(lastTwo)) {
    if (parts.length >= 3) {
      return '.' + parts.slice(-3).join('.');
    }
    return lowerHost;
  }

  if (parts.length === 2) {
    return '.' + parts.join('.');
  }

  return '.' + parts.slice(-2).join('.');
}

const COOKIE_DOMAIN = deriveCookieDomain(window.location.hostname);

// Smoke check helper (manual): run `window.__gobiiAnalyticsCookieDomainFor('app.example.co.uk')`
// in the browser console to verify how we derive the cookie scope for a hostname.
if (typeof window !== 'undefined') {
  window.__gobiiAnalyticsCookieDomainFor = deriveCookieDomain;
}

const UTM_PARAMS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
const CLICK_ID_PARAMS = ['gclid', 'wbraid', 'gbraid', 'msclkid', 'ttclid', 'rdt_cid', 'fbclid'];
const AUTH_REFERRER_DOMAINS = new Set([
  'accounts.google.com',
  'login.microsoftonline.com'
]);
const INTERNAL_REFERRER_ROOT_DOMAINS = new Set([
  'gobii.ai'
]);

const LANDING_PARAM = 'g';

function isAuthProviderReferrer(referrer) {
  if (!referrer) return false;
  try {
    const hostname = referrerHostname(referrer);
    for (const domain of AUTH_REFERRER_DOMAINS) {
      if (hostname === domain || hostname.endsWith(`.${domain}`)) {
        return true;
      }
    }
    return false;
  } catch (e) {
    return false;
  }
}

function referrerHostname(referrer) {
  if (!referrer) return '';
  try {
    return new URL(referrer).hostname.toLowerCase().replace(/\.$/, '');
  } catch (e) {
    return '';
  }
}

function isInternalReferrer(referrer) {
  const hostname = referrerHostname(referrer);
  if (!hostname) return false;
  for (const domain of INTERNAL_REFERRER_ROOT_DOMAINS) {
    if (hostname === domain || hostname.endsWith(`.${domain}`)) {
      return true;
    }
  }
  return false;
}

function isSameHostReferrer(referrer) {
  const hostname = referrerHostname(referrer);
  const currentHostname = (window.location.hostname || '').toLowerCase().replace(/\.$/, '');
  return Boolean(hostname && currentHostname && hostname === currentHostname);
}

function isExternalAcquisitionReferrer(referrer) {
  return Boolean(
    referrer
    && !isAuthProviderReferrer(referrer)
    && !isSameHostReferrer(referrer)
    && !isInternalReferrer(referrer)
  );
}

(function() {
  const params = new URLSearchParams(window.location.search);
 UTM_PARAMS.forEach(function(p) {
    const value = params.get(p);
    if (value) {
      // Store each UTM param in a 1st-party cookie (valid for, say, 60 days)
      const d = new Date();
      d.setTime(d.getTime() + (60*24*60*60*1000));
      document.cookie = p + "=" + encodeURIComponent(value) + "; expires=" + d.toUTCString() + "; path=/; SameSite=Lax; domain=" + COOKIE_DOMAIN;
    }
  });
})();

(function () {
  const params = new URLSearchParams(window.location.search);
  const found = {};

  CLICK_ID_PARAMS.forEach((param) => {
    let value = params.get(param);
    if (!value && param === 'rdt_cid') {
      value = params.get('rdt_click_id');
    }
    if (!value) return;

    const expiry = new Date();
    expiry.setTime(expiry.getTime() + (60*24*60*60*1000));
    const attrs = `; expires=${expiry.toUTCString()}; path=/; SameSite=Lax; domain=${COOKIE_DOMAIN}`;
    document.cookie = `${param}=${encodeURIComponent(value)}${attrs}`;
    found[param] = value;
  });

  if (Object.keys(found).length === 0) return;

  if (!document.cookie.includes('__click_first=')) {
    const expiry = new Date();
    expiry.setTime(expiry.getTime() + (60*24*60*60*1000));
    const attrs = `; expires=${expiry.toUTCString()}; path=/; SameSite=Lax; domain=${COOKIE_DOMAIN}`;
    document.cookie = `__click_first=${encodeURIComponent(JSON.stringify(found))}${attrs}`;
  }
})();

// Meta attribution fallbacks: synthesize _fbc from fbclid, generate _fbp when pixel is blocked
(function () {
  const params = new URLSearchParams(window.location.search);
  const fbclid = params.get('fbclid');
  const now = Date.now();
  const expiry = new Date(now + 90 * 24 * 60 * 60 * 1000);
  const attrs = `; expires=${expiry.toUTCString()}; path=/; SameSite=Lax; domain=${COOKIE_DOMAIN}`;

  // Synthesize _fbc when fbclid is present and _fbc is missing or for a different click
  if (fbclid) {
    const fbcMatch = document.cookie.match(/(?:^|;\s*)_fbc=([^;]*)/);
    const existing = fbcMatch ? decodeURIComponent(fbcMatch[1]) : '';
    const oldClickId = existing.startsWith('fb.1.') ? existing.split('.').slice(3).join('.') : '';
    if (oldClickId !== fbclid) {
      document.cookie = `_fbc=${encodeURIComponent('fb.1.' + now + '.' + fbclid)}${attrs}`;
    }
  }

  // Generate _fbp if Meta Pixel hasn't set it (e.g. ad blocker).
  // Short delay lets fbevents.js write it first when not blocked.
  setTimeout(function () {
    if (document.cookie.includes('_fbp=')) return;
    const rand = (Math.floor(Math.random() * 9000000000) + 1000000000).toString();
    document.cookie = `_fbp=${encodeURIComponent('fb.1.' + now + '.' + rand)}${attrs}`;
  }, 1500);
})();

(function () {
  const expiry = new Date();
  expiry.setTime(expiry.getTime() + (60*24*60*60*1000));
  const attrs = `; expires=${expiry.toUTCString()}; path=/; SameSite=Lax; domain=${COOKIE_DOMAIN}`;

  const currentPath = window.location.pathname + window.location.search;
  const rawReferrer = document.referrer || '';
  const isExternalReferrer = isExternalAcquisitionReferrer(rawReferrer);
  const referrer = isExternalReferrer ? rawReferrer : '';

  if (!document.cookie.includes('first_referrer=')) {
    document.cookie = `first_referrer=${encodeURIComponent(referrer)}${attrs}`;
  }
  if (isExternalReferrer) {
    document.cookie = `last_referrer=${encodeURIComponent(referrer)}${attrs}`;
  }

  if (!document.cookie.includes('first_path=')) {
    document.cookie = `first_path=${encodeURIComponent(currentPath)}${attrs}`;
  }
  document.cookie = `last_path=${encodeURIComponent(currentPath)}${attrs}`;
})();

(function () {
  const params = new URLSearchParams(window.location.search);
  const landingCode = params.get(LANDING_PARAM);
  if (!landingCode) return;

  const d = new Date();
  d.setTime(d.getTime() + (60*24*60*60*1000));
  const cookieValue = encodeURIComponent(landingCode);
  const cookieAttrs = `; expires=${d.toUTCString()}; path=/; SameSite=Lax; domain=${COOKIE_DOMAIN}`;
  document.cookie = `landing_code=${cookieValue}${cookieAttrs}`;

  if (!document.cookie.includes('__landing_first=')) {
    document.cookie = `__landing_first=${cookieValue}${cookieAttrs}`;
  }
})();

(function () {
  const keys = ['utm_source','utm_medium','utm_campaign','utm_content','utm_term'];
  const hasUtm = keys.some(k => new URLSearchParams(location.search).has(k));
  if (!hasUtm) return;

  const utm = {};
  keys.forEach(k => {
    const v = new URLSearchParams(location.search).get(k);
    if (v) utm[k] = v;
  });
  // Persist first-touch once
  if (!document.cookie.includes('__utm_first=')) {
    document.cookie = '__utm_first=' + encodeURIComponent(JSON.stringify(utm))
                    + ';path=/;SameSite=Lax;max-age=' + 60*60*24*365
                    + ';domain=' + COOKIE_DOMAIN;
  }
})();

function getUTMParams() {
  // Returns an object with UTM parameters from cookies
  const params = {};

  UTM_PARAMS.forEach(name => {
    const match = document.cookie.match(
      new RegExp('(?:^|;\\s*)' + name + '=([^;]*)')   // ← tighter prefix, lenient space
    );
    if (match) params[name] = decodeURIComponent(match[1]);
  });

  return params;
}
