// J.A.V.A · Catálogo · App principal
const { useState, useMemo, useEffect, useRef } = React;

const PRODUCTS = window.JAVA_PRODUCTS;
const LINES = window.JAVA_LINES;
const RESTR = window.JAVA_RESTRICTIONS;
const RESTR_FILTERS = window.JAVA_RESTR_FILTERS;
const NUTRI = window.JAVA_NUTRI || {};

// ─── Packaging map ────────────────────────────────────────
// A embalagem vem do próprio tamanho (data.js, campo `embalagem` — junto do
// SKU/EAN reais do ERP). O fallback por label cobre dados antigos sem o campo.
function packagingFor(size) {
  if (size.embalagem) return size.embalagem;
  if (size.label === 'Tablete') return 'caixa com 6 unidades';
  if (size.label === 'Mini' || size.label === 'Mini recheado') return 'caixa com 10 unidades';
  return '';
}

// ─── Top bar ───────────────────────────────────────────────
function TopBar({ variant, onPedidoRapido }) {
  return (
    <header className="topbar interactive-only">
      <div className="brand">
        <img
          src="assets/logo-brown.png"
          alt="Java chocolates"
          className="brand-logo"
          style={{ filter: variant === 'premium' ? 'invert(1) hue-rotate(180deg)' : 'none' }} />
        
      </div>
      <nav>
        <a href="#produtos">Catálogo</a>
        <a href="#comparador">Comparador</a>
        <a href="#contato">Contato</a>
      </nav>
      <div className="actions">
        <a
          className="btn ghost"
          href={typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(max-width: 700px)').matches ? 'catalogo-pdf-mobile-print.html' : 'catalogo-pdf-print.html'}
          target="_blank"
          rel="noopener noreferrer">
          Baixar PDF
        </a>
        <button className="btn primary" type="button" onClick={onPedidoRapido}>⚡ Orçamento rápido</button>
        <a className="btn ghost" href="#contato">Contato</a>
      </div>
    </header>);

}

// ─── Cover ─────────────────────────────────────────────────
function Cover() {
  return (
    <section className="cover" data-screen-label="01 Capa">
      <div className="cover-text">
        <div className="meta">
          <span>Catálogo de revenda</span>
          <span>Indústria brasileira</span>
        </div>
        <div>
          <h1 className="cover-h1" style={{ fontFamily: '"Fira Sans"', lineHeight: '0.95', fontWeight: 900 }}>
            Do <em style={{ fontWeight: 900 }}>cacau</em><br />à barra.
          </h1>
          <p className="subtitle">
            Fazemos chocolate de origem, bean to bar – do cacau à barra, usando ingredientes naturais
            de alta qualidade e com rastreabilidade. Seguimos rigorosamente as boas práticas de
            fabricação, incluindo o controle de alergênicos. Aqui, todos os chocolates são zero
            lactose, zero glúten. Tão importante quanto ser gostoso, é ser seguro.
          </p>
        </div>
        <div className="cover-footnote">
          <span>Cacau de Origem</span>
          <span>Sem glúten</span>
          <span>Sem leite</span>
        </div>
      </div>
      <div className="cover-img">
        <img src="assets/img/cover-cacau.jpg" alt="" />
      </div>
    </section>);

}

// ─── Sumário ───────────────────────────────────────────────
function Sumario({ onJumpFilter }) {
  const counts = useMemo(
    () => Object.fromEntries(LINES.map((l) => [l.id, PRODUCTS.filter((p) => p.line === l.id).length])),
    []
  );
  return (
    <section id="sumario" className="sumario" data-screen-label="02 Sumário">
      <div className="shell">
        <div className="symbol-bar" aria-label="Certificações e atributos">
          <div className="sym">
            <svg viewBox="0 0 56 56" width="40" height="40" aria-hidden="true">
              <circle cx="28" cy="28" r="26" fill="none" stroke="currentColor" strokeWidth="2" />
              <path d="M20 18 h16 l-2 6 c2 2 3 5 3 9 v9 a4 4 0 0 1 -4 4 h-10 a4 4 0 0 1 -4 -4 v-9 c0 -4 1 -7 3 -9 z" fill="none" stroke="currentColor" strokeWidth="2" strokeLinejoin="round" />
              <line x1="10" y1="46" x2="46" y2="10" stroke="currentColor" strokeWidth="2.5" />
            </svg>
            <span>Sem leite</span>
          </div>
          <div className="sym">
            <svg viewBox="0 0 56 56" width="40" height="40" aria-hidden="true">
              <circle cx="28" cy="28" r="26" fill="none" stroke="currentColor" strokeWidth="2" />
              <path d="M28 14 v28 M22 20 c4 2 6 6 6 10 M34 20 c-4 2 -6 6 -6 10 M22 28 c4 2 6 6 6 10 M34 28 c-4 2 -6 6 -6 10" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
              <line x1="10" y1="46" x2="46" y2="10" stroke="currentColor" strokeWidth="2.5" />
            </svg>
            <span>Sem glúten</span>
          </div>
          <div className="sym">
            <svg viewBox="0 0 56 56" width="40" height="40" aria-hidden="true">
              <circle cx="28" cy="28" r="26" fill="none" stroke="currentColor" strokeWidth="2" />
              <path d="M28 18 c-8 0 -12 6 -12 12 c0 6 4 10 12 10 c8 0 12 -4 12 -10 c0 -6 -4 -12 -12 -12 z M28 18 v22 M21 28 c0 -3 2 -6 7 -6 M35 28 c0 -3 -2 -6 -7 -6" fill="none" stroke="currentColor" strokeWidth="2" strokeLinejoin="round" />
            </svg>
            <span>Vegano</span>
          </div>
        </div>
        <div className="grid">
          <div>
            <div className="section-eyebrow">Nossos produtos</div>
            <h2 className="sumario-h2">Chocolates de verdade.</h2>
            <p className="lead lead-italic" style={{ marginTop: 24, maxWidth: '32ch' }}>
              Atenda vários públicos com uma só marca: gourmet, veganos, fitness e alérgicos.
              Solução completa para sua loja: barrinhas de 20g perfeitas para o caixa e barras
              de 65g para levar.
            </p>
          </div>
          <div className="toc">
            {LINES.map((l, i) =>
            <div className="toc-row" key={l.id} onClick={() => onJumpFilter(l.id)}>
                <div className="num">0{i + 1}</div>
                <div>
                  <div className="name">{l.label}</div>
                  <div className="sub">{l.sub}</div>
                </div>
                <div className="count">{counts[l.id]} produtos</div>
              </div>
            )}
            <div className="toc-row toc-row-todos" onClick={() => onJumpFilter(null)}>
              <div className="num">0{LINES.length + 1}</div>
              <div>
                <div className="name">Todos</div>
                <div className="sub">Catálogo completo</div>
              </div>
              <div className="count">{PRODUCTS.length} produtos</div>
            </div>
          </div>
        </div>
      </div>
    </section>);

}

// ─── Filters ───────────────────────────────────────────────
function Filters({ line, setLine, cacau, setCacau, size, setSize, restr, setRestr, onlyBest, setOnlyBest, count }) {
  const cacauBins = [
  { id: 'all', label: 'Todos' },
  { id: '0-50', label: 'até 50%' },
  { id: '50-70', label: '50 – 70%' },
  { id: '70-85', label: '70 – 85%' },
  { id: '85-100', label: '85% +' }];
  const sizeBins = [
  { id: 'all', label: 'Todos' },
  { id: 'tablete', label: 'Tablete 65g' },
  { id: 'mini', label: 'Mini 20–25g' }];

  return (
    <div className="filters">
      <div className="grp">
        <span className="grp-label">Destaques</span>
        <button
          className={`chip chip-best ${onlyBest ? 'active' : ''}`}
          onClick={() => setOnlyBest(!onlyBest)}>
          
          ★ mais vendidos
        </button>
      </div>
      <div className="grp">
        <span className="grp-label">Linha</span>
        <button className={`chip ${!line ? 'active' : ''}`} onClick={() => setLine(null)}>todas</button>
        {LINES.map((l) =>
        <button
          key={l.id}
          className={`chip ${line === l.id ? 'active' : ''}`}
          onClick={() => setLine(l.id)}>
          
            {l.label.toLowerCase()}
          </button>
        )}
      </div>
      <div className="grp">
        <span className="grp-label">% cacau</span>
        {cacauBins.map((b) =>
        <button key={b.id} className={`chip ${cacau === b.id ? 'active' : ''}`} onClick={() => setCacau(b.id)}>
            {b.label}
          </button>
        )}
      </div>
      <div className="grp">
        <span className="grp-label">Tamanho</span>
        {sizeBins.map((b) =>
        <button key={b.id} className={`chip ${size === b.id ? 'active' : ''}`} onClick={() => setSize(b.id)}>
            {b.label}
          </button>
        )}
      </div>
      <div className="grp">
        <span className="grp-label">Restrições</span>
        {RESTR_FILTERS.map((f) =>
        <button
          key={f.id}
          className={`chip ${restr.includes(f.id) ? 'active' : ''}`}
          onClick={() => setRestr(restr.includes(f.id) ? restr.filter((x) => x !== f.id) : [...restr, f.id])}>
              {f.label}
            </button>
        )}
      </div>
      <button className="reset" onClick={() => {setLine(null);setCacau('all');setSize('all');setRestr([]);setOnlyBest(false);}}>
        ↺ limpar  ·  {count} mostrados
      </button>
    </div>);

}

// ─── Card ──────────────────────────────────────────────────
function Card({ p, onOpen, compareIds, toggleCompare, orcamentoIds, toggleOrcamento }) {
  const isCompared = compareIds.includes(p.id);
  const isInOrc = orcamentoIds.includes(p.id);
  return (
    <div className="card" onClick={() => onOpen(p)} role="button" tabIndex={0}
    onKeyDown={(e) => {if (e.key === 'Enter' || e.key === ' ') {e.preventDefault();onOpen(p);}}}>
      <div
        className={`photo ${p.img ? '' : 'placeholder'}`}
        style={p.placeholder ? { '--placeholder-tone': p.placeholder.tone } : {}}>
        
        {p.img ?
        <img src={p.img} alt={p.name} loading="lazy" /> :
        <div className="ph-label">{p.placeholder?.label || p.name}</div>}
        {p.status === 'novo' && <div className="badge-new">Novo</div>}
        {p.bestseller && <div className="badge-best" title="Mais vendido">★</div>}
      </div>

      <div className="card-actions">
        <button
          className={`mini-btn ${isCompared ? 'active' : ''}`}
          onClick={(e) => {e.stopPropagation();toggleCompare(p.id);}}
          title="Comparar">
          
          {isCompared ? '✓' : '⇆'} comparar
        </button>
        <button
          className={`mini-btn primary ${isInOrc ? 'active' : ''}`}
          onClick={(e) => {e.stopPropagation();toggleOrcamento(p.id);}}
          title="Adicionar ao orçamento">
          
          {isInOrc ? '✓ no orçamento' : '+ orçamento'}
        </button>
      </div>

      <div>
        <div className="meta">
          <span className="pct">{p.cacauLabel || `${p.cacau}% cacau`}</span>
        </div>
        <h3 style={{ marginTop: 6 }}>{p.name}</h3>
        <div className="family">{p.family}</div>
        <div className="sizes">
          {p.sizes.map((s) =>
          <span className="sz" key={s.label}>{s.label} · {s.g}g</span>
          )}
        </div>
      </div>
    </div>);

}

// ─── Sheet (detail) ────────────────────────────────────────
function Sheet({ product, onClose, onCompare, compareIds, onOrcamento, orcamentoIds, onVerOrcamento }) {
  const p = product;
  useEffect(() => {
    const onEsc = (e) => e.key === 'Escape' && onClose();
    window.addEventListener('keydown', onEsc);
    document.body.style.overflow = 'hidden';
    return () => {window.removeEventListener('keydown', onEsc);document.body.style.overflow = '';};
  }, []);
  const placeholderStyle = p.placeholder ? { '--placeholder-tone': p.placeholder.tone } : {};

  const nutri = NUTRI[p.id];

  return (
    <div className="sheet-backdrop interactive-only" onClick={onClose}>
      <aside className="sheet" onClick={(e) => e.stopPropagation()}>
        <div className="sheet-head" style={placeholderStyle}>
          {p.img ? <img src={p.img} alt="" /> : <div className="placeholder">{p.placeholder?.label || p.name}</div>}
          <button className="close" onClick={onClose} aria-label="Fechar">✕</button>
        </div>
        <div className="sheet-body">
          <div>
            <div className="pct">{p.cacauLabel ? p.cacauLabel : `${p.cacau}% cacau`} · {p.family}</div>
            <h2>{p.name}</h2>
          </div>

          <p className="desc">{p.description}</p>

          {p.origin &&
          <div>
              <div className="block-title">Origem</div>
              <div style={{ fontSize: 15 }}>{p.origin}</div>
            </div>
          }

          <div>
            <div className="block-title">Embalagens · 2026</div>
            <div className="skus">
              {p.sizes.map((s) =>
              <div className="sku-row" key={s.label}>
                  <span className="label">{s.label}</span>
                  <span className="gram"><span className="new">{s.g}g</span></span>
                  <span className="pack">{packagingFor(s)}</span>
                </div>
              )}
            </div>
          </div>

          <div>
            <div className="block-title">Restrições e certificações</div>
            <div className="restrictions-list">
              {p.restrictions.map((r) => {
                const d = RESTR.find((x) => x.id === r);
                return <span className="r" key={r}>{d?.label || r}</span>;
              })}
            </div>
          </div>

          {nutri ?
          <>
              <div>
                <div className="block-title">Ingredientes</div>
                <p className="desc" style={{ margin: 0 }}>{nutri.ingredientes}</p>
              </div>
              <div>
                <div className="block-title">Alérgicos</div>
                <p className="desc" style={{ margin: 0 }}>{nutri.alergicos}</p>
              </div>
              <div>
                <div className="block-title">Informação nutricional</div>
                <div style={{ fontSize: 12, color: 'var(--fg-soft)', marginBottom: 8 }}>
                  Porções por embalagem: <strong>{nutri.porcoes}</strong>
                  {'  ·  '}
                  Porção: <strong>{nutri.porcaoG} g</strong> ({nutri.porcaoDesc})
                </div>
                <div className="nutri">
                  <table>
                    <thead>
                      <tr>
                        <th></th>
                        <th style={{ textAlign: 'right' }}>100 g</th>
                        <th style={{ textAlign: 'right' }}>{nutri.porcaoG} g</th>
                        <th style={{ textAlign: 'right' }}>%VD*</th>
                      </tr>
                    </thead>
                    <tbody>
                      {nutri.rows.map((r) =>
                    <tr key={r.k}>
                          <th>{r.k}</th>
                          <td className="val">{r.p100}</td>
                          <td className="val">{r.ps}</td>
                          <td className="val">{r.vd}</td>
                        </tr>
                    )}
                    </tbody>
                  </table>
                  <div style={{ fontSize: 10, color: 'var(--fg-soft)', marginTop: 8, lineHeight: 1.5 }}>
                    *Percentual de valores diários fornecidos pela porção, com base em uma dieta de 2.000 kcal ou 8.400 kJ. Seus valores diários podem ser maiores ou menores dependendo de suas necessidades energéticas.
                    {nutri.rows.some((r) => r.k.includes('Polióis')) && <><br />**Valor diário não estabelecido.</>}
                  </div>
                </div>
              </div>
            </> :

          <div>
              <div className="block-title">Informação nutricional</div>
              <div style={{ padding: '16px', border: '1px dashed var(--rule)', borderRadius: 4, color: 'var(--fg-soft)', fontSize: 13, lineHeight: 1.5 }}>
                Informações nutricionais e lista de ingredientes em atualização. Consulte a embalagem para os valores oficiais.
              </div>
            </div>
          }

          <div className="sheet-actions">
            <button className="btn" onClick={() => onCompare(p.id)}>
              {compareIds.includes(p.id) ? '✓ no comparador' : '⇆ comparar'}
            </button>
            <button className="btn primary" onClick={() => onOrcamento(p.id)}>
              {orcamentoIds.includes(p.id) ? '✓ no orçamento' : '+ adicionar ao orçamento'}
            </button>
          </div>
        </div>
        {/* Saídas da ficha (celular): voltar ao catálogo OU ir direto ao orçamento —
            quem chegou aqui pelo link "ver no catálogo" precisa do caminho de volta. */}
        <div className="fab-dupla">
          <button className="fab fab-catalogo" type="button" onClick={onClose}>
            📖 Ver catálogo
          </button>
          {onVerOrcamento &&
            <button className="fab fab-orcamento" type="button" onClick={onVerOrcamento}
              title="Voltar ao orçamento — suas quantidades ficam guardadas">
              🧾 Ver orçamento
            </button>
          }
        </div>
      </aside>
    </div>);

}

// ─── Comparator ────────────────────────────────────────────
function Comparator({ ids, setIds }) {
  const items = ids.map((id) => PRODUCTS.find((p) => p.id === id)).filter(Boolean);
  const slots = Math.max(3, items.length);

  return (
    <section id="comparador" className="comparator interactive-only" data-screen-label="Comparador">
      <div className="shell">
        <h2>Comparador</h2>
        <p className="hint">Adicione produtos pelo botão <strong>⇆ comparar</strong> em cada card. Compare até 4 lado a lado.</p>

        <div className="table" style={{ '--cols': slots }}>
          <div className="cell field" style={{ background: 'transparent', borderBottom: '1px solid var(--rule)' }}> </div>
          {Array.from({ length: slots }).map((_, i) => {
            const p = items[i];
            if (!p) return (
              <div className="empty-slot" key={'empty' + i} style={{ borderBottom: '1px solid var(--rule)', height: '100%' }}>
                Slot vazio
              </div>);

            return (
              <div key={p.id} className="cell" style={{ padding: 0, position: 'relative' }}>
                <button className="remove" onClick={() => setIds(ids.filter((x) => x !== p.id))}>×</button>
                {p.img ?
                <img src={p.img} alt="" style={{ aspectRatio: '4/3', width: '100%', objectFit: 'cover' }} /> :
                <div className="photo ph" style={{ aspectRatio: '4/3', display: 'flex', alignItems: 'center', justifyContent: 'center', background: p.placeholder?.tone, color: 'var(--cream)', fontFamily: 'var(--font-display)', fontSize: 18, padding: 16, textAlign: 'center' }}>
                      {p.placeholder?.label || p.name}
                    </div>}
              </div>);

          })}

          {comparatorRow('Produto', items, slots, (p) =>
          <div>
              <div style={{ fontFamily: 'var(--font-display)', fontSize: 20, fontWeight: 500 }}>{p.name}</div>
              <div style={{ fontSize: 12, color: 'var(--fg-soft)', marginTop: 2 }}>{p.family}</div>
            </div>
          )}
          {comparatorRow('% Cacau', items, slots, (p) => <span style={{ fontFamily: 'var(--font-display)', fontSize: 22 }}>{p.cacauLabel || `${p.cacau}%`}</span>)}
          {comparatorRow('Linha', items, slots, (p) => LINES.find((l) => l.id === p.line)?.label)}
          {comparatorRow('Embalagens', items, slots, (p) =>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
              {p.sizes.map((s) =>
            <div key={s.label} style={{ fontSize: 12 }}>
                  <strong>{s.label} · {s.g}g</strong> · <span style={{ color: 'var(--fg-soft)' }}>{packagingFor(s)}</span>
                </div>
            )}
            </div>
          )}
          {comparatorRow('Restrições', items, slots, (p) =>
          <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
              {p.restrictions.map((r) => {
              const d = RESTR.find((x) => x.id === r);
              return <span key={r} style={{ fontSize: 11, padding: '3px 8px', background: 'var(--accent)', color: 'var(--bg)', borderRadius: 100 }}>{d?.label || r}</span>;
            })}
            </div>
          )}
        </div>
      </div>
    </section>);

}
function comparatorRow(label, items, slots, render) {
  return (
    <React.Fragment>
      <div className="cell field">{label}</div>
      {Array.from({ length: slots }).map((_, i) => {
        const p = items[i];
        return <div className="cell" key={label + '-' + i}>{p ? render(p) : ''}</div>;
      })}
    </React.Fragment>);

}

// ─── Orçamento (cart + send) ───────────────────────────────
function OrcamentoModal({ items, qtyMap, setQty, onRemove, onClose, message, setMessage, onVerProduto }) {
  const [cnpj, setCnpj] = useState('');
  const [zap, setZap] = useState('');            // WhatsApp do cliente (obrigatório no P0)
  const [enviando, setEnviando] = useState(false);
  const [enviado, setEnviado] = useState(null);   // { numero } após o backend confirmar
  const [fallbackWa, setFallbackWa] = useState(false); // número não validado → wa.me manual
  const [formError, setFormError] = useState('');
  const [toast, setToast] = useState('');
  const cnpjRef = React.useRef(null);
  const zapRef = React.useRef(null);

  useEffect(() => { if (!toast) return; const t = setTimeout(() => setToast(''), 2400); return () => clearTimeout(t); }, [toast]);

  const flagMissing = () => {
    if (!temItens) {
      setFormError('Escolha a quantidade de pelo menos um produto para pedir o orçamento.');
      return;
    }
    if (!zapOk) setFormError('Informe o WhatsApp com DDD — é nele que o orçamento chega.');
    else setFormError('Informe um CNPJ válido (14 dígitos) — o endereço sai do cadastro.');
    const target = !zapOk ? zapRef.current : cnpjRef.current;
    if (target) { try { target.focus({ preventScroll: false }); } catch { target.focus(); } }
  };
  const formatCnpj = (v) => {
    const d = v.replace(/\D/g, '').slice(0, 14);
    if (d.length <= 2) return d;
    if (d.length <= 5) return d.replace(/^(\d{2})(\d+)/, '$1.$2');
    if (d.length <= 8) return d.replace(/^(\d{2})(\d{3})(\d+)/, '$1.$2.$3');
    if (d.length <= 12) return d.replace(/^(\d{2})(\d{3})(\d{3})(\d+)/, '$1.$2.$3/$4');
    return d.replace(/^(\d{2})(\d{3})(\d{3})(\d{4})(\d+)/, '$1.$2.$3/$4-$5');
  };
  const cnpjDigits = cnpj.replace(/\D/g, '');
  const cnpjOk = cnpjDigits.length === 14;
  const formatZap = (v) => {
    const d = v.replace(/\D/g, '').slice(0, 13);
    const semDdi = (d.length >= 12 && d.startsWith('55')) ? d.slice(2) : d;
    if (semDdi.length <= 2) return semDdi;
    if (semDdi.length <= 6) return semDdi.replace(/^(\d{2})(\d+)/, '($1) $2');
    if (semDdi.length <= 10) return semDdi.replace(/^(\d{2})(\d{4})(\d+)/, '($1) $2-$3');
    return semDdi.replace(/^(\d{2})(\d{5})(\d+)/, '($1) $2-$3');
  };
  const zapDigits = (() => {
    let d = zap.replace(/\D/g, '');
    if ((d.length === 12 || d.length === 13) && d.startsWith('55')) d = d.slice(2);
    return d;
  })();
  const zapOk = zapDigits.length === 10 || zapDigits.length === 11;
  const temItens = items.some((p) => p.sizes.some((sz) => ((qtyMap[p.id] && qtyMap[p.id][sz.label]) | 0) > 0));
  const formOk = zapOk && cnpjOk && temItens;

  // ─── Envio pelo PRÓPRIO SITE (Plano 0): o backend valida o número (conversa
  // recente = janela de 24h aberta), cria o orçamento no ERP e devolve o PDF no
  // WhatsApp informado. Sem conversa recente → fallback wa.me com a mensagem pronta.
  const enviarPeloSite = async () => {
    if (!formOk) { flagMissing(); return; }
    setEnviando(true); setFormError(''); setFallbackWa(false);
    try {
      // Pedido por UNIDADE (decisão 31/07): a lista de preço Lojista precifica o
      // tablete avulso — enviamos o código unitário × (embalagens × un/embalagem).
      const itens = [];
      items.forEach((p) => p.sizes.forEach((s) => {
        const q = getQty(p.id, s.label);
        if (!q) return;
        const codigo = s.skuUnidade || s.sku;
        if (codigo) itens.push({ sku: codigo, quantidade: q * (s.un || 1) });
      }));
      const res = await fetch('/api/public/orcamento', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          slug: 'java',
          whatsapp: '55' + zapDigits,
          cnpj: cnpjDigits,
          itens,
          observacoes: message.trim() || undefined,
        }),
      });
      const json = await res.json().catch(() => ({}));
      if (res.ok && json.ok) {
        setEnviado({ numero: json.numeroPedido || null });
      } else if (res.status === 409) {
        setFallbackWa(true);
        setFormError(json.message || 'Não encontramos uma conversa recente com esse WhatsApp. Envie a mensagem pronta pelo botão verde — respondemos por lá.');
      } else {
        setFallbackWa(true);
        setFormError(json.message || 'Não foi possível gerar o orçamento agora. Envie pelo botão verde que atendemos por lá.');
      }
    } catch {
      setFallbackWa(true);
      setFormError('Falha de conexão. Envie pelo botão verde que atendemos por lá.');
    } finally {
      setEnviando(false);
    }
  };

  useEffect(() => {
    const onEsc = (e) => e.key === 'Escape' && onClose();
    window.addEventListener('keydown', onEsc);
    document.body.style.overflow = 'hidden';
    return () => {window.removeEventListener('keydown', onEsc);document.body.style.overflow = '';};
  }, []);

  const getQty = (pid, label) => {
    const m = qtyMap[pid];
    if (!m || typeof m !== 'object') return 0;
    return m[label] | 0;
  };
  const productTotal = (p) => p.sizes.reduce((sum, s) => sum + getQty(p.id, s.label), 0);
  const nSelecionados = items.reduce((n, p) => n + p.sizes.filter((sz) => getQty(p.id, sz.label) > 0).length, 0);

  const buildMessage = () => {
    const lines = [];
    lines.push('Olá! Gostaria de orçamento para os seguintes itens:');
    lines.push('');
    if (cnpj) {
      lines.push('Dados para emissão:');
      lines.push(`CNPJ: ${cnpj}`);
      lines.push('');
    }
    const orcPairs = [];
    items.forEach((p) => {
      p.sizes.forEach((s) => {
        const qty = getQty(p.id, s.label);
        if (!qty) return;
        const codigo = s.sku ? ` — SKU ${s.sku}${s.ean ? ' · EAN ' + s.ean : ''}` : '';
        lines.push(`• ${qty} × ${p.name} — ${p.cacauLabel || p.cacau + '% cacau'} — ${s.label} ${s.g}g (${packagingFor(s)})${codigo}`);
        const codigoOrc = s.skuUnidade || s.sku;
        if (codigoOrc) orcPairs.push(`${codigoOrc} x${qty * (s.un || 1)}`);
      });
    });
    if (message.trim()) {lines.push('');lines.push('Observações:');lines.push(message.trim());}
    // Bloco estruturado p/ o bot criar o orçamento no ERP sem interpretação de
    // texto livre (parse determinístico por SKU). Não remover.
    if (orcPairs.length) {
      lines.push('');
      lines.push('Código do pedido (uso interno — não apague):');
      lines.push(`ORC: ${orcPairs.join('; ')} | CNPJ ${cnpjDigits}`);
    }
    lines.push('');
    lines.push('— Pedido gerado pelo catálogo interativo Java 2026');
    return lines.join('\n');
  };

  const waUrl = `https://wa.me/5531973267809?text=${encodeURIComponent(buildMessage())}`;

  // Copia o texto antes de abrir — evita perder a mensagem se o WhatsApp
  // não abrir (preview embarcado, popup bloqueado etc.).
  const tryCopy = async () => {
    try {await navigator.clipboard.writeText(buildMessage());} catch {}
  };
  const copyMsg = async () => {
    try {await navigator.clipboard.writeText(buildMessage());setToast('Mensagem copiada para a área de transferência.');}
    catch {setToast('Não foi possível copiar — selecione o texto manualmente.');}
  };

  return (
    <div className="sheet-backdrop interactive-only" onClick={onClose}>
      <aside className="sheet sheet-wide" onClick={(e) => e.stopPropagation()}>
        <div className="sheet-body" style={{ padding: 'clamp(24px, 3vw, 40px)' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline' }}>
            <div>
              <div className="block-title" style={{ marginBottom: 6 }}>Orçamento · {nSelecionados} {nSelecionados === 1 ? 'item no pedido' : 'itens no pedido'}</div>
              <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 32, fontWeight: 500, margin: 0 }}>Pedir orçamento</h2>
            </div>
            <button className="close-x" onClick={onClose}>✕</button>
          </div>

          <p style={{ color: 'var(--fg-soft)', fontSize: 14, marginTop: 8 }}>
            Ajuste as quantidades, informe seu WhatsApp e CNPJ e clique em
            <strong> Receber orçamento no WhatsApp</strong> — o documento em PDF chega na
            sua conversa em instantes, com os preços da sua tabela.
          </p>

          {items.length === 0 &&
          <div style={{ padding: '40px 16px', textAlign: 'center', border: '1px dashed var(--rule)', borderRadius: 4, color: 'var(--fg-soft)' }}>
              Nenhum produto adicionado ainda.<br />
              Adicione pelos cards usando <strong>+ orçamento</strong>.
            </div>
          }

          <div className="orc-list">
            {items.map((p) => {
              const total = productTotal(p);
              const hasMulti = p.sizes.length > 1;
              const noneSelected = total === 0;
              return (
              <div className="orc-row" key={p.id}>
                <div className="orc-thumb"
                  style={p.placeholder ? { background: p.placeholder.tone } : {}}>
                  {p.img ?
                    <img src={p.img} alt="" /> :
                    <span style={{ color: 'var(--cream)', fontSize: 11, padding: 6, textAlign: 'center' }}>{p.placeholder?.label}</span>}
                </div>
                <div className="orc-info">
                  <div className="orc-head">
                    <span className="orc-name">{p.name}</span>
                    <span className="orc-sub">{p.cacauLabel || `${p.cacau}% cacau`}</span>
                  </div>
                  {onVerProduto &&
                    <button className="orc-vercatalogo" type="button"
                      onClick={() => onVerProduto(p)}
                      title="Ver detalhes deste produto no catálogo">
                      ver no catálogo →
                    </button>
                  }
                </div>
                <button className="orc-remove" onClick={() => onRemove(p.id)} title="Remover">✕</button>

                <div className="orc-sizes">
                  {hasMulti &&
                    <div className="orc-sizes-hint">Ajuste a quantidade de cada tamanho:</div>
                  }
                  {p.sizes.map((s) => {
                    const qty = getQty(p.id, s.label);
                    const selected = qty > 0;
                    return (
                      <div className={`orc-size-row ${selected ? 'is-on' : ''}`} key={s.label}>
                        <span className="orc-size-label">
                          <span className="orc-size-line"><strong>{s.label}</strong> · {s.g}g</span>
                          <em className="orc-size-pack">{packagingFor(s)}</em>
                        </span>
                        <div className="qty">
                          <button
                            type="button"
                            onClick={() => { setQty(p.id, s.label, Math.max(0, qty - 1)); if (formError) setFormError(''); }}>−</button>
                          <input
                            type="number"
                            value={qty}
                            min={0}
                            onChange={(e) => {
                              const v = Math.max(0, parseInt(e.target.value || '0', 10) || 0);
                              setQty(p.id, s.label, v);
                              if (formError) setFormError('');
                            }} />
                          <button
                            type="button"
                            onClick={() => { setQty(p.id, s.label, qty + 1); if (formError) setFormError(''); }}>+</button>
                        </div>
                      </div>);

                  })}
                  {noneSelected &&
                    <div className="orc-size-warn">Sem quantidade — este produto não entra no orçamento.</div>
                  }
                </div>
              </div>);

            })}
          </div>

          {items.length > 0 &&
          <>
              <div className="orc-form-grid">
                <label className="orc-field">
                  <span className="orc-field-label">Seu WhatsApp (com DDD) <em>*</em></span>
                  <input
                  type="tel"
                  className={`orc-input ${(zap && !zapOk) || (formError && !zapOk) ? 'invalid' : ''}`}
                  placeholder="(31) 99999-9999"
                  inputMode="tel"
                  ref={zapRef}
                  value={zap}
                  onChange={(e) => { setZap(formatZap(e.target.value)); if (formError) setFormError(''); }}
                  required />
                  {zap && !zapOk && <span className="orc-hint">Número com DDD (10 ou 11 dígitos).</span>}
                  {!zap && formError && !zapOk && <span className="orc-hint">Campo obrigatório — o orçamento chega nele.</span>}
                </label>
                <label className="orc-field">
                  <span className="orc-field-label">CNPJ <em>*</em></span>
                  <input
                  type="text"
                  className={`orc-input ${(cnpj && !cnpjOk) || (formError && !cnpjOk) ? 'invalid' : ''}`}
                  placeholder="00.000.000/0000-00"
                  inputMode="numeric"
                  ref={cnpjRef}
                  value={cnpj}
                  onChange={(e) => { setCnpj(formatCnpj(e.target.value)); if (formError) setFormError(''); }}
                  required />
                  {cnpj && !cnpjOk && <span className="orc-hint">CNPJ deve ter 14 dígitos.</span>}
                  {!cnpj && formError && !cnpjOk && <span className="orc-hint">Campo obrigatório.</span>}
                </label>
              </div>

              <div className="block-title" style={{ marginTop: 8 }}>Observações (opcional)</div>
              <textarea
              className="orc-textarea"
              value={message}
              onChange={(e) => setMessage(e.target.value)} />
            

              <div className="block-title">Mensagem que será enviada</div>
              <pre className="orc-preview">{buildMessage()}</pre>

              {formError &&
              <div className="orc-error" role="alert" aria-live="assertive">
                <span className="orc-error-icon" aria-hidden="true">!</span>
                <span>{formError}</span>
              </div>
              }

              {enviado ?
              <div className="orc-error" role="status" aria-live="polite"
                style={{ background: '#EBF7EE', borderColor: '#3E7C4F', color: '#245231' }}>
                <span aria-hidden="true">✅</span>
                <span>
                  <strong>Orçamento{enviado.numero ? ` nº ${enviado.numero}` : ''} gerado!</strong>{' '}
                  O PDF chega no seu WhatsApp em instantes. Qualquer ajuste, é só responder por lá.
                </span>
              </div> :
              <div className="orc-actions">
                <button
                className={`btn whats ${!formOk || enviando ? 'is-disabled' : ''}`}
                type="button"
                onClick={() => { if (enviando) return; enviarPeloSite(); }}
                aria-disabled={!formOk || enviando}
                title={!formOk ? 'Preencha WhatsApp e CNPJ' : 'O orçamento em PDF chega no seu WhatsApp'}>
                  {enviando ? 'Gerando orçamento…' : 'Receber orçamento no WhatsApp'} <span>→</span>
                </button>
                {fallbackWa &&
                <a
                className="btn whats"
                href={waUrl}
                target="_blank"
                rel="noopener noreferrer"
                onClick={() => { tryCopy(); }}
                title="Abre o WhatsApp com a mensagem pronta">
                  Enviar mensagem pronta pelo WhatsApp <span>→</span>
                </a>
                }
                <button className="btn ghost" onClick={copyMsg}>
                  Copiar mensagem
                </button>
              </div>
              }
            </>
          }
        </div>
        {toast &&
        <div className="orc-toast" role="status" aria-live="polite">{toast}</div>
        }
        {/* Item 2: quem abre o link ?rapido=1 no celular cai direto aqui e não
            percebe que existe catálogo atrás. Fechar preserva as quantidades. */}
        <button className="fab fab-catalogo interactive-only" type="button" onClick={onClose}
          title="Ver o catálogo — suas quantidades ficam guardadas">
          📖 Ver catálogo
        </button>
      </aside>
    </div>);

}

