/* global React, ReactDOM, VendusAtoms, VendusData, VendusDashboard, VendusPagesA, VendusPagesB, VendusPagesC, VendusCopiloto, VendusMensagens, VendusCopilot */
const { useState, useMemo, useEffect, useRef } = React;
const { I, Chip, Btn, Card, Eyebrow, SectionTitle, EmptyState, brl } = window.VendusAtoms;

/* Página vazia (usuário sem dados) — usada no router para as telas que dependem
   de dados de loja. Some quando os dados reais existirem (loja conectada). */
const EMPTY_PAGES = {
  products:    { eyebrow: "Catálogo",   title: "Produtos",               icon: "package",       desc: "Seus produtos aparecem aqui assim que você conectar uma loja — o Vendus sincroniza o catálogo automaticamente." },
  sales:       { eyebrow: "Vendas",     title: "Vendas",                 icon: "shopping-cart", desc: "Seus pedidos entram automaticamente quando há uma loja conectada." },
  strategic:   { eyebrow: "Planejamento · IA", title: "Modo Estratégico", icon: "activity",     desc: "Simulações e cenários ficam disponíveis quando houver dados de vendas e custos da sua loja." },
  stores:      { eyebrow: "Lojas",      title: "Minhas lojas",           icon: "store",         desc: "Você ainda não conectou nenhuma loja. Conecte o Mercado Livre para começar." },
  comparatives:{ eyebrow: "Lojas",      title: "Comparativos",           icon: "bar-chart-3",   desc: "Compare canais e lojas aqui depois de conectar pelo menos uma loja." },
  cashflow:    { eyebrow: "Financeiro", title: "Fluxo de caixa",         icon: "banknote",      desc: "Entradas e saídas aparecem aqui conforme suas vendas e custos são registrados." },
  costs:       { eyebrow: "Financeiro", title: "Custos",                 icon: "receipt",       desc: "Cadastre seus custos fixos e variáveis para acompanhar a margem real." },
  suppliers:   { eyebrow: "Financeiro", title: "Fornecedores",           icon: "users",         desc: "Seus fornecedores e contas a pagar ficam organizados aqui." },
  purchases:   { eyebrow: "Financeiro", title: "Compras de estoque",     icon: "shopping-bag",  desc: "Acompanhe reposições e pedidos de compra de estoque." },
  reports:     { eyebrow: "Análises",   title: "Relatórios",             icon: "file-text",     desc: "Relatórios são gerados a partir dos dados da sua loja." },
  goals:       { eyebrow: "Análises",   title: "Metas",                  icon: "target",        desc: "Defina metas de faturamento, margem e pedidos para acompanhar seu progresso." },
  forecasts:   { eyebrow: "Análises",   title: "Previsões e Projeções",  icon: "trending-up",   desc: "Projeções aparecem quando houver histórico de vendas suficiente." },
};
function EmptyPage({ id, navigate, connected }) {
  const p = EMPTY_PAGES[id] || { title: "Em breve", icon: "inbox", desc: "" };
  return (
    <div className="page fade-in">
      <div className="page-header">
        <div>
          <Eyebrow>{p.eyebrow || ""}</Eyebrow>
          <h1 className="page-title">{p.title}</h1>
        </div>
      </div>
      <EmptyState icon={p.icon}
        title={connected ? "Em desenvolvimento" : "Ainda não há nada por aqui"}
        desc={connected ? "Este módulo está sendo preparado para usar os dados da sua loja. Em breve por aqui!" : p.desc}
        cta={connected ? undefined : "Conectar uma loja"}
        onCta={connected ? undefined : () => navigate("settings")} />
    </div>
  );
}

/* Lojas — mostra a loja conectada */
function ConnectedStores({ navigate, store, setSettingsTab }) {
  const [accounts, setAccounts] = useState(null);
  const [editId, setEditId] = useState(null);
  const [nome, setNome] = useState("");
  function load() { window.VendusCopilot.getAccounts().then(setAccounts); }
  useEffect(() => { load(); }, []);
  const ativo = (store && store.account_id) || window.VendusCopilot.getActiveAccount();
  function toast(m, t, i) { window.vendusToast && window.vendusToast(m, { icon: i || "check-check", tone: t || "success" }); }
  async function salvar(a) {
    const r = await window.VendusCopilot.renameAccount(a.id, nome.trim());
    if (r.ok) { setEditId(null); load(); toast("Loja renomeada ✓"); } else toast(r.error || "Não consegui renomear.", "danger", "alert-triangle");
  }
  function conectar() { window.VendusCopilot.connectStore().then((r) => { if (!r.ok) toast(r.error, "warning", "alert-triangle"); }); }
  const MKL = { mercado_livre: "Mercado Livre", shopee: "Shopee", tiktok: "TikTok Shop" };
  return (
    <div className="page fade-in">
      <div className="page-header">
        <div>
          <Eyebrow>Lojas</Eyebrow>
          <h1 className="page-title">Minhas lojas</h1>
          <div className="page-sub">{accounts ? `${accounts.length} ${accounts.length === 1 ? "loja conectada" : "lojas conectadas"}` : "Carregando…"}</div>
        </div>
        <Btn variant="primary" onClick={conectar}><I name="plus" size={14} /> Conectar outra loja</Btn>
      </div>
      {!accounts ? <Card padding={24}><div className="text-muted">Carregando…</div></Card> : accounts.map((a) => (
        <Card key={a.id} style={{ maxWidth: 560, marginBottom: 12 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 14, flexWrap: "wrap" }}>
            <div style={{ width: 48, height: 48, borderRadius: 12, background: "var(--logo-gradient)", display: "grid", placeItems: "center", color: "white" }}><I name="store" size={22} /></div>
            <div style={{ flex: 1, minWidth: 180 }}>
              {editId === a.id ? (
                <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
                  <input className="input" value={nome} onChange={(e) => setNome(e.target.value)} placeholder={a.nickname} style={{ flex: 1 }} autoFocus />
                  <Btn size="sm" variant="primary" onClick={() => salvar(a)}>Salvar</Btn>
                  <Btn size="sm" variant="ghost" onClick={() => setEditId(null)}>Cancelar</Btn>
                </div>
              ) : (
                <>
                  <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                    <div style={{ fontWeight: 700, fontSize: 15 }}>{a.nome}</div>
                    {a.id === ativo && <Chip tone="success">ativa</Chip>}
                    {a.primary && <Chip tone="default">principal</Chip>}
                  </div>
                  <div className="text-muted" style={{ fontSize: 12.5 }}>{MKL[a.marketplace] || a.marketplace} · <span className="text-success">conectada</span></div>
                </>
              )}
            </div>
            {editId !== a.id && (
              <div style={{ display: "flex", gap: 8 }}>
                {a.id !== ativo && <Btn size="sm" variant="ghost" onClick={() => window.VendusCopilot.setActiveAccount(a.id)}>Usar esta</Btn>}
                <Btn size="sm" variant="outline" onClick={() => { setEditId(a.id); setNome(a.apelido || ""); }}><I name="pencil" size={12} /> Renomear</Btn>
              </div>
            )}
          </div>
        </Card>
      ))}
    </div>
  );
}

