/* ============================================================
   DAILY BONUS MAP
   - real-date driven: past days = claimed, today = red + claimable,
     future = locked. Months render exactly daysInMonth nodes (28–31).
   - node positions are % coords (serpentine); the golden route SVG is
     rebuilt from the same coords in pixel space, so path and nodes can
     never drift apart. Recomputed on resize / layout change.
   - today's claim persists in localStorage (np-bm-claim-YYYY-M-D).
   ============================================================ */
(function () {
  'use strict';

  /* ---------- date state ---------- */
  var now = new Date();
  var YEAR = now.getFullYear(), MONTH = now.getMonth(), TODAY = now.getDate();
  var DAYS = new Date(YEAR, MONTH + 1, 0).getDate();
  var MONTHS = ['January','February','March','April','May','June',
                'July','August','September','October','November','December'];
  var CLAIM_KEY = 'np-bm-claim-' + YEAR + '-' + MONTH + '-' + TODAY;

  /* rotating flavour prizes (demo): [prize, game, provider] */
  var PRIZES = [
    ['20 Free Spins', 'Big Bass Splash', 'Pragmatic Play'],
    ['10% Cashback', 'All Casino Games', 'National Play'],
    ['65 Free Spins', 'Wild Wild Bet', 'Mascot'],
    ['€5 Free Chip', 'Live Roulette', 'Evolution'],
    ['50 Free Spins', 'Gates of Olympus', 'Pragmatic Play'],
    ['50% Reload', 'All Casino Games', 'National Play'],
    ['Mystery Prize', 'Open to Reveal', 'National Play']
  ];

  /* ---------- serpentine coordinates (percent of map box) ----------
     31 slots, hand-jittered so the route reads organic, dodging the
     legend (bottom-left), Today panel + mascot (right side). */
  var DESK = [
    [8,45],[15,42],[23,41],[31,44],[38,46],[45,40],[52,34],[60,33],[67,34],        /* 1–9  → */
    [73,40],[78,48],[71,54],[63,52],[55,50],[49,52],[43,55],[36,61],[28,60],       /* 10–18 ← */
    [18,59],[13,66],[21,69],[29,66],[37,69],[46,73],[55,75],[64,73],[72,76],       /* 19–27 → */
    [65,83],[57,85],[49,83],[40,86]                                                /* 28–31 ← (clears legend + panel) */
  ];
  var MOB = [
    /* row 1 sits at y≥10 so the crowned "today" sprite never clips the map top */
    [13,10],[36,12],[60,10],[84,12],             /* 1–4  → */
    [90,25],[62,27],[35,25],[10,27],             /* 5–8  ← */
    [12,39],[40,42],[68,39],[90,42],             /* 9–12 → */
    [88,53],[60,56],[34,53],[10,56],             /* 13–16 ← */
    [12,64],[42,68],[70,64],[90,68],             /* 17–20 → */
    [84,76],[56,80],[30,76],[10,80],             /* 21–24 ← */
    [18,88],[48,92],[78,88],                     /* 25–27 → */
    [90,96],[62,99],[34,96],[10,99]              /* 28–31 ← */
  ];
  var MQ = window.matchMedia('(max-width:760px)');

  /* ---------- dom ---------- */
  var map = document.getElementById('bmpMap');
  if (!map) return;
  var nodesBox = document.getElementById('bmpNodes');
  var svg = document.getElementById('bmpPath');
  var pathDim = document.getElementById('bmpPathDim');
  var pathGold = document.getElementById('bmpPathGold');
  var monthEl = document.getElementById('bmpMonth');
  var todayCard = document.getElementById('bmpToday');
  var pop = document.getElementById('bmpPop');
  var modal = document.getElementById('bmpModal');

  monthEl.textContent = MONTHS[MONTH] + ' ' + YEAR;

  var claimed = false;
  try { claimed = !!localStorage.getItem(CLAIM_KEY); } catch (e) {}

  var CROWN = '<svg viewBox="0 0 24 24"><path d="M3.2 17.5 2 7.6l5 3.6L12 4l5 7.2 5-3.6-1.2 9.9H3.2zm.3 2.1h17c.4 0 .7.3.7.7v.5c0 .4-.3.7-.7.7h-17c-.4 0-.7-.3-.7-.7v-.5c0-.4.3-.7.7-.7z"/></svg>';

  /* ---------- today's promo card (bottom panel + node hover popup) ---------- */
  function pad2(n) { return (n < 10 ? '0' : '') + n; }

  function cardHTML() {
    var pr = PRIZES[(TODAY - 1) % PRIZES.length];
    return '<div class="btc-head"><div>' +
        '<span class="btc-date">' + pad2(TODAY) + '/' + pad2(MONTH + 1) + '/' + YEAR + '</span>' +
        '<span class="btc-cur">Current</span></div>' +
        '<a class="btc-tc" href="promotions.html">T&amp;C</a></div>' +
      '<div class="btc-prize"><img src="assets-new/bonus-map/chest.webp" alt="" /><div>' +
        '<b class="btc-title">Map Day ' + TODAY + '</b>' +
        '<span class="btc-name">' + pr[0] + '</span></div></div>' +
      '<div class="btc-game">in <a href="casino.html">' + pr[1] + '</a></div>' +
      '<div class="btc-prov">' + pr[2] + '</div>' +
      '<button class="bmp-claim" type="button"' + (claimed ? ' disabled' : '') + '>' +
        '<span>' + (claimed ? 'Activated — back tomorrow!' : CROWN + 'Claim Offer') + '</span></button>';
  }

  function renderCards() {
    todayCard.innerHTML = cardHTML();
    pop.innerHTML = cardHTML();
  }

  /* popup rides the today-node; clamped so it stays on the map */
  var popTimer = null;
  function showPop() {
    clearTimeout(popTimer);
    var c = coords()[TODAY - 1];
    var lo = MQ.matches ? 42 : 13, hi = MQ.matches ? 58 : 62;
    pop.style.left = Math.min(Math.max(c[0], lo), hi) + '%';
    if (c[1] > 42) { pop.style.top = (c[1] - 6) + '%'; pop.style.transform = 'translate(-50%,-100%)'; }
    else { pop.style.top = (c[1] + 6) + '%'; pop.style.transform = 'translate(-50%,0)'; }
    pop.hidden = false;
  }
  function hidePop() { popTimer = setTimeout(function () { pop.hidden = true; }, 200); }
  pop.addEventListener('mouseenter', function () { clearTimeout(popTimer); });
  pop.addEventListener('mouseleave', hidePop);

  /* ---------- build nodes ---------- */
  function coords() {
    var source = MQ.matches ? MOB : DESK;
    return source.map(function (p) {
      var y = MQ.matches ? 31 + p[1] * 0.66 : p[1];
      return [p[0], Math.min(MQ.matches ? 98.3 : 87, y)];
    });
  }

  function tipFor(d) {
    if (d < TODAY) return 'Day ' + d + ' · Claimed';
    if (d > TODAY) return 'Unlocks ' + MONTHS[MONTH] + ' ' + d;
    return '';   /* today gets the promo popup instead of a tooltip */
  }

  function build() {
    var c = coords();
    nodesBox.innerHTML = '';
    for (var d = 1; d <= DAYS; d++) {
      var b = document.createElement('button');
      b.type = 'button';
      b.dataset.day = d;
      b.style.left = c[d - 1][0] + '%';
      b.style.top = c[d - 1][1] + '%';
      var tip = tipFor(d);
      if (tip) b.setAttribute('data-tip', tip);
      b.innerHTML = '<span class="bn-num">' + d + '</span>';
      /* keep tooltips inside the map: flip below near the top edge,
         anchor inward near the left/right edges */
      var edge = '';
      if (c[d - 1][1] <= 13) edge += ' bmp-tip-below';
      if (c[d - 1][0] <= 18) edge += ' bmp-tip-l';
      else if (c[d - 1][0] >= 82) edge += ' bmp-tip-r';
      if (d < TODAY) {
        b.className = 'bmp-node is-claimed';
        b.setAttribute('aria-label', 'Day ' + d + ', claimed');
      } else if (d === TODAY) {
        b.className = 'bmp-node is-today' + (claimed ? ' is-done' : '');
        b.setAttribute('aria-label', 'Day ' + d + ', today' + (claimed ? ', claimed' : ', see today’s bonus'));
        b.addEventListener('mouseenter', showPop);
        b.addEventListener('mouseleave', hidePop);
        b.addEventListener('click', function () {
          if (pop.hidden) showPop(); else pop.hidden = true;
        });
      } else {
        b.className = 'bmp-node is-locked';
        b.setAttribute('aria-label', 'Day ' + d + ', locked');
        b.addEventListener('click', shake);
      }
      b.className += edge;
      nodesBox.appendChild(b);
    }
    drawPath();
  }

  /* ---------- route ---------- */
  function catmull(pts) {
    if (pts.length < 2) return '';
    var d = 'M' + pts[0][0].toFixed(1) + ' ' + pts[0][1].toFixed(1);
    for (var i = 0; i < pts.length - 1; i++) {
      var p0 = pts[Math.max(i - 1, 0)], p1 = pts[i],
          p2 = pts[i + 1], p3 = pts[Math.min(i + 2, pts.length - 1)];
      var c1x = p1[0] + (p2[0] - p0[0]) / 6, c1y = p1[1] + (p2[1] - p0[1]) / 6;
      var c2x = p2[0] - (p3[0] - p1[0]) / 6, c2y = p2[1] - (p3[1] - p1[1]) / 6;
      d += 'C' + c1x.toFixed(1) + ' ' + c1y.toFixed(1) + ',' +
                 c2x.toFixed(1) + ' ' + c2y.toFixed(1) + ',' +
                 p2[0].toFixed(1) + ' ' + p2[1].toFixed(1);
    }
    return d;
  }

  function drawPath() {
    var w = map.clientWidth, h = map.clientHeight;
    if (!w || !h) return;
    svg.setAttribute('viewBox', '0 0 ' + w + ' ' + h);
    var px = coords().slice(0, DAYS).map(function (p) {
      return [p[0] * w / 100, p[1] * h / 100];
    });
    pathDim.setAttribute('d', catmull(px.slice(TODAY - 1)));
    pathGold.setAttribute('d', catmull(px.slice(0, TODAY)));
    var sw = Math.max(6, Math.round(w / 140));
    pathDim.setAttribute('stroke-width', sw);
    pathGold.setAttribute('stroke-width', sw);
  }

  /* ---------- interactions ---------- */
  function shake(e) {
    var n = e.currentTarget;
    n.classList.remove('bmp-shake');
    void n.offsetWidth;
    n.classList.add('bmp-shake');
  }

  function claim() {
    if (claimed) return;
    claimed = true;
    try { localStorage.setItem(CLAIM_KEY, '1'); } catch (e) {}
    var todayNode = nodesBox.querySelector('.is-today');
    if (todayNode) {
      todayNode.classList.add('is-done', 'bmp-burst');
      todayNode.setAttribute('aria-label', 'Day ' + TODAY + ', today, offer activated');
    }
    renderCards();
  }

  /* claim CTA lives in the panel, the popup and the modal — delegate */
  document.addEventListener('click', function (e) {
    var btn = e.target.closest && e.target.closest('.bmp-claim');
    if (!btn) return;
    claim();
    if (btn.closest('.bmp-modal')) modal.classList.remove('open');
  });

  /* how-it-works modal */
  document.getElementById('bmpHowBtn').addEventListener('click', function () {
    modal.classList.add('open');
  });
  modal.addEventListener('click', function (e) {
    if (e.target === modal || e.target.closest('.bmp-modal-close')) modal.classList.remove('open');
  });
  document.addEventListener('keydown', function (e) {
    if (e.key === 'Escape') modal.classList.remove('open');
  });

  /* ---------- responsive ---------- */
  var ro = new ResizeObserver(drawPath);
  ro.observe(map);
  function onBreakpoint() { pop.hidden = true; build(); }
  MQ.addEventListener ? MQ.addEventListener('change', onBreakpoint) : MQ.addListener(onBreakpoint);

  renderCards();
  build();
})();