// ─── Contato ───────────────────────────────────────────────
function Contato() {
  return (
    <section id="contato" className="contato" data-screen-label="Contato">
      <div className="shell">
        <div>
          <div className="over" style={{ color: 'rgba(255,253,237,0.6)' }}>Pedidos · Revenda · Food Service</div>
          <h2 style={{ fontFamily: "\"Fira Sans\"", fontWeight: 900 }}>Faça seu<br />pedido.</h2>
          <p className="lead">
            Atendemos lojistas, hotelaria, cafeterias especiais e mercados gourmet
            em todo o Brasil. Pedido mínimo, condições e prazos sob consulta.
          </p>
          <div className="info">
            <div className="ln"><span className="lbl">WhatsApp</span><span>+55 31 97326-7809</span></div>
            <div className="ln"><span className="lbl">E-mail</span><span>comercial@javachocolates.com.br</span></div>
            <div className="ln"><span className="lbl">Site</span><span>www.javachocolates.com.br</span></div>
            <div className="ln"><span className="lbl">Fábrica</span><span>Belo Horizonte · Minas Gerais</span></div>
          </div>
          <div className="actions">
            <a className="btn primary" href="https://wa.me/5531973267809?text=Vim%20do%20cat%C3%A1logo%20e%20gostaria%20de%20pedir%20um%20or%C3%A7amento." target="_blank" rel="noreferrer">
              Pedir orçamento pelo WhatsApp <span>→</span>
            </a>
            <a
              className="btn"
              href={typeof window !== 'undefined' && window.matchMedia && window.matchMedia('(max-width: 700px)').matches ? 'catalogo-pdf-mobile-print.html' : 'catalogo-pdf-print.html'}
              target="_blank"
              rel="noopener noreferrer">
              Baixar este catálogo em PDF <span>↓</span>
            </a>
          </div>
        </div>
        <div className="logo-block">
          <img src="assets/logo-white.png" alt="Java chocolates" />
          <div style={{ fontFamily: 'var(--font-display)', fontSize: 20, fontWeight: 300 }}>
            Cacau de origem,<br />chocolate de Minas.
          </div>
          <div className="legals">
            JAVA Chocolates Ltda.<br />
            CNPJ 20.261.126/0001-27<br />
            Telefone: (31) 2520-6776<br />
            Indústria Brasileira<br />
            © 2026 — todos os direitos reservados.
          </div>
        </div>
      </div>
    </section>);

}

