// -------------------------------------------------------------------------
// DASHBOARD NUMEROS
//
// Destino: /lp/components/dashboard.jsx
// Protótipo: lab/protos/dashboard-numeros.html · Ficha: refs/dashboard-numeros/ficha.md
// GERADO por tools/portar.py — edite o protótipo e rode de novo.
//
// Ícones: use `ID` (window.Icon), já aliasado no topo de dashboard.jsx.
// Tudo vive numa IIFE porque os arquivos de /lp/components/ dividem o
// mesmo escopo global — nomes soltos colidem entre si.
// -------------------------------------------------------------------------

(function () {
  // Série de exemplo do painel do lojista (30 dias). Não é métrica agregada do
  // cartROI — é a tela que o lojista vê, no mesmo enquadramento do LiveROICounter.
  const SERIE = [18,22,19,26,31,28,35,33,41,38,46,52,49,58,55,63,71,68,76,82,79,88,95,91,104,112,108,121,118,128];
  const FATURAMENTO = 128470.00;
  const PEDIDOS = 1284;
  const VARIACAO = 42;
  const TICKET = FATURAMENTO / PEDIDOS;

  const brl = (v) => v.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  const int = (v) => Math.round(v).toLocaleString('pt-BR');

  function useReduced() {
    const [r, setR] = React.useState(false);
    React.useEffect(() => {
      if (!window.matchMedia) return;
      const mq = window.matchMedia('(prefers-reduced-motion: reduce)');
      setR(mq.matches);
      const on = (e) => setR(e.matches);
      mq.addEventListener ? mq.addEventListener('change', on) : mq.addListener(on);
      return () => { mq.removeEventListener ? mq.removeEventListener('change', on) : mq.removeListener(on); };
    }, []);
    return r;
  }

  // Dispara uma vez, quando entra em viewport. Mesmo espírito do .reveal do site.
  function useUmaVez(threshold = 0.4) {
    const ref = React.useRef(null);
    const [dentro, setDentro] = React.useState(false);
    React.useEffect(() => {
      const el = ref.current; if (!el) return;
      const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) { setDentro(true); io.disconnect(); } }, { threshold });
      io.observe(el); return () => io.disconnect();
    }, [threshold]);
    return [ref, dentro];
  }

  function useContagem(alvo, rodar, dur = 1600, atraso = 0) {
    const [v, setV] = React.useState(0);
    React.useEffect(() => {
      if (!rodar) return;
      let raf, t0 = null;
      const inicio = performance.now() + atraso;
      const tick = (t) => {
        if (t < inicio) { raf = requestAnimationFrame(tick); return; }
        if (t0 === null) t0 = t;
        const p = Math.min(1, (t - t0) / dur);
        setV(alvo * (1 - Math.pow(1 - p, 3)));       // easeOutCubic
        if (p < 1) raf = requestAnimationFrame(tick);
      };
      raf = requestAnimationFrame(tick);
      return () => cancelAnimationFrame(raf);
    }, [alvo, rodar, dur, atraso]);
    return v;
  }

  function Grafico({ rodar, reduzido }) {
    const W = 520, H = 190, PAD = 8;
    const { linha, area } = React.useMemo(() => {
      const max = Math.max(...SERIE), min = Math.min(...SERIE);
      const pts = SERIE.map((v, i) => {
        const x = PAD + (i / (SERIE.length - 1)) * (W - PAD * 2);
        const y = H - PAD - ((v - min) / (max - min)) * (H - PAD * 2);
        return [x, y];
      });
      // Curva suave por Catmull-Rom convertida em cúbicas de Bézier.
      let d = `M${pts[0][0]},${pts[0][1]}`;
      for (let i = 0; i < pts.length - 1; i++) {
        const p0 = pts[i - 1] || pts[i], p1 = pts[i], p2 = pts[i + 1], p3 = pts[i + 2] || p2;
        d += ` C${p1[0] + (p2[0] - p0[0]) / 6},${p1[1] + (p2[1] - p0[1]) / 6}` +
             ` ${p2[0] - (p3[0] - p1[0]) / 6},${p2[1] - (p3[1] - p1[1]) / 6} ${p2[0]},${p2[1]}`;
      }
      return { linha: d, area: `${d} L${pts[pts.length - 1][0]},${H} L${pts[0][0]},${H} Z` };
    }, []);

    const desenhar = rodar || reduzido;
    return (
      <svg viewBox={`0 0 ${W} ${H}`} className="w-full" role="img" aria-label="Faturamento dos últimos 30 dias, em alta">
        <defs>
          <linearGradient id="areaGrad" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="#a78bfa" stopOpacity="0.42" />
            <stop offset="100%" stopColor="#a78bfa" stopOpacity="0" />
          </linearGradient>
          <linearGradient id="linhaGrad" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0%" stopColor="#a78bfa" /><stop offset="100%" stopColor="#22d3ee" />
          </linearGradient>
        </defs>

        {[0.25, 0.5, 0.75].map((f) => (
          <line key={f} x1="0" x2={W} y1={H * f} y2={H * f} stroke="rgba(255,255,255,.06)" strokeWidth="1" />
        ))}

        <path d={area} fill="url(#areaGrad)"
          style={{ opacity: desenhar ? 1 : 0, transition: 'opacity .9s ease .55s' }} />
        <path d={linha} fill="none" stroke="url(#linhaGrad)" strokeWidth="2.5"
          strokeLinecap="round" strokeLinejoin="round"
          pathLength="1"
          style={{
            strokeDasharray: 1,
            strokeDashoffset: desenhar ? 0 : 1,
            transition: reduzido ? 'none' : 'stroke-dashoffset 1.5s cubic-bezier(.2,.7,.2,1)',
          }} />
      </svg>
    );
  }

  function DashboardNumeros() {
    const reduzido = useReduced();
    const [ref, dentro] = useUmaVez(0.35);
    const rodar = dentro && !reduzido;

    const fat = useContagem(FATURAMENTO, rodar, 1700);
    const ped = useContagem(PEDIDOS, rodar, 1700, 120);
    const varia = useContagem(VARIACAO, rodar, 1200, 260);
    const tick = useContagem(TICKET, rodar, 1700, 200);

    const V = (calc, alvo) => (reduzido ? alvo : calc);

    return (
      <section ref={ref} className="relative overflow-hidden bg-ink py-20 lg:py-28">
        <div className="absolute inset-0 -z-10">
          <div className="mesh-blob bg-violet-700/50 w-[520px] h-[520px] -top-32 right-0 animate-drift1"></div>
          <div className="mesh-blob bg-cyan-400/20 w-[380px] h-[380px] bottom-0 left-1/4 animate-drift3"></div>
          <div className="absolute inset-0 dot-grid opacity-[0.16]"></div>
        </div>

        <div className="mx-auto grid max-w-7xl items-center gap-14 px-6 lg:grid-cols-[1fr_1.15fr] lg:gap-16 lg:px-10">
          <div className="reveal">
            <div className="inline-flex items-center gap-2 rounded-full border border-violet-300/20 bg-violet-500/10 px-3 py-1.5 text-[12px] font-medium text-violet-200">
              <span className="h-1.5 w-1.5 rounded-full bg-cyan-400"></span> Painel do lojista
            </div>
            <h2 className="mt-5 text-4xl font-semibold leading-[1.05] tracking-[-0.03em] sm:text-5xl">
              O número que importa,<br /><span className="grad-cyan">atualizado ao vivo.</span>
            </h2>
            <p className="mt-6 max-w-lg text-lg leading-relaxed text-violet-100/70">
              Faturamento, pedidos, ticket médio e taxa de aprovação no mesmo painel —
              por gateway, por método de pagamento e por público PF ou PJ.
            </p>
            <div className="mt-7 flex flex-wrap gap-x-5 gap-y-2 text-[13px] text-violet-200/70">
              <span>Sem planilha</span><span className="text-violet-200/20">·</span>
              <span>Sem esperar D+1</span><span className="text-violet-200/20">·</span>
              <span>Exportável</span>
            </div>
          </div>

          {/* Card do painel */}
          <div className="reveal">
            <div className="relative rounded-3xl border border-white/10 bg-[#15102a]/90 p-6 shadow-card backdrop-blur-xl lg:p-7">
              <div className="pointer-events-none absolute -right-16 -top-20 h-52 w-52 rounded-full bg-violet-600/25 blur-3xl"></div>

              <div className="relative flex items-start justify-between">
                <div>
                  <div className="text-[11px] uppercase tracking-[0.16em] text-violet-200/45">
                    Faturamento · últimos 30 dias
                  </div>
                  <div className="mt-1.5 flex items-baseline gap-3">
                    <span className="text-[38px] font-semibold leading-none tracking-[-0.035em] tabular-nums text-white lg:text-[44px]">
                      R$ {brl(V(fat, FATURAMENTO))}
                    </span>
                    <span className="flex items-center gap-1 rounded-full bg-emerald-400/12 px-2 py-1 text-[12px] font-medium text-emerald-300">
                      <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
                        <polyline points="4 16 10 9 14 13 20 6"/><polyline points="20 11 20 6 15 6"/>
                      </svg>
                      {Math.round(V(varia, VARIACAO))}%
                    </span>
                  </div>
                </div>
                <span className="hidden items-center gap-1.5 rounded-full border border-cyan-300/25 bg-cyan-400/5 px-2.5 py-1 text-[10.5px] font-mono text-cyan-200/80 sm:flex">
                  <span className="h-1.5 w-1.5 rounded-full bg-cyan-400 animate-pulse"></span> ao vivo
                </span>
              </div>

              <div className="relative mt-5"><Grafico rodar={rodar} reduzido={reduzido} /></div>

              <div className="relative -mt-1 flex justify-between font-mono text-[10px] text-violet-200/35">
                {['12/07','19/07','26/07','02/08','09/08'].map((d) => <span key={d}>{d}</span>)}
              </div>

              <div className="relative mt-6 grid grid-cols-3 gap-3 border-t border-white/8 pt-5">
                {[
                  { l: 'Pedidos', v: int(V(ped, PEDIDOS)) },
                  { l: 'Ticket médio', v: `R$ ${brl(V(tick, TICKET))}` },
                  { l: 'Aprovação', v: '96,4%' },
                ].map((m) => (
                  <div key={m.l}>
                    <div className="text-[10.5px] uppercase tracking-[0.12em] text-violet-200/40">{m.l}</div>
                    <div className="mt-1 text-[17px] font-semibold tabular-nums text-white lg:text-[19px]">{m.v}</div>
                  </div>
                ))}
              </div>
            </div>

            <p className="mt-4 font-mono text-[11px] text-violet-200/35">
              Tela ilustrativa do painel. Os números são de uma loja de exemplo.
            </p>
          </div>
        </div>
      </section>
    );
  }

  setTimeout(() => window.__attachReveal && window.__attachReveal(), 50);

  Object.assign(window, { DashboardNumeros });
})();
