/* Replaces the original bundle.js.
 *
 * Differences from the original:
 *   - one spin instead of two (grape stage only), prize fixed at USD 168
 *   - no GTM / dataLayer, no aft fingerprinting, no DataDome, no rps-helper
 *   - no FormGenerator: the modal is a single button that opens the offer link
 *   - the offer link is read from link.php at runtime, so the admin panel can
 *     change it without touching any file the visitor downloads
 */
(function () {
  'use strict';

  var SPIN_MS = 3600;        // one full wheel rotation
  var GIF_IN_MS = 1000;      // flying grape appears
  var GIF_NUM_MS = 2000;     // its amount appears
  var SETTLE_MS = 4000;      // amount lands in the side panel
  var MODAL_MS = 5600;       // claim modal opens

  var main = document.getElementById('run-circle');
  var spinner = document.querySelector('.main__spinner');
  var button = document.querySelector('.main__button');
  var bonus = document.querySelector('.main__bonus');
  var grape = document.querySelector('.main__bonus-grape');
  var grapeGif = document.querySelector('.main__bonus-grape-gif');
  var grapeGifNum = document.querySelector('.main__bonus-grape-gif-num');
  var modal = document.querySelector('.main__modal');
  var claim = document.getElementById('claim-btn');

  /* ---------------------------------------------------------------- the link
   * Whatever the visitor arrived with (?st=, s1..s5, p_id, pc …) is appended to
   * the offer link, otherwise sub-id attribution is lost the moment they click. */

  function withVisitorParams(url) {
    var search = window.location.search.replace(/^\?/, '');
    if (!search) return url;
    var hash = '';
    var h = url.indexOf('#');
    if (h !== -1) { hash = url.slice(h); url = url.slice(0, h); }
    return url + (url.indexOf('?') === -1 ? '?' : '&') + search + hash;
  }

  function setLink(url) {
    if (!url) return;
    claim.href = withVisitorParams(url);
  }

  // config.js is the no-PHP fallback (plain static hosting); link.php wins when
  // it answers, which is what the admin panel writes to.
  setLink(window.OFFER_LINK || 'https://example.com/');

  fetch('link.php', { cache: 'no-store' })
    .then(function (r) { return r.ok ? r.json() : null; })
    .then(function (d) { if (d && d.link) setLink(d.link); })
    .catch(function () { /* static hosting without PHP — config.js value stands */ });

  /* ------------------------------------------------------------ text sizing
     The prize used to be a PNG of the literal amount, so main.css sizes those
     elements by height at each breakpoint. Derive the font size from that
     rendered height instead of duplicating every media query. */

  function fitText() {
    var num = document.getElementById('grape-num');
    if (num && num.clientHeight) {
      num.style.fontSize = num.clientHeight + 'px';
      num.style.lineHeight = num.clientHeight + 'px';
    }
    if (grapeGifNum && grapeGifNum.clientHeight) {
      grapeGifNum.style.fontSize = grapeGifNum.clientHeight + 'px';
      grapeGifNum.style.lineHeight = grapeGifNum.clientHeight + 'px';
    }
    // Zero the padding first so the measurement is the panel's own CSS width
    // and not width-plus-last-pass's-padding; then everything below scales off
    // that one number and stays idempotent across resizes.
    var title = document.querySelector('.kh-bonus__title');
    if (!bonus || !title) return;
    bonus.style.padding = '0px';
    var w = bonus.getBoundingClientRect().width;
    if (!w) return;
    bonus.style.padding = Math.round(w * 0.11) + 'px ' + Math.round(w * 0.13) + 'px ' + Math.round(w * 0.13) + 'px';

    // Shrink the heading until it fits on one line — Khmer words are long and
    // the panel is narrow, so a fixed ratio wraps at some breakpoints only.
    var size = Math.round(w * 0.15);
    title.style.whiteSpace = 'nowrap';
    title.style.fontSize = size + 'px';
    var avail = title.clientWidth;
    while (size > 8 && avail > 0 && title.scrollWidth > avail) {
      size -= 1;
      title.style.fontSize = size + 'px';
    }
  }

  /* Mobile browsers report 100vh as the pre-toolbar height; the original bundle
     pinned the real innerHeight instead. Same trick here. */
  function fitViewport() {
    var h = document.body.clientWidth < 479 ? window.innerHeight + 'px' : '100vh';
    document.body.style.minHeight = h;
    main.style.minHeight = h;
    var container = document.querySelector('.main__container');
    if (container) container.style.minHeight = h;
  }

  function relayout() { fitViewport(); fitText(); }

  window.addEventListener('resize', relayout);
  window.addEventListener('orientationchange', relayout);
  relayout();

  /* -------------------------------------------------------------- the spin */

  function openModal() {
    if (grapeGif) grapeGif.classList.add('hide');
    modal.classList.add('main__modal_show');
    main.scrollTo(0, 0);
    main.style.overflow = 'hidden';
  }

  var spun = false;

  main.addEventListener('click', function () {
    if (spun) return;
    spun = true;

    button.style.pointerEvents = 'none';
    button.style.cursor = 'default';

    spinner.classList.remove('stage-1');
    spinner.classList.add('spin-to-stage-two');

    setTimeout(function () {
      spinner.classList.remove('spin-to-stage-two');
      spinner.classList.add('stage-1', 'stage-1-complete');
      bonus.classList.remove('hide');
      fitText();

      setTimeout(function () { grapeGif.classList.remove('hide'); }, GIF_IN_MS);
      setTimeout(function () { grapeGifNum.classList.remove('hide'); fitText(); }, GIF_NUM_MS);
      setTimeout(function () {
        grapeGifNum.classList.add('hide');
        grape.classList.remove('hide');
        button.classList.add('hide');
        fitText();
      }, SETTLE_MS);
      setTimeout(openModal, MODAL_MS);
    }, SPIN_MS);
  });
})();