// ─── Print version ─────────────────────────────────────────
function PrintVersion() {
  return (
    <div className="print-only">
      {/* Cover */}
      <div className="pdf-page" style={{ background: 'var(--brown)', color: 'var(--cream)', display: 'flex' }}>
        <div style={{ flex: 1, padding: '40mm 28mm', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
          <div style={{ fontSize: 10, letterSpacing: '0.22em', textTransform: 'uppercase' }}>Catálogo 2026 · Revenda</div>
          <div>
            <h1 style={{ fontFamily: 'var(--font-display)', fontSize: 64, fontWeight: 300, lineHeight: 0.95, margin: 0, letterSpacing: '-0.02em' }}>
              <strong style={{ fontWeight: 800 }}>Do</strong> cacau<br />à barra.
            </h1>
            <p style={{ fontSize: 14, maxWidth: '28ch', color: 'rgba(255,253,237,0.78)', marginTop: 24 }}>
              Chocolate fino brasileiro. Cacau de origem. Sem glúten. Sem leite.
            </p>
          </div>
          <img src="assets/logo-white.png" style={{ width: 90 }} alt="" />
        </div>
        <div style={{ flex: 1, overflow: 'hidden' }}>
          <img src="assets/img/cover-cacau.jpg" style={{ width: '100%', height: '100%', objectFit: 'cover' }} alt="" />
        </div>
      </div>

      {/* Sumário */}
      <div className="pdf-page" style={{ padding: '24mm 22mm' }}>
        <div style={{ fontSize: 12, letterSpacing: '0.08em', fontWeight: 700, fontFamily: 'var(--font-display)' }}>Nossos produtos</div>
        <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 42, fontWeight: 400, marginTop: 8, lineHeight: 1.05 }}>
          Chocolates de verdade.
        </h2>
        <div style={{ marginTop: 32, display: 'flex', flexDirection: 'column' }}>
          {LINES.map((l, i) => {
            const items = PRODUCTS.filter((p) => p.line === l.id).sort((a, b) => a.cacau - b.cacau);
            return (
              <div key={l.id} style={{ padding: '14px 0', borderBottom: '1px solid #eee' }}>
                <div style={{ display: 'grid', gridTemplateColumns: 'auto 1fr auto', gap: 16, alignItems: 'baseline' }}>
                  <span style={{ fontFamily: 'ui-monospace, monospace', fontSize: 11, color: '#888' }}>0{i + 1}</span>
                  <div>
                    <div style={{ fontFamily: 'var(--font-display)', fontSize: 18, fontWeight: 500 }}>{l.label}</div>
                    <div style={{ fontSize: 11, color: '#888', marginTop: 2 }}>{l.sub}</div>
                  </div>
                  <span style={{ fontSize: 11, fontFamily: 'ui-monospace, monospace', color: '#888' }}>{items.length} produtos</span>
                </div>
                <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '2px 24px', marginTop: 10, paddingLeft: 28 }}>
                  {items.map((p) =>
                  <div key={p.id} style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, padding: '3px 0', borderBottom: '1px dotted #ddd' }}>
                      <span>{p.cacau}% · {p.name}</span>
                      <span style={{ color: '#888' }}>{p.sizes.map((s) => s.g + 'g').join(' / ')}</span>
                    </div>
                  )}
                </div>
              </div>);

          })}
        </div>
        <div style={{ position: 'absolute', bottom: '20mm', left: '22mm', right: '22mm', fontSize: 10, color: '#888' }}>
          <strong style={{ color: '#333' }}>Atualizações 2026:</strong> Barras 80g → <strong style={{ color: '#6E3D30' }}>65g</strong> ·
          Mini 25g → <strong style={{ color: '#6E3D30' }}>20g</strong>.
        </div>
      </div>

      {[...PRODUCTS].sort((a, b) => a.cacau - b.cacau).map((p) => <PrintProductPage key={p.id} p={p} />)}

      {/* Contact */}
      <div className="pdf-page" style={{ background: 'var(--brown)', color: 'var(--cream)', padding: '36mm 24mm', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
        <div>
          <div style={{ fontSize: 10, letterSpacing: '0.22em', textTransform: 'uppercase', color: 'rgba(255,253,237,0.6)' }}>Pedidos · Revenda · Food Service</div>
          <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 56, fontWeight: 300, marginTop: 12, lineHeight: 0.98, letterSpacing: '-0.02em' }}>
            Faça seu<br />pedido.
          </h2>
          <p style={{ fontSize: 15, maxWidth: '36ch', marginTop: 24, color: 'rgba(255,253,237,0.78)' }}>
            Atendemos lojistas, hotelaria, cafeterias especiais e mercados gourmet em todo o Brasil.
          </p>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 32 }}>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            {[['WhatsApp', '+55 11 99999-9999'], ['E-mail', 'vendas@javachocolates.com.br'], ['Site', 'javachocolates.com.br'], ['Fábrica', 'Belo Horizonte · MG']].map(([k, v]) =>
            <div key={k}>
                <div style={{ fontSize: 9, letterSpacing: '0.22em', textTransform: 'uppercase', opacity: 0.6 }}>{k}</div>
                <div style={{ fontSize: 15, marginTop: 2 }}>{v}</div>
              </div>
            )}
          </div>
          <div style={{ borderLeft: '1px solid rgba(255,253,237,0.2)', paddingLeft: 24 }}>
            <img src="assets/logo-white.png" style={{ width: 110 }} alt="" />
            <div style={{ fontFamily: 'var(--font-display)', fontSize: 16, fontWeight: 300, marginTop: 16 }}>
              Cacau de origem,<br />chocolate de Minas.
            </div>
            <div style={{ fontSize: 9, lineHeight: 1.7, color: 'rgba(255,253,237,0.5)', marginTop: 16 }}>
              Java Chocolates Indústria e Comércio Ltda.<br />
              CNPJ 20.261.126/0001-27<br />
              Telefone: (31) 2520-6776<br />
              Indústria Brasileira<br />
              © 2026 — todos os direitos reservados.
            </div>
          </div>
        </div>
      </div>
    </div>);

}

