/* ═══════════════════════════════════════════════════════════
   Contador de entregas — o mostrador de marketing.
   Lê o total acumulado em GET {API}/public/delivery-counter (backend do
   cerrado-express: uma linha só no banco, somada uma vez por dia) e anima
   os dígitos do zero até o total, rolo a rolo, no estilo caça-níquel.
   Depende de site-primitives.jsx (CE, Eyebrow).

   Uso:  <ContadorEntregas />                       (seção pronta)
         <Odometro valor={12345} />                 (só os rolos)
   ═══════════════════════════════════════════════════════════ */

var CE_API_URL = window.CE_API_URL || 'https://cerrado-express.onrender.com/api';
var CE_CONTADOR_CACHE = 'ce_entregas_total';
var CE_ROLO_H = 1.12; // altura de cada dígito, em "em" (deixa respiro para o glifo)

function ceLerCache() {
  try {
    var raw = localStorage.getItem(CE_CONTADOR_CACHE);
    if (!raw) return null;
    var j = JSON.parse(raw);
    return typeof j.total === 'number' ? j.total : null;
  } catch (e) { return null; }
}
function ceGravarCache(total) {
  try { localStorage.setItem(CE_CONTADOR_CACHE, JSON.stringify({ total: total, em: Date.now() })); } catch (e) {}
}
function ceReduzMovimento() {
  try { return window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches; } catch (e) { return false; }
}
/* Busca o total no backend; devolve Promise<number>. */
function ceBuscarTotal() {
  return fetch(CE_API_URL + '/public/delivery-counter', { headers: { Accept: 'application/json' } })
    .then(function(r) { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
    .then(function(j) {
      if (typeof j.total !== 'number') throw new Error('resposta sem total');
      return j.total;
    });
}

/* Um rolo (um dígito). Monta a faixa partindo do dígito anterior, dá `voltas`
   completas e para no dígito novo; a faixa começa parada no primeiro item e,
   quando `iniciar` liga, desliza até o último com uma curva que desacelera
   como o rolo de um caça-níquel. */
function Rolo({ digito, de, voltas, duracao, iniciar, semMovimento }) {
  var faixa = React.useMemo(function() {
    var arr = [];
    for (var d = de; d <= 9; d++) arr.push(d);
    for (var v = 0; v < voltas; v++) for (var k = 0; k <= 9; k++) arr.push(k);
    for (var f = 0; f <= digito; f++) arr.push(f);
    return arr;
  }, [digito, de, voltas]);
  var fim = faixa.length - 1;
  var st = React.useState(0), pos = st[0], setPos = st[1];

  React.useEffect(function() {
    if (semMovimento) { setPos(fim); return; }
    setPos(0);
    if (!iniciar) return;
    // dois quadros: o navegador pinta a posição 0 antes de a transição começar
    var r1 = requestAnimationFrame(function() { r1 = requestAnimationFrame(function() { setPos(fim); }); });
    return function() { cancelAnimationFrame(r1); };
  }, [faixa, fim, iniciar, semMovimento]);

  var animando = pos > 0 && !semMovimento;
  return (
    <span className="ce-rolo" style={{ position: 'relative', display: 'inline-block', height: CE_ROLO_H + 'em',
      minWidth: '.72em', padding: '0 .06em', overflow: 'hidden', textAlign: 'center',
      background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.13)', borderRadius: '.14em',
      boxShadow: 'inset 0 .08em .22em rgba(0,0,0,.45), inset 0 -.08em .22em rgba(0,0,0,.45)' }}>
      <span style={{ display: 'block', willChange: 'transform',
        transform: 'translateY(-' + (pos * CE_ROLO_H) + 'em)',
        transition: animando ? 'transform ' + duracao + 's cubic-bezier(.16,1,.3,1)' : 'none' }}>
        {faixa.map(function(d, i) {
          return <span key={i} style={{ display: 'block', height: CE_ROLO_H + 'em', lineHeight: CE_ROLO_H + 'em' }}>{d}</span>;
        })}
      </span>
      {/* sombra do cilindro: escurece o topo e a base do rolo */}
      <span aria-hidden="true" style={{ position: 'absolute', inset: 0, pointerEvents: 'none', borderRadius: 'inherit',
        background: 'linear-gradient(180deg, rgba(0,0,0,.42) 0%, rgba(0,0,0,0) 32%, rgba(0,0,0,0) 68%, rgba(0,0,0,.42) 100%)' }} />
    </span>
  );
}

/* Rolo girando sem parar — usado enquanto o total ainda não chegou. */
function RoloGirando() {
  var faixa = [0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9];
  return (
    <span className="ce-rolo" style={{ position: 'relative', display: 'inline-block', height: CE_ROLO_H + 'em',
      minWidth: '.72em', padding: '0 .06em', overflow: 'hidden', textAlign: 'center',
      background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.13)', borderRadius: '.14em',
      boxShadow: 'inset 0 .08em .22em rgba(0,0,0,.45), inset 0 -.08em .22em rgba(0,0,0,.45)' }}>
      <span style={{ display: 'block', animation: 'ceRoloGira .55s linear infinite' }}>
        {faixa.map(function(d, i) {
          return <span key={i} style={{ display: 'block', height: CE_ROLO_H + 'em', lineHeight: CE_ROLO_H + 'em', opacity: .55 }}>{d}</span>;
        })}
      </span>
      <span aria-hidden="true" style={{ position: 'absolute', inset: 0, pointerEvents: 'none', borderRadius: 'inherit',
        background: 'linear-gradient(180deg, rgba(0,0,0,.42) 0%, rgba(0,0,0,0) 32%, rgba(0,0,0,0) 68%, rgba(0,0,0,.42) 100%)' }} />
    </span>
  );
}

