/* ============================================================
   Globinex — Trust / Quality Verification section animations
   ============================================================ */
(function () {
  "use strict";

  /* ---------- 1. Rotating quality flags around the shield ---------- */
  var flagSets = {
    top: [
      { cls: "green",  icon: "bi-person-check-fill", text: "Impossible tenure claim" }
    ],
    mid: [
      { cls: "red",    icon: "bi-robot",             text: "Bot cadence detected" }
    ],
    bottom: [
      { cls: "amber",  icon: "bi-keyboard-fill",     text: "Password manager autofill trace" }
    ]
  };

  function cycleFlag(el, list, interval, offset) {
    var i = 0;
    function render() {
      var f = list[i % list.length];
      el.className = "flag " + el.dataset.pos + " " + f.cls;
      el.innerHTML = '<span class="flag-ic"><i class="bi ' + f.icon + '"></i></span><span class="flag-text">' + f.text + '</span>';
      // fade in
      requestAnimationFrame(function () {
        requestAnimationFrame(function () { el.classList.add("show"); });
      });
      // fade out before swap
      setTimeout(function () { el.classList.remove("show"); }, interval - 600);
      i++;
    }
    setTimeout(function () { render(); setInterval(render, interval); }, offset);
  }

  var fTop = document.getElementById("flagTop");
  var fMid = document.getElementById("flagMid");
  var fBottom = document.getElementById("flagBottom");
  if (fTop)    { fTop.dataset.pos = "f-top";       cycleFlag(fTop, flagSets.top, 3600, 400); }
  if (fMid)    { fMid.dataset.pos = "f-mid";        cycleFlag(fMid, flagSets.mid, 4200, 1600); }
  if (fBottom) { fBottom.dataset.pos = "f-bottom";  cycleFlag(fBottom, flagSets.bottom, 3900, 2600); }

  /* ---------- 2. Certified-data counter (declared before flow so bumps are safe) ---------- */
  var certEl = document.getElementById("certNum");
  var certValue = 68935924;
  function bumpCounter() {
    if (!Number.isFinite(certValue)) certValue = 68935924;
    certValue += 1;
    if (certEl) certEl.textContent = certValue.toLocaleString("en-US");
  }
  if (certEl) {
    var certStart = certValue - 260, ct0 = null, cdur = 1600;
    (function intro(ts) {
      if (!ct0) ct0 = ts;
      var p = Math.min((ts - ct0) / cdur, 1);
      var eased = 1 - Math.pow(1 - p, 3);
      var val = Math.round(certStart + (certValue - certStart) * eased);
      if (Number.isFinite(val)) certEl.textContent = val.toLocaleString("en-US");
      if (p < 1) requestAnimationFrame(intro);
    })();
  }

  /* ---------- 3. Single continuous journey:
        country -> shield -> certified box -> one category (one by one) ---------- */
  var section = document.querySelector(".tv-section");
  var shieldWrap = document.querySelector(".shield-wrap");
  var dbIcon = document.querySelector(".db-icon");
  var cards = [].slice.call(document.querySelectorAll(".tv-card"));
  var countryBubbles = [].slice.call(document.querySelectorAll(".bubble.country"));

  if (section && shieldWrap && dbIcon && cards.length) {
    var layer = document.createElement("div");
    layer.className = "tv-flow";
    section.appendChild(layer);

    function center(el) {
      var r = el.getBoundingClientRect(), s = section.getBoundingClientRect();
      return { x: r.left - s.left + r.width / 2, y: r.top - s.top + r.height / 2 };
    }
    function easeInOut(t) { return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2; }

    var cardIdx = 0;

    function spawn() {
      var target = cardIdx % cards.length;
      cardIdx++;
      var rejected = Math.random() < 0.05;   // normal filtration: only a rare few filtered out

      var startEl = countryBubbles[Math.floor(Math.random() * countryBubbles.length)] || shieldWrap;
      var pStart = center(startEl);
      var pShield = center(shieldWrap);
      var pDb = center(dbIcon);
      var pCardEl = cards[target].querySelector(".ic");
      var pCard = center(pCardEl);
      var jit = (Math.random() - 0.5) * 26;   // slight spread so overlapping users don't stack

      var wp, END;
      if (rejected) {
        // country -> shield -> get flagged and drop away
        wp = [
          { x: pStart.x,  y: pStart.y,  t: 0 },
          { x: pShield.x, y: pShield.y + jit, t: 1400 },
          { x: pShield.x, y: pShield.y + jit, t: 1850 },
          { x: pShield.x - 70 + jit, y: pShield.y + 120, t: 2650 }  // rejected: fall out to the side
        ];
        END = 2650;
      } else {
        wp = [
          { x: pStart.x,  y: pStart.y,  t: 0 },
          { x: pShield.x, y: pShield.y + jit, t: 1450 },
          { x: pShield.x, y: pShield.y + jit, t: 1950 },   // hold: verification
          { x: pDb.x,     y: pDb.y + jit,     t: 3000 },
          { x: pDb.x,     y: pDb.y + jit,     t: 3400 },    // hold: certified
          { x: pCard.x,   y: pCard.y,         t: 4600 }
        ];
        END = 4600;
      }

      var dot = document.createElement("i");
      dot.className = "bi bi-person-fill tv-runner";
      layer.appendChild(dot);

      var shieldHit = false, dbHit = false, cardHit = false, flagged = false;
      var t0 = null;
      function step(ts) {
        if (t0 === null) t0 = ts;
        var el = ts - t0;
        var i = 0;
        while (i < wp.length - 1 && el > wp[i + 1].t) i++;
        var a = wp[i], b = wp[Math.min(i + 1, wp.length - 1)];
        var span = Math.max(1, b.t - a.t);
        var lt = Math.min(1, Math.max(0, (el - a.t) / span));
        var e = easeInOut(lt);
        dot.style.left = (a.x + (b.x - a.x) * e) + "px";
        dot.style.top = (a.y + (b.y - a.y) * e) + "px";

        var op = 1;
        if (el < 180) op = el / 180;
        if (el > END - 300) op = Math.max(0, (END - el) / 300);
        dot.style.opacity = op;

        if (!shieldHit && el >= 1400) { shieldHit = true; shieldWrap.classList.add("hit"); setTimeout(function(){ shieldWrap.classList.remove("hit"); }, 400); }

        if (rejected) {
          if (!flagged && el >= 1700) { flagged = true; dot.classList.add("rejected"); }
        } else {
          if (!dbHit && el >= 3000) { dbHit = true; dbIcon.classList.add("hit"); setTimeout(function(){ dbIcon.classList.remove("hit"); }, 450); }
          if (!cardHit && el >= END - 120) { cardHit = true; cards[target].classList.add("hit"); bumpCounter(); setTimeout(function(){ cards[target].classList.remove("hit"); }, 650); }
        }

        if (el < END) requestAnimationFrame(step);
        else dot.remove();
      }
      requestAnimationFrame(step);
    }

    // gentle continuous stream — users come and go, overlapping
    spawn();
    setInterval(function () {
      var burst = 1 + Math.floor(Math.random() * 2);   // 1–2 users per wave
      for (var n = 0; n < burst; n++) setTimeout(spawn, n * 320);
    }, 1400);
  }
})();