function PrintProductPage({ p }) {
  const lineLabel = LINES.find((l) => l.id === p.line)?.label;
  return (
    <div className="pdf-page" style={{ display: 'flex', flexDirection: 'column' }}>
      <div style={{ flex: '0 0 55%', position: 'relative', overflow: 'hidden', background: p.placeholder?.tone || 'var(--cream-warm)' }}>
        {p.img ?
        <img src={p.img} style={{ width: '100%', height: '100%', objectFit: 'cover' }} alt="" /> :
        <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--cream)', fontFamily: 'var(--font-display)', fontSize: 48, background: `linear-gradient(135deg, ${p.placeholder?.tone}, #4a2820)` }}>
              {p.placeholder?.label}
            </div>}
        <div style={{ position: 'absolute', top: '12mm', left: '12mm', color: 'var(--cream)', fontSize: 10, letterSpacing: '0.22em', textTransform: 'uppercase', mixBlendMode: 'difference' }}>
          {lineLabel}
        </div>
        {p.status === 'novo' &&
        <div style={{ position: 'absolute', top: '12mm', right: '12mm', padding: '6px 12px', background: 'var(--cream)', color: 'var(--brown)', fontSize: 9, letterSpacing: '0.22em', textTransform: 'uppercase' }}>
            Novo · 2026
          </div>
        }
      </div>
      <div style={{ flex: '1 1 45%', padding: '14mm 18mm', display: 'flex', flexDirection: 'column' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, letterSpacing: '0.18em', textTransform: 'uppercase', color: '#888' }}>
          <span>{lineLabel}</span>
          <span style={{ color: 'var(--brown)', fontWeight: 600 }}>{p.cacauLabel || `${p.cacau}% cacau`}</span>
        </div>
        <h2 style={{ fontFamily: 'var(--font-display)', fontSize: 36, fontWeight: 500, lineHeight: 1.05, margin: '4px 0 2px', letterSpacing: '-0.01em' }}>
          {p.name}
        </h2>
        <div style={{ fontSize: 13, color: '#888' }}>{p.family}</div>
        <p style={{ fontSize: 13, lineHeight: 1.55, marginTop: 12, color: '#333' }}>{p.description}</p>

        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 16, marginTop: 'auto', paddingTop: 12 }}>
          <div>
            <div style={{ fontSize: 9, letterSpacing: '0.22em', textTransform: 'uppercase', color: '#888', marginBottom: 6 }}>Restrições</div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 4 }}>
              {p.restrictions.map((r) => {
                const d = RESTR.find((x) => x.id === r);
                return <span key={r} style={{ fontSize: 10, padding: '2px 7px', background: 'var(--brown)', color: 'var(--cream)', borderRadius: 100 }}>{d?.label || r}</span>;
              })}
            </div>
            {p.origin &&
            <>
                <div style={{ fontSize: 9, letterSpacing: '0.22em', textTransform: 'uppercase', color: '#888', marginTop: 12, marginBottom: 6 }}>Origem</div>
                <div style={{ fontSize: 12 }}>{p.origin}</div>
              </>
            }
          </div>
          <div>
            <div style={{ fontSize: 9, letterSpacing: '0.22em', textTransform: 'uppercase', color: '#888', marginBottom: 6 }}>Embalagens 2026</div>
            <div>
              {p.sizes.map((s) =>
              <div key={s.label} style={{ padding: '6px 0', borderBottom: '1px solid #eee' }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12 }}>
                    <span style={{ fontFamily: 'var(--font-display)', fontWeight: 500 }}>{s.label}</span>
                    <span style={{ color: 'var(--brown)', fontWeight: 600, fontFamily: 'ui-monospace, monospace', fontSize: 11 }}>{s.g}g</span>
                  </div>
                  <div style={{ fontSize: 10, color: '#888' }}>{packagingFor(s)}</div>
                </div>
              )}
            </div>
          </div>
        </div>
      </div>
    </div>);

}