/* O painel de rolos. `valor` null = ainda carregando (rolos girando).
   `iniciar` segura a animação até a seção aparecer na tela. */
function Odometro({ valor, iniciar, digitosCarregando, fontSize, color }) {
  var anterior = React.useRef(0);
  var atual = React.useRef(0);
  if (valor != null && valor !== atual.current) { anterior.current = atual.current; atual.current = valor; }
  var semMovimento = ceReduzMovimento();

  var estilo = { fontFamily: CE.disp, fontWeight: 800, fontStyle: 'italic', fontVariantNumeric: 'tabular-nums',
    fontSize: fontSize || 'clamp(46px, 9vw, 104px)', lineHeight: 1, color: color || CE.sun, letterSpacing: '-.01em',
    display: 'inline-flex', alignItems: 'center', gap: '.07em', whiteSpace: 'nowrap' };

  if (valor == null) {
    var n = Math.max(3, digitosCarregando || 5), rolos = [];
    for (var i = 0; i < n; i++) rolos.push(<RoloGirando key={i} />);
    return <span style={estilo} aria-label="carregando">{rolos}</span>;
  }

  var str = Math.max(0, Math.round(valor)).toLocaleString('pt-BR');
  var digitosDe = String(Math.max(0, Math.round(anterior.current))).split('').map(Number); // só os dígitos, sem separador
  var totalDigitos = str.replace(/\D/g, '').length;
  var idx = 0; // índice do dígito, da esquerda para a direita
  return (
    <span style={estilo} aria-label={str + ' entregas realizadas'} role="img">
      {str.split('').map(function(ch, i) {
        if (!/\d/.test(ch)) {
          return <span key={'s' + i} style={{ opacity: .75, padding: '0 .02em' }}>{ch}</span>;
        }
        var posEsq = idx++;                         // 0 = dígito mais à esquerda
        var posDir = totalDigitos - 1 - posEsq;     // 0 = unidade
        var kDe = digitosDe.length - 1 - posDir;    // dígito anterior na mesma casa
        var de = kDe >= 0 ? digitosDe[kDe] : 0;
        return (
          <Rolo key={'d' + posDir} digito={Number(ch)} de={de}
            voltas={1 + posEsq}                      // rolos da direita rodam mais
            duracao={1.5 + posEsq * 0.35}            // ...e param por último
            iniciar={!!iniciar} semMovimento={semMovimento} />
        );
      })}
    </span>
  );
}