/* Produtos reais — com edição de custo (manual ou planilha) e margem */
/* Drawer com a análise do anúncio feita pela IA */
function ProductDrawer({ state, onClose }) {
  if (!state) return null;
  const { product = {}, loading, ok, analise, produto, error } = state;
  const a = analise || {};
  const pr = produto || {};
  const notaTone = a.nota == null ? "default" : a.nota >= 75 ? "success" : a.nota >= 50 ? "warning" : "danger";
  const MK_NOME = { mercado_livre: "Mercado Livre", shopee: "Shopee", tiktok: "TikTok Shop" };
  const TIPO_ANUNCIO = { gold_pro: "Premium", gold_special: "Clássico", gold: "Clássico", silver: "Clássico", bronze: "Grátis", free: "Grátis" };
  const facts = !loading && ok ? [
    ["Loja / marketplace", MK_NOME[product.marketplace] || "Mercado Livre"],
    ["Preço no anúncio", brl(pr.preco)],
    ["Custo", pr.custo != null ? brl(pr.custo) : "—"],
    ["Margem", pr.margem_pct != null ? pr.margem_pct + "%" : "—"],
    ["Estoque", (pr.disponivel ?? 0) + " un."],
    ["Vendidos", String(pr.vendidos ?? 0)],
    ["Tipo de anúncio", TIPO_ANUNCIO[pr.tipo_anuncio] || (pr.tipo_anuncio ?? "—")],
    ["Fotos", String(pr.fotos ?? 0)],
    ["Ficha técnica", pr.atributos_total ? `${pr.atributos_preenchidos}/${pr.atributos_total} preenchidos` : "—"],
    ["Descrição", pr.tem_descricao ? `${pr.descricao_len} caracteres` : "sem descrição"],
    ["Saúde (ML)", pr.saude != null ? Math.round(pr.saude * 100) + "%" : "—"],
    ["Frete grátis", pr.frete_gratis ? "sim" : "não"],
  ] : [];
  return (
    <div onClick={onClose} style={{ position: "fixed", inset: 0, background: "rgba(0,0,0,.5)", zIndex: 300, display: "flex", justifyContent: "flex-end" }}>
      <div onClick={(e) => e.stopPropagation()} className="fade-in" style={{ width: "min(540px,100%)", height: "100%", background: "var(--bg-surface)", borderLeft: "1px solid var(--border)", overflowY: "auto", boxShadow: "-8px 0 40px rgba(0,0,0,.35)" }}>
        <div style={{ position: "sticky", top: 0, background: "var(--bg-surface)", borderBottom: "1px solid var(--border)", padding: "16px 20px", display: "flex", alignItems: "center", gap: 10, zIndex: 1 }}>
          <I name="sparkles" size={18} className="text-orange" />
          <div style={{ flex: 1, fontWeight: 700, fontSize: 14, lineHeight: 1.3 }}>{product.titulo}</div>
          <button onClick={onClose} title="Fechar" style={{ background: "transparent", border: "none", color: "var(--fg-2)", cursor: "pointer", padding: 4, display: "grid", placeItems: "center" }}><I name="x" size={18} /></button>
        </div>
        <div style={{ padding: 20 }}>
          {loading ? (
            <div style={{ display: "flex", flexDirection: "column", alignItems: "center", gap: 12, padding: "48px 0", textAlign: "center" }}>
              <div className="spin"><I name="loader" size={28} className="text-orange" /></div>
              <div className="text-muted" style={{ fontSize: 13.5 }}>Analisando este anúncio com a IA…<br/>Lendo fotos, descrição, preço e desempenho.</div>
            </div>
          ) : !ok ? (
            <EmptyState icon="alert-triangle" title="Não consegui analisar" desc={error || "Tente novamente em instantes."} />
          ) : (
            <>
              <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 16 }}>
                <div style={{ width: 64, height: 64, borderRadius: 14, display: "grid", placeItems: "center", background: notaTone === "success" ? "rgba(34,197,94,.15)" : notaTone === "warning" ? "rgba(250,204,21,.15)" : "rgba(255,106,106,.15)", color: notaTone === "success" ? "#4ADE80" : notaTone === "warning" ? "#FACC15" : "#FF6A6A" }}>
                  <span className="font-display" style={{ fontSize: 24, fontWeight: 800 }}>{a.nota ?? "—"}</span>
                </div>
                <div>
                  <div style={{ fontWeight: 700, fontSize: 15 }}>{a.nota_texto || "Análise do anúncio"}</div>
                  <div className="text-muted" style={{ fontSize: 13, lineHeight: 1.5, marginTop: 2 }}>{a.resumo}</div>
                </div>
              </div>

              <div style={{ fontWeight: 700, fontSize: 12.5, marginBottom: 8 }}>Detalhes do anúncio</div>
              <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 8, marginBottom: 18 }}>
                {facts.map(([l, v]) => (
                  <div key={l} style={{ background: "var(--bg-elev)", borderRadius: 9, padding: "8px 10px" }}>
                    <div className="text-faint" style={{ fontSize: 10.5 }}>{l}</div>
                    <div className="mono-numeric" style={{ fontWeight: 600, fontSize: 13 }}>{v}</div>
                  </div>
                ))}
              </div>

              {/* Status de vínculo (Fase A) */}
              <div style={{ display: "flex", alignItems: "center", gap: 8, background: "var(--bg-elev)", borderRadius: 10, padding: "9px 12px", marginBottom: 16 }}>
                <I name="link" size={14} className={product.produto_mestre_id ? "text-success" : "text-faint"} />
                <div style={{ flex: 1, fontSize: 12.5 }}>
                  {product.produto_mestre_id
                    ? <>Vinculado a: <b>{product.mestre_titulo || "um produto do seu catálogo"}</b></>
                    : <span className="text-muted">Sem vínculo. Vincule pra somar este anúncio com os outros do mesmo produto.</span>}
                </div>
              </div>

              {(a.pontos_fortes || []).length > 0 && (
                <div style={{ marginBottom: 14 }}>
                  <div style={{ fontWeight: 700, fontSize: 12.5, marginBottom: 6, display: "flex", alignItems: "center", gap: 6 }}><I name="thumbs-up" size={14} className="text-success" /> Pontos fortes</div>
                  {a.pontos_fortes.map((p, i) => <div key={i} className="text-muted" style={{ fontSize: 12.5, padding: "3px 0", display: "flex", gap: 6 }}><I name="check" size={13} className="text-success" /> {p}</div>)}
                </div>
              )}
              {(a.pontos_fracos || []).length > 0 && (
                <div style={{ marginBottom: 14 }}>
                  <div style={{ fontWeight: 700, fontSize: 12.5, marginBottom: 6, display: "flex", alignItems: "center", gap: 6 }}><I name="alert-triangle" size={14} className="text-danger" /> Pontos a melhorar</div>
                  {a.pontos_fracos.map((p, i) => <div key={i} className="text-muted" style={{ fontSize: 12.5, padding: "3px 0", display: "flex", gap: 6 }}><I name="minus" size={13} className="text-danger" /> {p}</div>)}
                </div>
              )}

              {(a.acoes || []).length > 0 && (
                <div>
                  <div style={{ fontWeight: 700, fontSize: 12.5, marginBottom: 8, display: "flex", alignItems: "center", gap: 6 }}><I name="list-checks" size={14} className="text-orange" /> O que fazer</div>
                  <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                    {a.acoes.map((ac, i) => (
                      <div key={i} style={{ background: "var(--bg-elev)", borderRadius: 10, padding: 12 }}>
                        <div style={{ fontWeight: 600, fontSize: 13 }}>{i + 1}. {ac.titulo}</div>
                        <div className="text-muted" style={{ fontSize: 12.5, marginTop: 3, lineHeight: 1.5 }}>{ac.o_que_fazer}</div>
                        {ac.impacto && <Chip tone="orange" style={{ marginTop: 6 }}>{ac.impacto}</Chip>}
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {pr.permalink && <div style={{ marginTop: 18 }}><a href={pr.permalink} target="_blank" rel="noreferrer" className="text-orange" style={{ fontSize: 12.5, fontWeight: 600 }}>Ver anúncio no Mercado Livre →</a></div>}
            </>
          )}
        </div>
      </div>
    </div>
  );
}

/* Seletor de canal/loja — hoje 1 canal; escala para Shopee/TikTok e multi-loja */
const MK_LABEL = { mercado_livre: "Mercado Livre", shopee: "Shopee", tiktok: "TikTok Shop" };

/* Switcher de loja (multi-loja Fase 1): o chip do topo lista as lojas e troca o contexto. */
function StoreSwitcher({ store, setPage, setSettingsTab }) {
  const [open, setOpen] = useState(false);
  const [accounts, setAccounts] = useState([]);
  useEffect(() => { window.VendusCopilot.getAccounts().then(setAccounts); }, []);
  const sel = window.VendusCopilot.getActiveAccount();
  const consolidado = sel === "todas";
  const ativo = consolidado ? "todas" : ((store && store.account_id) || sel);
  const nome = consolidado ? "Todas as lojas" : ((store && store.nickname) || "Sua loja");
  const conectarOutra = () => { setOpen(false); window.VendusCopilot.connectStore().then((r) => { if (!r.ok) window.vendusToast && window.vendusToast(r.error, { icon: "alert-triangle", tone: "warning" }); }); };
  return (
    <div style={{ position: "relative", margin: "12px 12px 6px" }}>
      <button onClick={() => setOpen((o) => !o)} title="Trocar de loja"
        style={{ width: "100%", padding: "10px 12px", display: "flex", alignItems: "center", gap: 10, background: "var(--bg-elev)", border: "1px solid " + (open ? "var(--primary)" : "var(--border)"), borderRadius: 10, cursor: "pointer", textAlign: "left" }}>
        <div style={{ width: 28, height: 28, borderRadius: 7, background: "var(--logo-gradient)", display: "grid", placeItems: "center", color: "white" }}><I name={consolidado ? "layers" : "store"} size={14} /></div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontWeight: 600, fontSize: 12.5, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{nome}</div>
          <div className="text-faint" style={{ fontSize: 11 }}>{consolidado ? `${accounts.length} lojas somadas` : (MK_LABEL[store && store.marketplace] || "Mercado Livre") + (accounts.length > 1 ? ` · ${accounts.length} lojas` : " · conectada")}</div>
        </div>
        <I name="chevrons-up-down" size={14} className="text-faint" />
      </button>
      {open && (
        <div className="fade-in" style={{ position: "absolute", top: "100%", left: 0, right: 0, marginTop: 4, background: "var(--bg-surface)", border: "1px solid var(--border)", borderRadius: 10, boxShadow: "0 12px 32px rgba(0,0,0,.4)", zIndex: 50, overflow: "hidden" }}>
          {accounts.length > 1 && (
            <button onClick={() => { if (!consolidado) window.VendusCopilot.setActiveAccount("todas"); else setOpen(false); }}
              className="navbtn" style={{ width: "100%", textAlign: "left", padding: "9px 12px", display: "flex", alignItems: "center", gap: 8, fontSize: 12.5, background: "transparent", border: "none", cursor: "pointer", color: "var(--fg-1)", borderBottom: "1px solid var(--border)" }}>
              <I name={consolidado ? "check" : "layers"} size={13} className={consolidado ? "text-success" : "text-faint"} />
              <span style={{ flex: 1, fontWeight: 600 }}>Todas as lojas</span>
              <span className="text-faint" style={{ fontSize: 10.5 }}>consolidado</span>
            </button>
          )}
          <div className="text-faint" style={{ fontSize: 10, padding: "8px 12px 4px", textTransform: "uppercase", letterSpacing: ".06em" }}>Suas lojas</div>
          {accounts.map((a) => (
            <button key={a.id} onClick={() => { if (a.id !== ativo) window.VendusCopilot.setActiveAccount(a.id); else setOpen(false); }}
              className="navbtn" style={{ width: "100%", textAlign: "left", padding: "8px 12px", display: "flex", alignItems: "center", gap: 8, fontSize: 12.5, background: "transparent", border: "none", cursor: "pointer", color: "var(--fg-1)" }}>
              <I name={a.id === ativo ? "check" : "store"} size={13} className={a.id === ativo ? "text-success" : "text-faint"} />
              <span style={{ flex: 1, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{a.nome}</span>
              <span className="text-faint" style={{ fontSize: 10.5 }}>{MK_LABEL[a.marketplace] || a.marketplace}</span>
            </button>
          ))}
          <div style={{ borderTop: "1px solid var(--border)" }}>
            <button onClick={conectarOutra} className="navbtn" style={{ width: "100%", textAlign: "left", padding: "9px 12px", display: "flex", alignItems: "center", gap: 8, fontSize: 12.5, background: "transparent", border: "none", cursor: "pointer", color: "var(--primary)", fontWeight: 600 }}>
              <I name="plus" size={13} /> Conectar outra loja
            </button>
            <button onClick={() => { setOpen(false); setPage("stores"); }} className="navbtn" style={{ width: "100%", textAlign: "left", padding: "9px 12px", display: "flex", alignItems: "center", gap: 8, fontSize: 12, background: "transparent", border: "none", cursor: "pointer", color: "var(--fg-2)" }}>
              <I name="settings-2" size={13} /> Gerenciar lojas
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
function ChannelFilter({ store, value, onChange }) {
  const channels = store && store.connected ? [{ id: store.account_id || "ml", label: `${MK_LABEL[store.marketplace] || "Mercado Livre"} · ${store.nickname}` }] : [];
  return (
    <select className="input" value={value} onChange={(e) => onChange(e.target.value)} style={{ maxWidth: 240 }} title="Filtrar por canal/loja">
      <option value="all">Todos os canais</option>
      {channels.map((c) => <option key={c.id} value={c.id}>{c.label}</option>)}
    </select>
  );
}

const PROD_FILTROS = [
  ["todos", "Todos", "Todo o catálogo"],
  ["sem_custo", "Sem custo", "Produtos sem custo cadastrado — margem no escuro"],
  ["estoque_baixo", "Estoque baixo", "Vai zerar em ~7 dias no ritmo atual"],
  ["zerados", "Zerados", "Estoque 0 — anúncio no ar sem poder vender"],
  ["curva_a", "Curva A", "Seus campeões de venda"],
  ["margem_baixa", "Margem baixa (<15%)", "Margem abaixo de 15% — sobra pouco"],
];
const PROD_ORDENAR = [["vendidos", "Mais vendidos"], ["pct_receita", "% da receita"], ["margem", "Margem"], ["estoque", "Estoque"], ["cobertura", "Cobertura"], ["preco", "Preço"], ["nome", "Nome (A–Z)"]];
const CURVA_META = { A: { tone: "warning", cor: "var(--primary)" }, B: { tone: "violet", cor: "#A78BFA" }, C: { tone: "default", cor: "var(--fg-3)" } };
const POR_PAGINA = 25;
// Tooltips em linguagem de gente (MICROTEXTOS-MODULO-PRODUTOS.md)
const PROD_TIP = {
  curva: "Mostra o que mais pesa no seu faturamento. A = seus campeões (juntos fazem a maior parte das vendas). B = vendem bem. C = vendem pouco. Cuide dos A como ouro: se um deles falha, a loja sente.",
  vendas: "Quanto esse produto vendeu nos últimos 30 dias — em unidades e em reais. É a régua de quem realmente puxa a receita.",
  pct: "Quanto esse produto representa do seu faturamento. Se um só passa de 50%, é sinal de risco: você depende demais dele.",
  estoque: "Quantas unidades você tem agora. Abaixo, a cobertura: por quantos dias o estoque aguenta no ritmo de venda atual.",
  cobertura: "Por quantos dias o estoque atual aguenta no ritmo de venda de agora. ~8 dias = repõe logo. Muitos meses = dinheiro parado em estoque. 'Sem giro p/ estimar' = vendeu pouco pra calcular.",
  margem: "O que sobra de cada venda depois do custo do produto (ainda sem as taxas do marketplace). Verde = saudável, amarelo = apertada, vermelho = quase no zero. Cadastre o custo pra ela aparecer.",
  custo: "Quanto você paga ao fornecedor por unidade. É o que falta pra calcular sua margem real — preencha aqui ou importe pela planilha.",
  semdado: "ainda não temos esse dado",
};
const PROD_CARD_TIP = { todos: "Total no seu catálogo", sem_custo: "Sem isso, não dá pra saber a margem", estoque_baixo: "Podem zerar e sumir da busca", curva_a: "Os que fazem a maior parte da venda" };
// Estado vazio conforme o filtro/busca ativos
function prodVazio(filtro, temBusca) {
  if (temBusca) return { titulo: "Nenhum produto encontrado", desc: "Tente outro nome ou SKU, ou limpe a busca." };
  if (filtro === "sem_custo") return { titulo: "Tudo com custo cadastrado 🎉", desc: "Sua margem real está completa — o Copiloto consegue calcular tudo." };
  if (filtro === "zerados") return { titulo: "Nenhum produto zerado", desc: "Seu estoque está cobrindo a demanda. Continue de olho na cobertura." };
  if (filtro === "estoque_baixo") return { titulo: "Nenhum estoque crítico agora", desc: "Nada prestes a zerar — bom momento pra focar em vender." };
  if (filtro === "margem_baixa") return { titulo: "Nenhuma margem no vermelho", desc: "Os produtos com custo cadastrado estão saudáveis." };
  if (filtro === "curva_a") return { titulo: "Nenhum campeão por aqui", desc: "Ainda não há produtos de Curva A no período." };
  return { titulo: "Nenhum produto com esses filtros", desc: "Ajuste a busca ou os filtros acima." };
}

function RealProducts({ store }) {
  const [items, setItems] = useState(null);
  const [edits, setEdits] = useState({});
  const [saving, setSaving] = useState(false);
  const [analysis, setAnalysis] = useState(null);
  const [canal, setCanal] = useState("all");
  const [busca, setBusca] = useState("");
  const [filtro, setFiltro] = useState("todos");
  const [marketplaceF, setMarketplaceF] = useState("all");
  const [marcaF, setMarcaF] = useState("all");
  const [ordenar, setOrdenar] = useState("vendidos");
  const [dir, setDir] = useState("desc");
  const [pagina, setPagina] = useState(1);
  const fileRef = useRef(null);
  function load() { window.VendusCopilot.getProducts().then(setItems); }
  useEffect(() => { load(); }, []);
  useEffect(() => { setPagina(1); }, [busca, filtro, marketplaceF, marcaF, ordenar, dir]);

  async function analisar(p) {
    setAnalysis({ product: p, loading: true });
    const r = await window.VendusCopilot.getProductAnalysis(p.ml_item_id);
    setAnalysis({ product: p, loading: false, ...r });
  }

  function custoAtual(p) {
    const e = edits[p.ml_item_id];
    if (e !== undefined) { const n = Number(String(e).replace(",", ".")); return Number.isNaN(n) ? null : n; }
    return p.custo;
  }
  async function salvar() {
    const costs = Object.entries(edits).filter(([, v]) => String(v).trim() !== "").map(([ml_item_id, custo]) => ({ ml_item_id, custo }));
    if (!costs.length) return;
    setSaving(true);
    const r = await window.VendusCopilot.saveCosts(costs);
    setSaving(false);
    if (r.ok) { window.vendusToast && window.vendusToast(`${r.updated} custo(s) salvos ✓`, { icon: "check-check", tone: "success" }); setEdits({}); load(); }
    else window.vendusToast && window.vendusToast(r.error, { icon: "alert-triangle", tone: "danger" });
  }
  function exportarCsv() {
    const rows = [["ml_item_id", "sku", "titulo", "preco", "estoque", "custo"]];
    (items || []).forEach((p) => rows.push([p.ml_item_id, p.sku || "", String(p.titulo || "").replace(/[\n;]/g, " "), p.preco ?? "", p.estoque ?? "", p.custo ?? ""]));
    const csv = rows.map((r) => r.join(";")).join("\n");
    const blob = new Blob(["﻿" + csv], { type: "text/csv;charset=utf-8" });
    const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = "produtos-vendus.csv"; a.click();
  }
  async function importarCsv(e) {
    const file = e.target.files && e.target.files[0]; if (!file) return;
    const text = await file.text();
    const lines = text.replace(/﻿/g, "").split(/\r?\n/).filter((l) => l.trim());
    if (!lines.length) return;
    const sep = lines[0].includes(";") ? ";" : ",";
    const header = lines[0].split(sep).map((h) => h.trim().toLowerCase());
    const iId = header.indexOf("ml_item_id"), iSku = header.indexOf("sku"), iCusto = header.indexOf("custo");
    if (iCusto === -1) { window.vendusToast && window.vendusToast("A planilha precisa de uma coluna 'custo'.", { icon: "alert-triangle", tone: "warning" }); fileRef.current.value = ""; return; }
    const costs = [];
    for (let i = 1; i < lines.length; i++) {
      const c = lines[i].split(sep); const custo = (c[iCusto] || "").trim(); if (!custo) continue;
      const ml_item_id = iId >= 0 ? (c[iId] || "").trim() : ""; const sku = iSku >= 0 ? (c[iSku] || "").trim() : "";
      if (ml_item_id) costs.push({ ml_item_id, custo }); else if (sku) costs.push({ sku, custo });
    }
    fileRef.current.value = "";
    if (!costs.length) { window.vendusToast && window.vendusToast("Nenhum custo preenchido na planilha.", { icon: "info", tone: "default" }); return; }
    setSaving(true); const r = await window.VendusCopilot.saveCosts(costs); setSaving(false);
    if (r.ok) { window.vendusToast && window.vendusToast(`${r.updated} custos importados ✓`, { icon: "check-check", tone: "success" }); load(); }
    else window.vendusToast && window.vendusToast(r.error, { icon: "alert-triangle", tone: "danger" });
  }

  const margemDe = (p) => { const cv = custoAtual(p); return cv != null && p.preco ? ((p.preco - cv) / p.preco) * 100 : null; };
  // Estoque baixo = vai zerar em < 7 dias no ritmo atual (cobertura). Sem giro pra estimar → cai pro critério de unidades (<5).
  const estoqueBaixo = (p) => (p.cobertura_dias != null ? p.cobertura_dias < 7 : (p.estoque != null && p.estoque < 5));
  const lista = items || [];
  const semCusto = lista.filter((p) => custoAtual(p) == null).length;
  const estoqueBaixoN = lista.filter(estoqueBaixo).length;
  const curvaAN = lista.filter((p) => p.curva === "A").length;
  const pendentes = Object.keys(edits).length;

  function passaFiltro(p) {
    if (filtro === "sem_custo") return custoAtual(p) == null;
    if (filtro === "estoque_baixo") return estoqueBaixo(p);
    if (filtro === "zerados") return p.estoque === 0;
    if (filtro === "curva_a") return p.curva === "A";
    if (filtro === "margem_baixa") { const m = margemDe(p); return m != null && m < 15; }
    return true;
  }
  // opções de marketplace/marca presentes no catálogo (Fase A — vínculo)
  const MK_NOME = { mercado_livre: "Mercado Livre", shopee: "Shopee", tiktok: "TikTok Shop" };
  const marketplaces = [...new Set(lista.map((p) => p.marketplace).filter(Boolean))];
  const marcas = [...new Set(lista.map((p) => p.marca).filter(Boolean))].sort();
  const q = busca.trim().toLowerCase();
  function sortVal(p) {
    if (ordenar === "vendidos") return p.unidades_periodo || 0;
    if (ordenar === "pct_receita") return p.pct_receita || 0;
    if (ordenar === "margem") return margemDe(p);
    if (ordenar === "estoque") return p.estoque;
    if (ordenar === "cobertura") return p.cobertura_dias;
    if (ordenar === "preco") return p.preco;
    return 0;
  }
  const filtrados = lista.filter((p) => {
    if (q && !(`${p.titulo || ""} ${p.sku || ""}`.toLowerCase().includes(q))) return false;
    if (marketplaceF !== "all" && (p.marketplace || "") !== marketplaceF) return false;
    if (marcaF !== "all" && (p.marca || "") !== marcaF) return false;
    return passaFiltro(p);
  });
  const ordenados = [...filtrados].sort((a, b) => {
    if (ordenar === "nome") return (dir === "asc" ? 1 : -1) * String(a.titulo || "").localeCompare(String(b.titulo || ""));
    const va = sortVal(a), vb = sortVal(b);
    if (va == null && vb == null) return 0;
    if (va == null) return 1; if (vb == null) return -1; // sem dado sempre por último
    return (dir === "asc" ? 1 : -1) * (va - vb);
  });
  const totalPaginas = Math.max(1, Math.ceil(ordenados.length / POR_PAGINA));
  const pag = Math.min(pagina, totalPaginas);
  const visiveis = ordenados.slice((pag - 1) * POR_PAGINA, pag * POR_PAGINA);
  function ordenarPor(k) { if (k === ordenar) setDir((d) => (d === "asc" ? "desc" : "asc")); else { setOrdenar(k); setDir(k === "nome" || k === "cobertura" ? "asc" : "desc"); } }
  const seta = (k) => (ordenar === k ? (dir === "asc" ? " ▲" : " ▼") : "");

  const cards = [
    { rotulo: "Produtos", valor: lista.length, f: "todos" },
    { rotulo: "Sem custo", valor: semCusto, f: "sem_custo", cor: semCusto > 0 ? "#FF6A6A" : undefined },
    { rotulo: "Estoque baixo", valor: estoqueBaixoN, f: "estoque_baixo", cor: estoqueBaixoN > 0 ? "#FB923C" : undefined },
    { rotulo: "Campeões", valor: curvaAN, f: "curva_a", cor: "var(--primary)" },
  ];
  const campeao = lista.filter((p) => p.curva).sort((a, b) => (b.pct_receita || 0) - (a.pct_receita || 0))[0];
  const campeaoSemCusto = !!(campeao && custoAtual(campeao) == null);

  return (
    <div className="page fade-in">
      <div className="page-header">
        <div>
          <Eyebrow>Catálogo</Eyebrow>
          <h1 className="page-title">Produtos</h1>
          <div className="page-sub">{items ? `${lista.length} produtos · ${semCusto} sem custo cadastrado` : "Carregando…"}</div>
        </div>
        <div style={{ display: "flex", gap: 8, flexWrap: "wrap", justifyContent: "flex-end", alignItems: "center" }}>
          <ChannelFilter store={store} value={canal} onChange={setCanal} />
          <input ref={fileRef} type="file" accept=".csv,text/csv" style={{ display: "none" }} onChange={importarCsv} />
          <Btn variant="ghost" onClick={exportarCsv}><I name="download" size={14} /> Exportar planilha</Btn>
          <Btn variant="secondary" onClick={() => fileRef.current && fileRef.current.click()}><I name="upload" size={14} /> Importar custos</Btn>
          {pendentes > 0 && <Btn variant="primary" onClick={salvar} disabled={saving}><I name="check" size={14} /> {saving ? "Salvando…" : `Salvar ${pendentes} custo(s)`}</Btn>}
        </div>
      </div>

      {!items ? <Card padding={24}><div className="text-muted">Carregando…</div></Card>
        : lista.length === 0 ? <EmptyState icon="package" title="Nenhum produto sincronizado ainda" desc="Clique em Sincronizar nas Configurações para puxar seu catálogo." />
        : (
        <>
          {/* Faixa de resumo — KPIs clicáveis (aplicam filtro) */}
          <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 12, marginBottom: 14 }}>
            {cards.map((c) => (
              <button key={c.rotulo} title={PROD_CARD_TIP[c.f] || ""} onClick={() => setFiltro(c.f)} style={{ textAlign: "left", cursor: "pointer", background: filtro === c.f ? "rgba(249,115,22,.10)" : "var(--bg-elev)", border: "1px solid " + (filtro === c.f ? "var(--primary)" : "var(--border)"), borderRadius: 12, padding: "12px 14px" }}>
                <div className="text-faint" style={{ fontSize: 11 }}>{c.rotulo}</div>
                <div className="font-display mono-numeric" style={{ fontSize: 24, fontWeight: 800, color: c.cor || "var(--fg-1)", marginTop: 2 }}>{c.valor}</div>
              </button>
            ))}
          </div>

          {semCusto > 0 && (
            <div className="banner" style={{ marginBottom: 14 }}>
              <I name="info" size={18} className="text-orange" />
              <div className="text-muted" style={{ fontSize: 13, flex: 1, lineHeight: 1.5 }}>
                {campeaoSemCusto
                  ? <><b>Seu produto que mais vende ainda está sem custo.</b> É a margem mais importante da loja e está no escuro — cadastre o custo dele primeiro.</>
                  : <><b>{semCusto} produto(s) sem custo.</b> Preencha pra ver sua <b>margem real</b> — comece pelos que mais vendem.</>}
              </div>
            </div>
          )}

          {/* Barra de ferramentas: busca + filtros + ordenação */}
          <Card padding={14} style={{ marginBottom: 14 }}>
            <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap" }}>
              <div style={{ position: "relative", flex: "1 1 240px", minWidth: 200 }}>
                <I name="search" size={14} style={{ position: "absolute", left: 10, top: "50%", transform: "translateY(-50%)", color: "var(--fg-3)" }} />
                <input className="input" placeholder="Buscar por título ou SKU…" value={busca} onChange={(e) => setBusca(e.target.value)} style={{ width: "100%", paddingLeft: 32 }} />
              </div>
              {marketplaces.length > 1 && (
                <select className="input" value={marketplaceF} onChange={(e) => setMarketplaceF(e.target.value)} style={{ width: 160 }} title="Filtrar por marketplace">
                  <option value="all">Todos os canais</option>
                  {marketplaces.map((m) => <option key={m} value={m}>{MK_NOME[m] || m}</option>)}
                </select>
              )}
              {marcas.length > 0 && (
                <select className="input" value={marcaF} onChange={(e) => setMarcaF(e.target.value)} style={{ width: 150 }} title="Filtrar por marca (do produto-mestre)">
                  <option value="all">Todas as marcas</option>
                  {marcas.map((m) => <option key={m} value={m}>{m}</option>)}
                </select>
              )}
              <label style={{ fontSize: 12, color: "var(--fg-2)", display: "flex", alignItems: "center", gap: 6 }}>
                Ordenar por
                <select className="input" value={ordenar} onChange={(e) => ordenarPor(e.target.value)} style={{ width: 150 }}>
                  {PROD_ORDENAR.map(([k, l]) => <option key={k} value={k}>{l}</option>)}
                </select>
              </label>
            </div>
            <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginTop: 10 }}>
              {PROD_FILTROS.map(([k, l, tip]) => (
                <button key={k} title={tip} onClick={() => setFiltro(k)} className="chip-btn" style={{ padding: "6px 11px", borderRadius: 9, fontSize: 12, fontWeight: 600, cursor: "pointer", border: "1px solid " + (filtro === k ? "var(--primary)" : "var(--border)"), background: filtro === k ? "rgba(249,115,22,.12)" : "transparent", color: filtro === k ? "var(--primary)" : "var(--fg-2)" }}>{l}</button>
              ))}
            </div>
          </Card>

          <Card padding={0}>
            <table className="tbl">
              <thead><tr>
                <th style={{ cursor: "pointer" }} onClick={() => ordenarPor("nome")}>Produto{seta("nome")}</th>
                <th>SKU</th>
                <th className="num" title={PROD_TIP.vendas} style={{ cursor: "pointer" }} onClick={() => ordenarPor("vendidos")}>Vendas (30d){seta("vendidos")}</th>
                <th className="num" title={PROD_TIP.pct} style={{ cursor: "pointer" }} onClick={() => ordenarPor("pct_receita")}>% receita{seta("pct_receita")}</th>
                <th className="num" style={{ cursor: "pointer" }} onClick={() => ordenarPor("preco")}>Preço{seta("preco")}</th>
                <th className="num" title={PROD_TIP.custo}>Custo</th>
                <th className="num" title={PROD_TIP.margem} style={{ cursor: "pointer" }} onClick={() => ordenarPor("margem")}>Margem{seta("margem")}</th>
                <th className="num" title={PROD_TIP.estoque} style={{ cursor: "pointer" }} onClick={() => ordenarPor("estoque")}>Estoque{seta("estoque")}</th>
                <th></th>
              </tr></thead>
              <tbody>
                {visiveis.map((p) => {
                  const cv = custoAtual(p);
                  const margem = cv != null && p.preco ? ((p.preco - cv) / p.preco) * 100 : null;
                  const cm = CURVA_META[p.curva];
                  return (
                  <tr key={p.ml_item_id}>
                    <td style={{ maxWidth: 280 }}>
                      <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
                        {p.curva && <span title={PROD_TIP.curva}><Chip tone={cm.tone}>{p.curva}</Chip></span>}
                        {p.produto_mestre_id && <span title={`Vinculado ao seu catálogo${p.mestre_titulo ? ` (${p.mestre_titulo})` : ""} — as vendas deste produto somam todos os anúncios.`} style={{ display: "inline-flex", color: "var(--success-soft, #4ADE80)" }}><I name="link" size={12} /></span>}
                        <span style={{ fontWeight: 500, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", cursor: "pointer" }} onClick={() => analisar(p)} title="Analisar com IA">{p.titulo}</span>
                      </div>
                    </td>
                    <td className="text-muted" style={{ fontSize: 12 }}>{p.sku || "—"}</td>
                    <td className="num mono-numeric">{p.unidades_periodo > 0 ? <span><b>{p.unidades_periodo}</b> un · {brl(p.receita_periodo)}</span> : <span className="text-faint" title={PROD_TIP.semdado}>—</span>}</td>
                    <td className="num">{p.pct_receita != null ? (
                      <div style={{ display: "flex", alignItems: "center", gap: 6, justifyContent: "flex-end" }}>
                        <div style={{ width: 44, height: 5, borderRadius: 99, background: "var(--bg-elev)", overflow: "hidden" }}><div style={{ width: Math.min(100, p.pct_receita) + "%", height: "100%", background: p.curva === "A" ? "var(--primary)" : "var(--fg-3)" }} /></div>
                        <span className="mono-numeric" style={{ fontWeight: 600, fontSize: 12.5 }}>{p.pct_receita}%</span>
                      </div>
                    ) : <span className="text-faint" title={PROD_TIP.semdado}>—</span>}</td>
                    <td className="num mono-numeric font-display" style={{ fontWeight: 700 }}>{brl(p.preco)}</td>
                    <td className="num">
                      <input className="input" inputMode="decimal" placeholder="0,00"
                        value={edits[p.ml_item_id] !== undefined ? edits[p.ml_item_id] : (p.custo != null ? String(p.custo).replace(".", ",") : "")}
                        onChange={(e) => setEdits((s) => ({ ...s, [p.ml_item_id]: e.target.value }))}
                        style={{ width: 84, textAlign: "right", padding: "6px 8px", borderColor: cv == null ? "rgba(251,146,60,.5)" : undefined }} />
                    </td>
                    <td className="num mono-numeric" title={margem == null ? PROD_TIP.semdado : PROD_TIP.margem} style={{ color: margem == null ? "var(--fg-3)" : margem < 15 ? "#FF6A6A" : margem < 30 ? "#FACC15" : "#4ADE80", fontWeight: 600 }}>{margem == null ? "—" : margem.toFixed(0) + "%"}</td>
                    <td className="num">
                      <div style={{ display: "flex", flexDirection: "column", alignItems: "flex-end", gap: 1 }}>
                        <Chip tone={p.estoque == null ? "default" : p.estoque < 5 ? "danger" : p.estoque < 20 ? "warning" : "success"}>{p.estoque ?? "—"}</Chip>
                        <span className="text-faint" title={PROD_TIP.cobertura} style={{ fontSize: 10.5 }}>{p.cobertura_dias != null ? `~${p.cobertura_dias} dias` : (p.unidades_periodo > 0 ? "sem giro p/ estimar" : "")}</span>
                      </div>
                    </td>
                    <td className="num"><Btn size="sm" variant="ghost" onClick={() => analisar(p)} title="Analisar com IA"><I name="sparkles" size={14} /></Btn></td>
                  </tr>
                );})}
                {visiveis.length === 0 && (() => { const ev = prodVazio(filtro, !!q); return (
                  <tr><td colSpan={9} style={{ padding: 28, textAlign: "center" }}>
                    <div style={{ fontWeight: 700, fontSize: 14 }}>{ev.titulo}</div>
                    <div className="text-muted" style={{ fontSize: 12.5, marginTop: 4 }}>{ev.desc}</div>
                  </td></tr>
                ); })()}
              </tbody>
            </table>
            {totalPaginas > 1 && (
              <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "10px 16px", borderTop: "1px solid var(--border)" }}>
                <span className="text-faint" style={{ fontSize: 12 }}>Mostrando {(pag - 1) * POR_PAGINA + 1}–{Math.min(pag * POR_PAGINA, ordenados.length)} de {ordenados.length}</span>
                <div style={{ display: "flex", gap: 6 }}>
                  <Btn variant="ghost" size="sm" onClick={() => setPagina((n) => Math.max(1, n - 1))} disabled={pag <= 1}><I name="chevron-left" size={14} /> Anterior</Btn>
                  <Btn variant="ghost" size="sm" onClick={() => setPagina((n) => Math.min(totalPaginas, n + 1))} disabled={pag >= totalPaginas}>Próxima <I name="chevron-right" size={14} /></Btn>
                </div>
              </div>
            )}
          </Card>
        </>
      )}
      <ProductDrawer state={analysis} onClose={() => setAnalysis(null)} />
    </div>
  );
}

/* Vendas reais — com filtros de período */
const SALES_RANGES = [["hoje", "Hoje"], ["7", "7 dias"], ["30", "30 dias"], ["tudo", "Tudo"], ["custom", "Personalizado"]];
function RealSales({ store }) {
  const [data, setData] = useState(null);
  const [range, setRange] = useState("30");
  const [from, setFrom] = useState("");
  const [to, setTo] = useState("");
  const [canal, setCanal] = useState("all");
  useEffect(() => { window.VendusCopilot.getSales().then(setData); }, []);
  const allOrders = (data && data.orders) || [];

  const orders = useMemo(() => {
    if (!data) return [];
    const now = new Date();
    let start = null, end = null;
    if (range === "hoje") start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
    else if (range === "7") { start = new Date(now); start.setDate(now.getDate() - 7); }
    else if (range === "30") { start = new Date(now); start.setDate(now.getDate() - 30); }
    else if (range === "custom") { start = from ? new Date(from) : null; end = to ? new Date(to + "T23:59:59") : null; }
    return allOrders.filter((o) => {
      if (!o.data) return false;
      const d = new Date(o.data);
      if (start && d < start) return false;
      if (end && d > end) return false;
      return true;
    });
  }, [data, range, from, to]);

  const k = useMemo(() => {
    const sum = (f) => orders.reduce((s, o) => s + (Number(o[f]) || 0), 0);
    const bruta = sum("receita_bruta");
    return { pedidos: orders.length, bruta, liquida: sum("receita_liquida"), comissao: sum("comissao"), frete: sum("frete"), impostos: sum("impostos"), taxas: sum("taxas"), ticket: orders.length ? bruta / orders.length : 0 };
  }, [orders]);

  return (
    <div className="page fade-in">
      <div className="page-header">
        <div>
          <Eyebrow>Vendas</Eyebrow>
          <h1 className="page-title">Vendas</h1>
          <div className="page-sub">{data ? `${k.pedidos} pedidos no período` : "Carregando…"}</div>
        </div>
        <div style={{ display: "flex", gap: 8, alignItems: "center", flexWrap: "wrap", justifyContent: "flex-end" }}>
          <ChannelFilter store={store} value={canal} onChange={setCanal} />
          <div className="seg">
            {SALES_RANGES.map(([k2, l]) => <button key={k2} onClick={() => setRange(k2)} className={range === k2 ? "active" : ""}>{l}</button>)}
          </div>
        </div>
      </div>

      {range === "custom" && (
        <div style={{ display: "flex", gap: 12, alignItems: "flex-end", marginBottom: 16, flexWrap: "wrap" }}>
          <label style={{ fontSize: 12 }}><div className="text-muted" style={{ marginBottom: 4 }}>De</div><input type="date" className="input" value={from} onChange={(e) => setFrom(e.target.value)} /></label>
          <label style={{ fontSize: 12 }}><div className="text-muted" style={{ marginBottom: 4 }}>Até</div><input type="date" className="input" value={to} onChange={(e) => setTo(e.target.value)} /></label>
        </div>
      )}

      {!data ? <Card padding={24}><div className="text-muted">Carregando…</div></Card> : (
        <>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 16, marginBottom: 16 }}>
            <Card className="kpi kpi-orange" padding={18}><div className="kpi-icon"><I name="shopping-cart" size={18}/></div><div className="kpi-label">Pedidos</div><div className="kpi-value">{k.pedidos}</div></Card>
            <Card className="kpi kpi-success" padding={18}><div className="kpi-icon"><I name="banknote" size={18}/></div><div className="kpi-label">Receita bruta</div><div className="kpi-value">{brl(k.bruta)}</div></Card>
            <Card className="kpi kpi-info" padding={18}><div className="kpi-icon"><I name="trending-up" size={18}/></div><div className="kpi-label">Receita líquida</div><div className="kpi-value">{brl(k.liquida)}</div></Card>
            <Card className="kpi" padding={18}><div className="kpi-icon"><I name="receipt" size={18}/></div><div className="kpi-label">Ticket médio</div><div className="kpi-value">{brl(k.ticket)}</div></Card>
          </div>

          {/* Quanto saiu em taxas no período */}
          <Card style={{ marginBottom: 16 }} padding={16}>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 10 }}>
              <I name="percent" size={15} className="text-orange" />
              <span style={{ fontWeight: 700, fontSize: 13.5 }}>O que saiu em taxas no período</span>
              <span className="text-faint" style={{ fontSize: 12 }}>· puxado de cada venda no Mercado Livre</span>
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 12 }}>
              {[["Comissão ML", k.comissao, "megaphone"], ["Frete (você paga)", k.frete, "truck"], ["Impostos", k.impostos, "landmark"], ["Total de taxas", k.taxas, "percent"]].map(([l, v, ic], i) => (
                <div key={l} style={{ display: "flex", flexDirection: "column", gap: 2, padding: "8px 10px", background: "var(--bg-elev)", borderRadius: 10 }}>
                  <span className="text-faint" style={{ fontSize: 11, display: "flex", alignItems: "center", gap: 5 }}><I name={ic} size={12} /> {l}</span>
                  <span className="font-display mono-numeric" style={{ fontWeight: 700, fontSize: 16, color: i === 3 ? "var(--primary)" : "var(--fg-1)" }}>{brl(v)}</span>
                  {k.bruta > 0 && <span className="text-faint" style={{ fontSize: 10.5 }}>{((Number(v) / k.bruta) * 100).toFixed(1)}% da receita</span>}
                </div>
              ))}
            </div>
          </Card>

          {orders.length === 0 ? <EmptyState icon="shopping-cart" title="Nenhum pedido neste período" desc="Ajuste o filtro de período acima." /> : (
            <Card padding={0}>
              <table className="tbl">
                <thead><tr><th>Pedido</th><th>Data</th><th>Status</th><th className="num">Bruto</th><th className="num">Comissão</th><th className="num">Frete</th><th className="num">Impostos</th><th className="num">Líquido</th></tr></thead>
                <tbody>
                  {orders.map((o) => (
                    <tr key={o.ml_order_id}>
                      <td className="mono-numeric">#{o.ml_order_id}</td>
                      <td className="text-muted">{o.data ? new Date(o.data).toLocaleDateString("pt-BR") : "—"}</td>
                      <td><Chip tone={o.status === "paid" ? "success" : o.status === "cancelled" ? "danger" : "warning"}>{o.status}</Chip></td>
                      <td className="num mono-numeric">{brl(o.receita_bruta)}</td>
                      <td className="num mono-numeric text-danger">{o.comissao != null ? "−" + brl(o.comissao).replace("R$ ", "R$ ") : "—"}</td>
                      <td className="num mono-numeric text-danger">{o.frete != null ? "−" + brl(o.frete) : "—"}</td>
                      <td className="num mono-numeric text-danger">{o.impostos != null ? "−" + brl(o.impostos) : "—"}</td>
                      <td className="num mono-numeric font-display" style={{ fontWeight: 700 }}>{brl(o.receita_liquida)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </Card>
          )}
        </>
      )}
    </div>
  );
}

/* Dashboard real — métricas da loja conectada */
function RealDashboard({ navigate, user = {}, store }) {
  const [sales, setSales] = useState(null);
  const [products, setProducts] = useState(null);
  useEffect(() => { window.VendusCopilot.getSales().then(setSales); window.VendusCopilot.getProducts().then(setProducts); }, []);
  const nome = String(user.name || "").trim().split(/\s+/)[0] || "";
  const h = new Date().getHours();
  const saud = h < 12 ? "Bom dia" : h < 18 ? "Boa tarde" : "Boa noite";
  const k = (sales && sales.kpis) || {};
  const recent = ((sales && sales.orders) || []).slice(0, 6);
  const lowStock = (products || []).filter((p) => (p.estoque ?? 0) < 10).slice(0, 6);
  const semCusto = (products || []).filter((p) => p.custo == null).length;

  return (
    <div className="page fade-in">
      <div className="page-header">
        <div>
          <Eyebrow>Visão geral</Eyebrow>
          <h1 className="page-title">{saud}{nome ? `, ${nome}` : ""} 👋</h1>
          <div className="page-sub">{store ? `Loja ${store.nickname} · Mercado Livre` : "Sua loja"}</div>
        </div>
        <Btn variant="primary" onClick={() => navigate("copilot")}><I name="sparkles" size={14} /> Ver o Copiloto</Btn>
      </div>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 16, marginBottom: 20 }}>
        <Card className="kpi kpi-orange" padding={18}><div className="kpi-icon"><I name="banknote" size={18}/></div><div className="kpi-label">Receita bruta</div><div className="kpi-value">{brl(k.receita_bruta)}</div></Card>
        <Card className="kpi kpi-success" padding={18}><div className="kpi-icon"><I name="wallet" size={18}/></div><div className="kpi-label">Receita líquida</div><div className="kpi-value">{brl(k.receita_liquida)}</div></Card>
        <Card className="kpi kpi-info" padding={18}><div className="kpi-icon"><I name="shopping-cart" size={18}/></div><div className="kpi-label">Pedidos</div><div className="kpi-value">{k.pedidos || 0}</div></Card>
        <Card className="kpi" padding={18}><div className="kpi-icon"><I name="receipt" size={18}/></div><div className="kpi-label">Ticket médio</div><div className="kpi-value">{brl(k.ticket_medio)}</div></Card>
      </div>

      {semCusto > 0 && (
        <div className="banner" style={{ marginBottom: 20 }}>
          <div style={{ width: 36, height: 36, borderRadius: 9, background: "rgba(249,115,22,.15)", color: "var(--primary)", display: "grid", placeItems: "center", flexShrink: 0 }}><I name="percent" size={17} /></div>
          <div className="text-muted" style={{ fontSize: 13, flex: 1 }}>
            <b>{semCusto} produtos sem custo.</b> Cadastre os custos para liberar a <b>margem real</b> e análises mais precisas do Copiloto.
          </div>
          <Btn variant="secondary" size="sm" onClick={() => navigate("products")}>Cadastrar custos</Btn>
        </div>
      )}

      <div style={{ display: "grid", gridTemplateColumns: "1.4fr 1fr", gap: 16 }}>
        <Card>
          <SectionTitle title="Vendas recentes" sub="Últimos pedidos sincronizados" action={<Btn variant="ghost" size="sm" onClick={() => navigate("sales")}>Ver todas</Btn>} />
          {recent.length === 0 ? <div className="text-muted" style={{ fontSize: 13, padding: "12px 0" }}>Nenhum pedido ainda.</div> : (
            <table className="tbl"><tbody>
              {recent.map((o) => (
                <tr key={o.ml_order_id}>
                  <td className="mono-numeric">#{o.ml_order_id}</td>
                  <td className="text-muted">{o.data ? new Date(o.data).toLocaleDateString("pt-BR") : "—"}</td>
                  <td><Chip tone={o.status === "paid" ? "success" : "warning"}>{o.status}</Chip></td>
                  <td className="num mono-numeric font-display" style={{ fontWeight: 700 }}>{brl(o.receita_liquida)}</td>
                </tr>
              ))}
            </tbody></table>
          )}
        </Card>
        <Card>
          <SectionTitle title="Estoque baixo" sub="Produtos com menos de 10 un." />
          {lowStock.length === 0 ? <div className="text-muted" style={{ fontSize: 13, padding: "12px 0" }}>Nenhum produto com estoque baixo. 👍</div> : (
            <div style={{ display: "flex", flexDirection: "column", gap: 8, marginTop: 4 }}>
              {lowStock.map((p) => (
                <div key={p.ml_item_id} style={{ display: "flex", alignItems: "center", gap: 8 }}>
                  <span style={{ flex: 1, minWidth: 0, fontSize: 12.5, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{p.titulo}</span>
                  <Chip tone={p.estoque < 5 ? "danger" : "warning"}>{p.estoque ?? 0} un.</Chip>
                </div>
              ))}
            </div>
          )}
        </Card>
      </div>
    </div>
  );
}

function EmptyDashboard({ navigate, user = {}, store }) {
  const nome = String(user.name || "").trim().split(/\s+/)[0] || "";
  const h = new Date().getHours();
  const saud = h < 12 ? "Bom dia" : h < 18 ? "Boa tarde" : "Boa noite";
  const connected = store && store.connected;
  return (
    <div className="page fade-in">
      <div className="page-header">
        <div>
          <Eyebrow>Visão geral</Eyebrow>
          <h1 className="page-title">{saud}{nome ? `, ${nome}` : ""} 👋</h1>
          <div className="page-sub">{connected ? `Loja ${store.nickname} conectada ao Mercado Livre.` : "Vamos preparar sua loja. Conecte um canal de vendas para ver seus números aqui."}</div>
        </div>
      </div>
      {connected
        ? <EmptyState icon="sparkles" title={`${store.nickname} está conectada 🎉`}
            desc="O Copiloto já está analisando os dados da sua loja. Veja o resumo do dia, o score de qualidade e as ações recomendadas."
            cta="Ver o Copiloto" onCta={() => navigate("copilot")} />
        : <EmptyState icon="store" title="Sua loja está pronta para começar"
            desc="Conecte sua conta do Mercado Livre (ou outro canal) para o Vendus puxar seus pedidos, produtos e métricas automaticamente — e o Copiloto começar a analisar."
            cta="Conectar uma loja" onCta={() => navigate("settings")} />}
    </div>
  );
}

const { ProductsPage, SalesPage, CalculatorPage } = window.VendusPagesA;
const { CashFlowPage, CostsPage, SuppliersPage, StockPurchasesPage } = window.VendusPagesB;
const { StrategicPage, StoresPage, ComparativesPage, ReportsPage, GoalsPage, ForecastsPage, SettingsPage } = window.VendusPagesC;
const { RealComparatives, RealCashflow, RealCosts, RealForecasts, RealReports, RealSuppliers, RealPurchases, RealContasPagar, RealResultado, RealContasReceber } = window.VendusFinanceiro;
const { CopilotPage, AIConfigPage } = window.VendusCopiloto;
const { AdsPage } = window.VendusAds;
const { MessagesPage } = window.VendusMensagens;
const { VinculoPage } = window.VendusVinculo;
const { CatalogoPage } = window.VendusCatalogo;
const { VENDUS_PALETTES, VENDUS_FONT_PAIRS, ThemesPage, fontStack, displayStack } = window.VendusThemes;
const Dashboard = window.VendusDashboard;
const VendusAuthScreen = window.VendusAuthScreen;

const NAV = [
  { id: "dashboard", label: "Dashboard",           icon: "layout-dashboard" },
  { id: "messages",  label: "Mensagens",           icon: "message-square" },
  { id: "products",  label: "Produtos",            icon: "package" },
  { id: "catalogo",  label: "Meu catálogo",        icon: "boxes" },
  { id: "vinculo",   label: "Vincular anúncios",   icon: "link" },
  { id: "sales",     label: "Vendas",              icon: "shopping-cart" },
  { id: "calculator",label: "Calculadora",         icon: "calculator" },
];
const GROUPS = [
  {
    label: "IA Vendus", icon: "sparkles", defaultOpen: true,
    items: [
      { id: "copilot",   label: "Piloto",              icon: "compass" },
      { id: "strategic", label: "Modo Estratégico",    icon: "activity" },
      { id: "ads",       label: "Anúncios (Ads)",      icon: "megaphone" },
      { id: "aiconfig",  label: "Configurações da IA", icon: "sliders-horizontal" },
    ]
  },
  {
    label: "Lojas", icon: "store",
    items: [
      { id: "stores",       label: "Minhas lojas",  icon: "plus" },
      { id: "comparatives", label: "Comparativos",  icon: "bar-chart-3" },
    ]
  },
  {
    label: "Financeiro", icon: "wallet",
    items: [
      { id: "contas_pagar", label: "Contas a pagar", icon: "credit-card" },
      { id: "contas_receber", label: "Contas a receber", icon: "hand-coins" },
      { id: "resultado", label: "Resultado",         icon: "trending-up" },
      { id: "cashflow", label: "Fluxo de caixa",     icon: "banknote" },
      { id: "costs",    label: "Custos",             icon: "receipt" },
      { id: "suppliers",label: "Fornecedores",       icon: "users" },
      { id: "purchases",label: "Compras de estoque", icon: "shopping-bag" },
    ]
  },
  {
    label: "Análises", icon: "bar-chart",
    items: [
      { id: "reports",   label: "Relatórios",            icon: "file-text" },
      { id: "goals",     label: "Metas",                 icon: "target" },
      { id: "forecasts", label: "Previsões e Projeções", icon: "trending-up" },
    ]
  },
];

/* Símbolo do Vendus — círculo com gradiente laranja e "V" branco (vetor, nítido em qualquer tamanho) */
const VendusLogo = ({ size = 36 }) => (
  <svg width={size} height={size} viewBox="0 0 100 100" style={{ display: "block", flexShrink: 0 }} role="img" aria-label="Vendus">
    <defs>
      <linearGradient id="vendusLogoGrad" x1="0" y1="0" x2="1" y2="1">
        <stop offset="0%" stopColor="#FF9248" />
        <stop offset="100%" stopColor="#F74B0A" />
      </linearGradient>
    </defs>
    <circle cx="50" cy="50" r="50" fill="url(#vendusLogoGrad)" />
    <path d="M22 32 L50 78 L78 32 L63 32 L50 58 L37 32 Z" fill="#fff" stroke="#fff" strokeWidth="4" strokeLinejoin="round" strokeLinecap="round" />
  </svg>
);

function Sidebar({ page, setPage, collapsed, setSettingsTab, user = {}, store = null }) {
  const [openGroups, setOpenGroups] = useState({ "IA Vendus": true, "Lojas": true, "Financeiro": true, "Análises": true });
  const [pendingMsgs, setPendingMsgs] = useState(0);

  useEffect(() => {
    let alive = true;
    window.VendusCopilot.getMessages("demo").then((list) => {
      if (alive) setPendingMsgs(list.filter((m) => m.status === "pendente").length);
    });
    return () => { alive = false; };
  }, [page]);

  if (collapsed) {
    return (
      <aside style={{
        width: 72, flex:"0 0 72px",
        background: "var(--bg-surface)",
        borderRight: "1px solid var(--border)",
        display:"flex", flexDirection:"column", alignItems:"center",
        padding: "16px 0", gap: 6
      }}>
        <div style={{ marginBottom: 14 }}><VendusLogo size={42} /></div>
        {NAV.map(n => (
          <button key={n.id} onClick={()=>setPage(n.id)} title={n.label}
            style={{
              width: 44, height: 44, borderRadius: 10, border:0, cursor:"pointer",
              background: page === n.id ? "rgba(249,115,22,.18)" : "transparent",
              color: page === n.id ? "var(--primary)" : "var(--fg-2)",
              display:"grid", placeItems:"center"
            }}>
            <I name={n.icon} size={18}/>
          </button>
        ))}
      </aside>
    );
  }

  return (
    <aside style={{
      width: 264, flex: "0 0 264px",
      background: "var(--bg-surface)",
      borderRight: "1px solid var(--border)",
      display: "flex", flexDirection: "column",
      position: "relative", zIndex: 1
    }}>
      {/* Brand */}
      <div style={{ padding: "20px 18px", borderBottom: "1px solid var(--border)", display:"flex", alignItems:"center", gap: 12 }}>
        <VendusLogo size={36} />
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="font-display" style={{ fontWeight: 700, fontSize: 17, letterSpacing: "-0.01em" }}>
            <span>Vendus</span>
          </div>
          <div className="text-faint" style={{ fontSize: 11, fontFamily:"Space Grotesk", letterSpacing:".04em" }}>Gestão multicanal</div>
        </div>
      </div>

      {/* Seletor de loja (multi-loja) */}
      {store && store.connected ? (
        <StoreSwitcher store={store} setPage={setPage} setSettingsTab={setSettingsTab} />
      ) : (
        <button onClick={() => { setSettingsTab && setSettingsTab("integrations"); setPage("settings"); }}
          title="Conectar uma loja"
          style={{ margin: "12px 12px 6px", padding: "10px 12px", display:"flex", alignItems:"center", gap: 10, background: "var(--bg-elev)", border: "1px solid var(--border)", borderRadius: 10, cursor: "pointer", textAlign:"left" }}>
          <div style={{ width: 28, height: 28, borderRadius: 7, background: "var(--bg-surface)", border: "1px dashed var(--border-strong)", display:"grid", placeItems:"center", color:"var(--fg-3)" }}>
            <I name="store" size={14}/>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontWeight: 600, fontSize: 12.5 }}>Nenhuma loja conectada</div>
            <div className="text-faint" style={{ fontSize: 11 }}>Clique para conectar</div>
          </div>
          <I name="plus" size={14} className="text-faint"/>
        </button>
      )}

      {/* Nav */}
      <nav style={{ flex: 1, overflowY:"auto", padding: "10px 12px 20px" }}>
        {NAV.map(n => (
          <button key={n.id}
            onClick={() => setPage(n.id)}
            className={"navbtn " + (page === n.id ? "active" : "")}
          >
            <I name={n.icon} size={17} className="icon"/>
            <span>{n.label}</span>
            {n.id === "messages" && page !== "messages" && pendingMsgs > 0 && <span style={{ marginLeft: "auto", background: "var(--primary)", color: "white", borderRadius: 999, fontSize: 10, padding: "2px 6px", fontWeight: 700 }}>{pendingMsgs}</span>}
          </button>
        ))}

        <div style={{ height: 12 }}/>
        {GROUPS.map(g => {
          const open = openGroups[g.label];
          const childActive = g.items.some(it => it.id === page);
          return (
            <div key={g.label} style={{ marginBottom: 4 }}>
              <button
                onClick={() => setOpenGroups(o => ({ ...o, [g.label]: !o[g.label] }))}
                className={"navbtn " + (childActive && !open ? "active" : "")}
              >
                <I name={g.icon} size={17} className="icon"/>
                <span style={{ flex: 1, textAlign:"left" }}>{g.label}</span>
                <I name={open ? "chevron-down" : "chevron-right"} size={14} className="text-faint"/>
              </button>
              {open && (
                <div style={{ padding: "4px 0" }}>
                  {g.items.map(it => (
                    <button key={it.id}
                      onClick={() => setPage(it.id)}
                      className={"subnav " + (page === it.id ? "active" : "")}
                    >
                      <I name={it.icon} size={14}/>
                      <span>{it.label}</span>
                    </button>
                  ))}
                </div>
              )}
            </div>
          );
        })}

        {/* Upgrade banner */}
        <div style={{ marginTop: 18, padding: 14, background:"linear-gradient(135deg, rgba(249,115,22,.14), rgba(139,92,246,.18))", border:"1px solid rgba(139,92,246,.25)", borderRadius: 14 }}>
          <div style={{ display:"flex", alignItems:"center", gap: 8, marginBottom: 6 }}>
            <I name="crown" size={14} style={{ color:"var(--primary)" }}/>
            <span className="font-display" style={{ fontWeight: 700, fontSize: 12.5 }}>Vendus Premium</span>
          </div>
          <div className="text-muted" style={{ fontSize: 11.5, lineHeight: 1.5, marginBottom: 10 }}>
            Desbloqueie IA forecasting, comparativos avançados e suporte prioritário.
          </div>
          <Btn variant="primary" size="sm" style={{ width: "100%", justifyContent:"center" }}
            onClick={() => window.vendusToast && window.vendusToast("Página de upgrade aberta — escolha um plano", { icon:"crown", tone:"default" })}>Fazer upgrade</Btn>
        </div>
      </nav>

      {/* User */}
      <div style={{ padding: 12, borderTop: "1px solid var(--border)", display:"flex", alignItems:"center", gap: 10 }}>
        <div className="av">{user.initials || "U"}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontWeight: 600, fontSize: 12.5, whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis" }}>{user.name || "Usuário"}</div>
          <div className="text-faint" style={{ fontSize: 11, whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis" }}>{user.email || ""}</div>
        </div>
        <Btn variant="ghost" size="sm" iconOnly title="Configurações"
          onClick={() => { setSettingsTab && setSettingsTab("profile"); setPage("settings"); }}>
          <I name="settings" size={14}/>
        </Btn>
      </div>
    </aside>
  );
}

function TopBar({ page, setPage, theme, setTheme, collapsed, setCollapsed, setSettingsTab, user = {} }) {
  const [notifOpen, setNotifOpen] = useState(false);
  const [userOpen, setUserOpen]   = useState(false);
  const [alerts, setAlerts]       = useState([]);
  const notifRef = useRef(null);
  const userRef  = useRef(null);

  useEffect(() => {
    const handler = (e) => {
      if (notifRef.current && !notifRef.current.contains(e.target)) setNotifOpen(false);
      if (userRef.current && !userRef.current.contains(e.target)) setUserOpen(false);
    };
    document.addEventListener("mousedown", handler);
    return () => document.removeEventListener("mousedown", handler);
  }, []);

  // Alertas reais vindos do Copiloto (severidade → tom visual)
  useEffect(() => {
    let alive = true;
    window.VendusCopilot.getAlerts("demo").then((a) => { if (alive) setAlerts(a); });
    return () => { alive = false; };
  }, []);

  const ALERT_TONE = {
    critico: { bg: "rgba(239,68,68,.15)", fg: "#FCA5A5" },
    atencao: { bg: "rgba(249,115,22,.15)", fg: "var(--primary)" },
    info:    { bg: "rgba(139,92,246,.15)", fg: "#C4B5FD" },
  };
  const ALERT_ICON = { ads: "megaphone", desempenho: "trending-up", margem: "percent", conteudo: "image" };
  const hasUnread = alerts.some((a) => !a.lido);

  const allItems = [...NAV, ...GROUPS.flatMap(g => g.items), { id:"settings", label:"Configurações" }];
  const breadcrumb = allItems.find(i => i.id === page)?.label || "Dashboard";

  return (
    <header style={{
      position: "sticky", top: 0, zIndex: 5,
      background: "color-mix(in oklab, var(--bg-app) 80%, transparent)",
      backdropFilter: "blur(12px)",
      borderBottom: "1px solid var(--border)",
      padding: "12px 24px",
      display:"flex", alignItems:"center", gap: 14
    }}>
      <button onClick={() => setCollapsed(c => !c)} title="Recolher menu"
        style={{ background:"transparent", border:0, color:"var(--fg-2)", cursor:"pointer", padding: 6, borderRadius: 8 }}
      >
        <I name="panel-left" size={18}/>
      </button>

      <div style={{ display:"flex", alignItems:"center", gap: 8, color: "var(--fg-3)", fontSize: 13 }}>
        <I name="home" size={14}/>
        <I name="chevron-right" size={12}/>
        <span style={{ color: "var(--fg-1)", fontWeight: 600 }}>{breadcrumb}</span>
      </div>

      <div style={{ flex: 1, maxWidth: 460, marginLeft: 24, position:"relative" }}>
        <I name="search" size={15} style={{ position:"absolute", left: 12, top: 11, color: "var(--fg-3)" }}/>
        <input className="input" placeholder="Buscar produtos, pedidos, fornecedores..." style={{ paddingLeft: 36 }}/>
        <span style={{ position:"absolute", right: 8, top: 7, display:"flex", gap:4 }}>
          <span className="chip" style={{ padding:"2px 6px", fontSize: 10 }}>⌘ K</span>
        </span>
      </div>

      <div style={{ flex: 1 }}></div>

      <Btn variant="secondary" size="sm" onClick={() => { setPage("sales"); window.vendusToast && window.vendusToast("Nova venda — abra um pedido manual", { icon:"plus", tone:"default" }); }}><I name="plus" size={13}/> Nova venda</Btn>

      <button onClick={() => setTheme(t => t === "dark" ? "light" : "dark")}
        title="Alternar tema"
        style={{ background:"transparent", border:0, color:"var(--fg-2)", cursor:"pointer", padding: 8, borderRadius: 8 }}>
        <I name={theme==="dark" ? "sun" : "moon"} size={17}/>
      </button>

      {/* Notifications */}
      <div ref={notifRef} style={{ position:"relative" }}>
        <button onClick={() => setNotifOpen(v => !v)}
          style={{ background:"transparent", border:0, color:"var(--fg-2)", cursor:"pointer", padding: 8, borderRadius: 8, position:"relative" }}>
          <I name="bell" size={17}/>
          {hasUnread && <span style={{ position:"absolute", top: 6, right: 6, width: 8, height: 8, background: "var(--primary)", borderRadius:999, border:"2px solid var(--bg-app)" }}></span>}
        </button>
        {notifOpen && (
          <div style={{
            position:"absolute", top: 44, right: 0, width: 360,
            background: "var(--bg-surface)", border: "1px solid var(--border)",
            borderRadius: 12, boxShadow: "var(--shadow-3)", padding: 8, zIndex: 50
          }}>
            <div style={{ display:"flex", justifyContent:"space-between", alignItems:"center", padding: "8px 10px" }}>
              <div style={{ fontWeight: 700 }}>Alertas do Copiloto</div>
              <button className="text-orange" onClick={() => { setAlerts((prev) => prev.map((a) => ({ ...a, lido: true }))); window.vendusToast && window.vendusToast("Alertas marcados como lidos", { icon:"check-check", tone:"success" }); }} style={{ background:"none", border:0, fontSize: 12, cursor:"pointer", fontWeight: 600 }}>Marcar lidas</button>
            </div>
            {alerts.length === 0 && (
              <div className="text-faint" style={{ fontSize: 12.5, padding: "10px 10px" }}>Nenhum alerta no momento.</div>
            )}
            {alerts.map((a, i) => {
              const tone = ALERT_TONE[a.severidade] || ALERT_TONE.info;
              return (
                <div key={i} style={{ display:"flex", gap: 12, padding: "10px 10px", borderRadius: 8, cursor:"pointer", opacity: a.lido ? 0.6 : 1 }}
                  onClick={() => { setNotifOpen(false); setPage("copilot"); }}
                  role="button" tabIndex={0}
                  className="row">
                  <div style={{
                    width: 34, height: 34, borderRadius: 9, flexShrink: 0,
                    background: tone.bg, color: tone.fg,
                    display:"grid", placeItems:"center"
                  }}>
                    <I name={ALERT_ICON[a.origem] || "sparkles"} size={15}/>
                  </div>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontWeight: 600, fontSize: 13 }}>{a.titulo}</div>
                    <div className="text-faint" style={{ fontSize: 11.5 }}>{a.detalhe}</div>
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {/* User menu */}
      <div ref={userRef} style={{ position:"relative" }}>
        <button onClick={() => setUserOpen(v => !v)}
          style={{ background:"transparent", border:0, cursor:"pointer", padding: 2, borderRadius: 999 }}>
          <div className="av" style={{ width: 34, height: 34 }}>{user.initials || "U"}</div>
        </button>
        {userOpen && (
          <div style={{
            position:"absolute", top: 44, right: 0, width: 240,
            background: "var(--bg-surface)", border: "1px solid var(--border)",
            borderRadius: 12, boxShadow: "var(--shadow-3)", padding: 6, zIndex: 50
          }}>
            <div style={{ padding: 12, display:"flex", gap: 10 }}>
              <div className="av">{user.initials || "U"}</div>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontWeight: 700, fontSize: 13, whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis" }}>{user.name || "Usuário"}</div>
                <div className="text-faint" style={{ fontSize: 11, whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis", maxWidth: 170 }}>{user.email || ""}</div>
              </div>
            </div>
            {[
              ["Perfil","user","profile"],
              ["Configurações","settings","profile"],
              ["Cobrança","credit-card","billing"],
              ["Time","users","team"],
              ["Suporte","life-buoy",null],
            ].map(([l,ic,tab]) => (
              <button key={l} className="navbtn" onClick={() => {
                setUserOpen(false);
                if (tab) { setSettingsTab(tab); setPage("settings"); }
                else window.vendusToast && window.vendusToast("Chat de suporte iniciado", { icon:"life-buoy", tone:"info" });
              }}>
                <I name={ic} size={15} className="icon"/> {l}
              </button>
            ))}
            <div style={{ borderTop: "1px solid var(--border)", marginTop: 6, paddingTop: 6 }}>
              <button className="navbtn" onClick={() => { setUserOpen(false); window.VendusAuth.signOut().then(() => { window.vendusToast && window.vendusToast("Sessão encerrada", { icon:"log-out", tone:"warning" }); }); }} style={{ color: "var(--danger-soft)" }}>
                <I name="log-out" size={15} className="icon"/> Sair
              </button>
            </div>
          </div>
        )}
      </div>
    </header>
  );
}

/* =========== Tweaks =========== */
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "dark",
  "palette": ["#F97316","#EC4899","#8B5CF6"],
  "fontPair": "signal",
  "density": "comfy"
}/*EDITMODE-END*/;

function App() {
  const [t, setTweak] = window.useTweaks(TWEAK_DEFAULTS);
  const [page, setPage] = useState("dashboard");
  const [settingsTab, setSettingsTab] = useState("profile");
  const [collapsed, setCollapsed] = useState(false);
  const [session, setSession] = useState(undefined); // undefined=checando, null=deslogado, obj=logado
  useEffect(() => {
    window.VendusAuth.getSession().then(setSession).catch(() => setSession(null));
    window.VendusAuth.onChange(setSession);
  }, []);

  // Paywall: status de assinatura (SEMPRE do servidor). undefined=checando, obj={ativa,...}.
  const [assinatura, setAssinatura] = useState(undefined);
  const recheckAssinatura = useMemo(() => async () => {
    const s = await window.VendusCopilot.getSubscription();
    setAssinatura(s);
    return s;
  }, []);
  useEffect(() => {
    if (session === undefined) return;          // ainda checando login
    if (!session) { setAssinatura(undefined); return; } // deslogado → tela de login cuida
    recheckAssinatura();
  }, [session]);
  // Usuário logado (null-safe) — disponível para o router e o shell
  const sUser = (session && session.user) || null;
  const user = sUser ? {
    name: (sUser.user_metadata && sUser.user_metadata.full_name) || sUser.email || "Usuário",
    email: sUser.email || "",
    initials: window.VendusAuth.initialsOf((sUser.user_metadata && sUser.user_metadata.full_name) || sUser.email, sUser.email),
  } : {};

  // Loja conectada (Mercado Livre) + sincronização ao retornar da conexão
  const [store, setStore] = useState(null);
  useEffect(() => {
    if (!session) return;
    window.VendusCopilot.getStatus().then(setStore);
  }, [session]);
  useEffect(() => {
    if (!session) return;
    const params = new URLSearchParams(window.location.search);
    if (params.get("connected") !== "ml") return;
    params.delete("connected");
    window.history.replaceState({}, "", window.location.pathname + (params.toString() ? "?" + params : ""));
    window.vendusToast && window.vendusToast("Loja conectada! Sincronizando seus produtos e pedidos…", { icon: "check-check", tone: "success" });
    window.VendusCopilot.syncNow().then((r) => {
      window.VendusCopilot.getStatus().then(setStore);
      if (r.ok) {
        window.vendusToast && window.vendusToast(`Sincronizado: ${r.products || 0} produtos e ${r.orders || 0} pedidos. O Copiloto já está analisando…`, { icon: "package", tone: "success" });
        // dispara a primeira análise (1–2 min, em background)
        window.VendusCopilot.runAnalysisNow(undefined, "diario");
      } else {
        window.vendusToast && window.vendusToast(r.error || "Sincronização não concluída.", { icon: "alert-triangle", tone: "warning" });
      }
    });
  }, [session]);

  const accent    = t.palette[0];
  const mid       = t.palette[1] || "#EC4899";
  const secondary = t.palette[2] || "#8B5CF6";

  useEffect(() => { document.documentElement.dataset.theme = t.theme; }, [t.theme]);

  // Font pair -> CSS vars
  useEffect(() => {
    const fp = VENDUS_FONT_PAIRS.find(f => f.id === t.fontPair) || VENDUS_FONT_PAIRS[0];
    document.documentElement.style.setProperty("--font-sans",    fontStack(fp));
    document.documentElement.style.setProperty("--font-display", displayStack(fp));
  }, [t.fontPair]);

  useEffect(() => {
    const shift = (hex, dl) => {
      const r = parseInt(hex.slice(1,3),16), g = parseInt(hex.slice(3,5),16), b = parseInt(hex.slice(5,7),16);
      const adj = v => Math.max(0, Math.min(255, Math.round(v + dl)));
      return "#" + [adj(r),adj(g),adj(b)].map(v => v.toString(16).padStart(2,"0")).join("");
    };
    const root = document.documentElement;
    root.style.setProperty("--primary", accent);
    root.style.setProperty("--primary-hover",  shift(accent, -20));
    root.style.setProperty("--primary-active", shift(accent, -40));
    root.style.setProperty("--primary-soft",   shift(accent, 20));
    root.style.setProperty("--violet-500", secondary);
    root.style.setProperty("--violet-400", shift(secondary, 30));
    root.style.setProperty("--violet-600", shift(secondary, -20));
    root.style.setProperty("--logo-gradient", `linear-gradient(180deg, ${accent} 0%, ${mid} 55%, ${secondary} 100%)`);
  }, [accent, mid, secondary]);

  const connected = !!(store && store.connected);
  const ep = (id) => <EmptyPage id={id} navigate={setPage} connected={connected} />;
  const PageComp = useMemo(() => ({
    dashboard:   () => connected ? <RealDashboard navigate={setPage} user={user} store={store}/> : <EmptyDashboard navigate={setPage} user={user} store={store}/>,
    copilot:     () => <CopilotPage store={store}/>,
    ads:         () => <AdsPage store={store}/>,
    aiconfig:    () => <AIConfigPage store={store}/>,
    messages:    () => <MessagesPage store={store}/>,
    calculator:  () => <CalculatorPage/>,
    settings:    () => <SettingsPage tweaks={t} setTweak={setTweak} tab={settingsTab} setTab={setSettingsTab}/>,
    products:    () => connected ? <RealProducts store={store}/> : ep("products"),
    catalogo:    () => connected ? <CatalogoPage store={store}/> : ep("products"),
    vinculo:     () => connected ? <VinculoPage store={store}/> : ep("products"),
    sales:       () => connected ? <RealSales store={store}/> : ep("sales"),
    stores:      () => connected ? <ConnectedStores navigate={setPage} store={store} setSettingsTab={setSettingsTab}/> : ep("stores"),
    strategic:   () => connected ? <StrategicPage store={store}/> : ep("strategic"),
    comparatives:() => connected ? <RealComparatives/> : ep("comparatives"),
    contas_pagar:() => connected ? <RealContasPagar/> : ep("costs"),
    contas_receber:() => connected ? <RealContasReceber/> : ep("costs"),
    resultado:   () => connected ? <RealResultado/> : ep("costs"),
    cashflow:    () => connected ? <RealCashflow/> : ep("cashflow"),
    costs:       () => connected ? <RealCosts/> : ep("costs"),
    suppliers:   () => connected ? <RealSuppliers/> : ep("suppliers"),
    purchases:   () => connected ? <RealPurchases/> : ep("purchases"),
    reports:     () => connected ? <RealReports/> : ep("reports"),
    goals:       () => connected ? <GoalsPage store={store}/> : ep("goals"),
    forecasts:   () => connected ? <RealForecasts/> : ep("forecasts"),
  }[page] || (() => <div className="page">Em breve</div>)), [page, t, settingsTab, user.name, connected, store]);

  // re-render Lucide icons whenever DOM mutates
  useEffect(() => {
    if (window.lucide) window.lucide.createIcons();
  });

  // Portão de autenticação (multitenant)
  if (session === undefined) {
    return <div style={{ minHeight: "100vh", display: "grid", placeItems: "center", color: "var(--fg-2)", fontSize: 14 }}>Carregando…</div>;
  }
  if (!session) {
    return <VendusAuthScreen/>;
  }
  // Paywall: logado mas sem assinatura ativa → preso na tela de assinar (o servidor também trava as APIs).
  if (assinatura === undefined) {
    return <div style={{ minHeight: "100vh", display: "grid", placeItems: "center", color: "var(--fg-2)", fontSize: 14 }}>Carregando…</div>;
  }
  if (!assinatura.ativa) {
    const AssinarScreen = window.VendusAssinar && window.VendusAssinar.AssinarScreen;
    if (AssinarScreen) return <AssinarScreen sub={assinatura} onCheck={recheckAssinatura}/>;
  }

  return (
    <div style={{ display:"flex", height:"100vh", overflow:"hidden", position:"relative", zIndex: 1 }}>
      <Sidebar page={page} setPage={setPage} collapsed={collapsed} setSettingsTab={setSettingsTab} user={user} store={store}/>
      <div style={{ flex: 1, minWidth: 0, display:"flex", flexDirection:"column", overflow:"hidden" }}>
        <TopBar
          page={page} setPage={setPage}
          setSettingsTab={setSettingsTab}
          theme={t.theme}
          setTheme={(v) => setTweak("theme", typeof v === "function" ? v(t.theme) : v)}
          collapsed={collapsed} setCollapsed={setCollapsed}
          user={user}
        />
        <main style={{ flex: 1, overflow:"auto" }}>
          {PageComp()}
        </main>
      </div>

      <window.TweaksPanel title="Tweaks · Vendus">
        <window.TweakSection label="Aparência">
          <window.TweakRadio label="Tema" value={t.theme}
            options={[{value:"dark",label:"Escuro"},{value:"light",label:"Claro"}]}
            onChange={(v) => setTweak("theme", v)}/>
          <window.TweakButton label="Abrir galeria de temas"
            onClick={() => { setSettingsTab("appearance"); setPage("settings"); }}/>
        </window.TweakSection>
        <window.TweakSection label="Paleta de marca">
          <window.TweakColor label="Cores" value={t.palette}
            options={VENDUS_PALETTES.map(p => p.colors)}
            onChange={(v) => setTweak("palette", v)}/>
        </window.TweakSection>
        <window.TweakSection label="Tipografia">
          <window.TweakSelect label="Par de fontes" value={t.fontPair}
            options={VENDUS_FONT_PAIRS.map(f => ({ value: f.id, label: `${f.name} — ${f.body} / ${f.display}` }))}
            onChange={(v) => setTweak("fontPair", v)}/>
        </window.TweakSection>
      </window.TweaksPanel>
    </div>
  );
}

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App/>);