// ─── App root ─────────────────────────────────────────────
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "variant": "artesanal",
  "showCompare": true
} /*EDITMODE-END*/;

function App() {
  const [tweaks, setTweak] = window.useTweaks(TWEAK_DEFAULTS);

  const [line, setLine] = useState(null);
  const [cacau, setCacau] = useState('all');
  const [size, setSize] = useState('all');
  const [restr, setRestr] = useState([]);
  const [onlyBest, setOnlyBest] = useState(false);
  const [open, setOpen] = useState(null);
  const [cmpIds, setCmpIds] = useState([]);
  const [orcIds, setOrcIds] = useState([]);
  const [orcQty, setOrcQty] = useState({});
  const [orcMsg, setOrcMsg] = useState('');
  const [orcOpen, setOrcOpen] = useState(false);

  // itens com quantidade escolhida — alimenta o selo do botão flutuante
  const nOrcSelecionados = Object.values(orcQty).reduce(
    (n, tamanhos) => n + Object.values(tamanhos || {}).filter((q) => (q | 0) > 0).length, 0);

  const filtered = useMemo(() => PRODUCTS.filter((p) => {
    if (line && p.line !== line) {
      // Linhas podem ter uma faixa de % cacau adicional (ex.: equilibrados 35–50%)
      const lineObj = LINES.find((l) => l.id === line);
      const range = lineObj?.cacauRange;
      if (!range || p.cacau < range[0] || p.cacau > range[1]) return false;
    }
    if (cacau !== 'all') {
      const [lo, hi] = cacau.split('-').map(Number);
      if (p.cacau < lo || p.cacau > hi) return false;
    }
    if (size !== 'all') {
      const has = (label) => p.sizes.some((s) => s.label.toLowerCase().startsWith(label));
      if (size === 'tablete' && !has('tablete')) return false;
      if (size === 'mini' && !has('mini')) return false;
    }
    if (onlyBest && !p.bestseller) return false;
    if (restr.length) {
      const defs = RESTR_FILTERS.filter((f) => restr.includes(f.id));
      if (!defs.every((d) => d.match(p))) return false;
    }
    return true;
  }).sort((a, b) => a.cacau - b.cacau), [line, cacau, size, restr, onlyBest]);

  const toggleCmp = (id) => {
    setCmpIds((prev) => prev.includes(id) ? prev.filter((x) => x !== id) : prev.length >= 4 ? prev : [...prev, id]);
  };
  const toggleOrc = (id) => {
    setOrcIds((prev) => {
      if (prev.includes(id)) return prev.filter((x) => x !== id);
      setOrcQty((q) => {
        if (q[id] && typeof q[id] === 'object') return q;
        const product = PRODUCTS.find((p) => p.id === id);
        if (!product) return q;
        const init = {};
        // Default: first size selected with qty 1; outras desmarcadas (0).
        product.sizes.forEach((s, i) => { init[s.label] = i === 0 ? 1 : 0; });
        return { ...q, [id]: init };
      });
      return [...prev, id];
    });
  };
  const setQty = (id, sizeLabel, v) => setOrcQty((q) => {
    const cur = q[id] && typeof q[id] === 'object' ? q[id] : {};
    return { ...q, [id]: { ...cur, [sizeLabel]: Math.max(0, v | 0) } };
  });

  // ─── Pedido rápido ────────────────────────────────────────
  // Abre o modal com TODOS os produtos listados (qtd 0) — o cliente só sobe a
  // quantidade do que quer. `quantidades` opcional pré-preenche por código
  // (sku da caixa, código unitário ou EAN), em Nº DE EMBALAGENS.
  const abrirPedidoRapido = (quantidades) => {
    const ids = [];
    const qty = {};
    PRODUCTS.forEach((p) => {
      const init = {};
      let preset = false;
      p.sizes.forEach((s) => {
        const codigos = [s.sku, s.skuUnidade, s.ean].filter(Boolean).map((c) => String(c).toLowerCase());
        const hit = quantidades ? codigos.find((c) => quantidades[c] != null) : null;
        init[s.label] = hit ? quantidades[hit] : 0;
        if (hit) preset = true;
      });
      if (!quantidades || preset) { ids.push(p.id); qty[p.id] = init; }
    });
    if (!ids.length) return;
    setOrcIds(ids);
    setOrcQty(qty);
    setOrcOpen(true);
  };

  // Deep links: ?rapido=1 (lista completa) · ?q=codigo:embalagens;… (pré-preenchido —
  // é a semente do "repetir último pedido" enviado pelo bot).
  useEffect(() => {
    const sp = new URLSearchParams(window.location.search);
    const q = sp.get('q');
    if (q) {
      const quantidades = {};
      q.split(';').forEach((tok) => {
        const [c, n] = tok.split(':');
        const v = Math.max(0, parseInt(n || '0', 10) || 0);
        if (c && v > 0) quantidades[c.trim().toLowerCase()] = v;
      });
      if (Object.keys(quantidades).length) { abrirPedidoRapido(quantidades); return; }
    }
    if (sp.has('rapido')) abrirPedidoRapido(null);
  }, []);

  useEffect(() => {document.body.setAttribute('data-variant', tweaks.variant);}, [tweaks.variant]);

  const onJumpFilter = (lineId) => {
    setLine(lineId);
    setTimeout(() => document.getElementById('produtos')?.scrollIntoView({ behavior: 'smooth', block: 'start' }), 50);
  };

  const orcItems = orcIds.map((id) => PRODUCTS.find((p) => p.id === id)).filter(Boolean);

  return (
    <div className="site" data-variant={tweaks.variant}>
      <TopBar variant={tweaks.variant} onPedidoRapido={() => abrirPedidoRapido(null)} />
      <Cover />

      <section id="produtos" data-screen-label="02 Produtos">
        <div className="shell">
          <div className="section-head">
            <div>
              <div className="label">03 · Catálogo</div>
              <h2>Catálogo<br />completo.</h2>
            </div>
            <div className="right">
              Use os filtros para encontrar por linha, % cacau ou restrição alimentar.
              Adicione produtos ao <strong>orçamento</strong> ou ao <strong>comparador</strong> pelos botões em cada card.
            </div>
          </div>
          <Filters
            line={line} setLine={setLine}
            cacau={cacau} setCacau={setCacau}
            size={size} setSize={setSize}
            restr={restr} setRestr={setRestr}
            onlyBest={onlyBest} setOnlyBest={setOnlyBest}
            count={filtered.length} />
          
          <div className="grid-products">
            {filtered.map((p) =>
            <Card key={p.id} p={p} onOpen={setOpen}
            compareIds={cmpIds} toggleCompare={toggleCmp}
            orcamentoIds={orcIds} toggleOrcamento={toggleOrc} />
            )}
          </div>
        </div>
      </section>

      {tweaks.showCompare && cmpIds.length > 0 && <Comparator ids={cmpIds} setIds={setCmpIds} />}

      <Contato />

      {open && <Sheet product={open}
      onClose={() => setOpen(null)}
      onCompare={toggleCmp} compareIds={cmpIds}
      onOrcamento={toggleOrc} orcamentoIds={orcIds}
      onVerOrcamento={() => { setOpen(null); setOrcOpen(true); }} />}

      {/* FAB do catálogo (item 4): no celular o botão do topo some ao rolar, e a
          pessoa perde o caminho para o orçamento. Some quando o modal está aberto. */}
      {/* A bandeja "N no orçamento" já é o caminho quando há itens escolhidos —
          o FAB só aparece quando ela NÃO existe (senão sobrepõe, como em 15/08). */}
      {!orcOpen && !open && orcIds.length === 0 &&
      <button className="fab fab-orcamento interactive-only" type="button"
        onClick={() => (orcIds.length ? setOrcOpen(true) : abrirPedidoRapido(null))}
        title="Montar orçamento com os produtos do catálogo">
        🧾 Montar orçamento
        {nOrcSelecionados > 0 && <span className="fab-badge">{nOrcSelecionados}</span>}
      </button>
      }

      {orcOpen &&
      <OrcamentoModal
        items={orcItems}
        qtyMap={orcQty}
        setQty={setQty}
        onRemove={toggleOrc}
        onClose={() => setOrcOpen(false)}
        onVerProduto={(p) => { setOrcOpen(false); setOpen(p); }}
        message={orcMsg}
        setMessage={setOrcMsg} />

      }

      {/* Floating trays */}
      {(cmpIds.length > 0 || orcIds.length > 0) &&
      <div className="trays interactive-only">
          {orcIds.length > 0 &&
        <button className="tray orc-tray" onClick={() => setOrcOpen(true)}>
              <span className="lbl">🛒 {orcIds.length} no orçamento</span>
              <span className="arrow">Pedir orçamento →</span>
            </button>
        }
          {cmpIds.length > 0 &&
        <button className="tray cmp-tray" onClick={() => document.getElementById('comparador')?.scrollIntoView({ behavior: 'smooth' })}>
              <span className="lbl">⇆ {cmpIds.length} no comparador</span>
              <span className="arrow">Ver comparativo →</span>
            </button>
        }
        </div>
      }

      <window.TweaksPanel title="Tweaks · Java">
        <window.TweakSection label="Direção visual">
          <window.TweakRadio
            value={tweaks.variant}
            onChange={(v) => setTweak('variant', v)}
            options={[
            { value: 'artesanal', label: 'Artesanal' },
            { value: 'editorial', label: 'Editorial' },
            { value: 'premium', label: 'Premium' }]
            } />
          
        </window.TweakSection>
        <window.TweakSection label="Seções">
          <window.TweakToggle label="Comparador" value={tweaks.showCompare} onChange={(v) => setTweak('showCompare', v)} />
        </window.TweakSection>
        <window.TweakSection label="Exportar">
          <window.TweakButton label="Baixar PDF (desktop)" onClick={() => window.open('catalogo-pdf-print.html', '_blank', 'noopener')} />
          <window.TweakButton label="Baixar PDF (mobile)" onClick={() => window.open('catalogo-pdf-mobile-print.html', '_blank', 'noopener')} />
        </window.TweakSection>
      </window.TweaksPanel>

      <PrintVersion />
    </div>);

}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);