/* Seção pronta: faixa escura com o odômetro no centro. */
function ContadorEntregas({ eyebrow, titulo, legenda, id }) {
  var cache = ceLerCache();
  var stV = React.useState(cache), valor = stV[0], setValor = stV[1];
  var stE = React.useState(false), falhou = stE[0], setFalhou = stE[1];
  var stI = React.useState(false), visivel = stI[0], setVisivel = stI[1];
  var ref = React.useRef(null);

  // busca o total; se nada chegar em 25 s e não houver cache, a seção some
  React.useEffect(function() {
    var vivo = true, timer = null;
    ceBuscarTotal().then(function(t) {
      if (!vivo) return;
      ceGravarCache(t); setValor(t); if (timer) clearTimeout(timer);
    }).catch(function() { if (vivo && cache == null) setFalhou(true); });
    if (cache == null) timer = setTimeout(function() { if (vivo) setFalhou(true); }, 25000);
    return function() { vivo = false; if (timer) clearTimeout(timer); };
  }, []);

  // só começa a girar quando a seção entra na tela
  React.useEffect(function() {
    var el = ref.current;
    if (!el || !('IntersectionObserver' in window)) { setVisivel(true); return; }
    var io = new IntersectionObserver(function(entries) {
      if (entries.some(function(e) { return e.isIntersecting; })) { setVisivel(true); io.disconnect(); }
    }, { threshold: .35 });
    io.observe(el);
    return function() { io.disconnect(); };
  }, []);

  if (falhou && valor == null) return null;

  return (
    <section id={id || 'entregas'} ref={ref} style={{ position: 'relative', overflow: 'hidden',
      background: 'linear-gradient(168deg, ' + CE.blue900 + ' 0%, ' + CE.blue800 + ' 60%, ' + CE.blue + ' 100%)' }}>
      <style dangerouslySetInnerHTML={{ __html:
        '@keyframes ceRoloGira{from{transform:translateY(0)}to{transform:translateY(-' + (10 * CE_ROLO_H) + 'em)}}' +
        '@media (prefers-reduced-motion:reduce){.ce-rolo>span{animation:none!important;transition:none!important}}' }} />
      <div style={{ position: 'absolute', left: '-8%', top: '-40%', width: 560, height: 560, borderRadius: '50%',
        background: 'radial-gradient(circle, ' + CE.sun + ' 0%, transparent 62%)', opacity: .22 }} />
      <div style={{ position: 'relative', maxWidth: 1180, margin: '0 auto', padding: '64px 40px 68px', textAlign: 'center' }}>
        <Eyebrow light>{eyebrow || 'Entregas realizadas'}</Eyebrow>
        <h2 style={{ fontFamily: CE.disp, fontWeight: 800, textTransform: 'uppercase', fontSize: 34,
          color: '#fff', lineHeight: 1.05, margin: '12px 0 26px', letterSpacing: '-.01em' }}>
          {titulo || 'Cada número aqui é uma entrega feita.'}
        </h2>
        <Odometro valor={valor} iniciar={visivel}
          digitosCarregando={cache != null ? String(cache).length : 5} />
        <p style={{ fontFamily: CE.body, fontSize: 16, lineHeight: 1.6, color: CE.blue100, margin: '22px auto 0', maxWidth: 520 }}>
          {legenda || 'entregas realizadas pela Cerrado Express — e contando. O número é atualizado todos os dias.'}
        </p>
      </div>
      <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 6, display: 'flex' }}>
        <div style={{ flex: 2, background: CE.rust }} />
        <div style={{ flex: 1, background: CE.sun }} />
        <div style={{ flex: 4, background: CE.blue700 }} />
      </div>
    </section>
  );
}

Object.assign(window, { ContadorEntregas, Odometro });
