// mb-app.jsx — root app: routing, cart, themes, tweaks

const THEMES = {
  marinho: { accent: "oklch(0.52 0.17 264)", turbo: "linear-gradient(135deg,#FF8A1E,#FF2E63)", ts: "rgba(255,60,99,.4)" },
  litoral: { accent: "oklch(0.60 0.115 205)", turbo: "linear-gradient(135deg,#13C6B4,#0E86C4)", ts: "rgba(14,134,196,.4)" },
  coral:   { accent: "oklch(0.64 0.165 33)",  turbo: "linear-gradient(135deg,#FFB020,#FF3D77)", ts: "rgba(255,61,119,.4)" },
};
const FONTS = { "Plus Jakarta Sans": "'Plus Jakarta Sans'", "DM Sans": "'DM Sans'", Poppins: "'Poppins'", Manrope: "'Manrope'" };
const LIGHT = { bg: "#F3F5FA", surface: "#FFFFFF", text: "#15173A", muted: "#71748F", line: "#E8EAF2", brand: "#181B57", cbbg: "#E7F6EE", cbink: "#0A6B43", ph1: "#EEF1F6", ph2: "#E4E8F0", pht: "#9AA0B4" };
const DARK = { bg: "#0D0F1E", surface: "#191C30", text: "#ECEEF7", muted: "#9A9EBE", line: "#2A2E48", brand: "#232652", cbbg: "#143226", cbink: "#7DE0AC", ph1: "#222640", ph2: "#1B1E33", pht: "#71768F" };

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "theme": "marinho",
  "font": "Plus Jakarta Sans",
  "appearance": "Claro",
}/*EDITMODE-END*/;

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const th = THEMES[t.theme] || THEMES.marinho;
  const pal = t.appearance === "Escuro" ? DARK : LIGHT;
  const rootVars = {
    "--ui": (FONTS[t.font] || FONTS["DM Sans"]) + ", system-ui, sans-serif",
    "--mono": "'DM Mono', ui-monospace, monospace",
    "--accent": th.accent, "--accent-ink": "#fff",
    "--accent-50": "color-mix(in srgb, var(--accent) 13%, " + pal.surface + ")",
    "--accent-shadow": "color-mix(in srgb, var(--accent) 38%, transparent)",
    "--turbo-grad": th.turbo, "--turbo-shadow": th.ts,
    "--bg": pal.bg, "--surface": pal.surface, "--text": pal.text, "--muted": pal.muted, "--line": pal.line,
    "--brand": pal.brand, "--cb": "#0FA968", "--cb-bg": pal.cbbg, "--cb-ink": pal.cbink,
    "--ph1": pal.ph1, "--ph2": pal.ph2, "--ph-text": pal.pht,
  };

  // ── navigation ──
  const [tab, setTab] = React.useState("home");
  const [filt, setFilt] = React.useState({ region: "Todas", seg: null, cat: null, radius: 8, mode: "todos" });
  const [filtersOpen, setFiltersOpen] = React.useState(false);
  const [cashbackOpen, setCashbackOpen] = React.useState(false);

  const [storeId, setStoreId] = React.useState(null);
  const [storeMode, setStoreMode] = React.useState("delivery");
  const [product, setProduct] = React.useState(null);
  const [cartOpen, setCartOpen] = React.useState(false);
  const [checkoutOpen, setCheckoutOpen] = React.useState(false);
  const [success, setSuccess] = React.useState(null);
  const [review, setReview] = React.useState(null);
  const [replaceItem, setReplaceItem] = React.useState(null);
  const [toast, setToast] = React.useState(null);

  // ── cart ──
  const [cart, setCart] = React.useState({ partnerId: null, items: {} });
  const cartCount = Object.values(cart.items).reduce((s, e) => s + e.qty, 0);
  const cartTotal = Object.values(cart.items).reduce((s, e) => s + e.item.price * e.qty, 0);

  const [novoLarOpen, setNovoLarOpen] = React.useState(false);
  const [servicesOpen, setServicesOpen] = React.useState(false);
  const [gastroOpen, setGastroOpen] = React.useState(false);
  const [blogInitialPost, setBlogInitialPost] = React.useState(null);

  const openBlog = (post) => {
    if (post) setBlogInitialPost(post);
    setTab("blog");
  };
  const [bookInfo, setBookInfo] = React.useState(null); // {partner, service}
  const [leadInfo, setLeadInfo] = React.useState(null); // {partner, listing}
  const [profileView, setProfileView] = React.useState(null);
  const [agendaDetail, setAgendaDetail] = React.useState(null);
  const [authed, setAuthed] = React.useState(true);
  const [perfilAuthOpen, setPerfilAuthOpen] = React.useState(false);
  const [notifsOpen, setNotifsOpen] = React.useState(false);

  // ── PWA install modal ──
  const isIOS      = /iPhone|iPad|iPod/.test(navigator.userAgent) && !window.MSStream;
  const isAndroid  = /Android/.test(navigator.userAgent);
  const isMobile   = isIOS || isAndroid;
  // Safari em qualquer plataforma (iOS ou Mac) — não tem beforeinstallprompt
  const isSafari   = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
  // Mostra o botão "Instalar App" para quem pode instalar: prompt nativo, mobile ou Safari
  const canShowInstallUI = (pwaCanInstall || isMobile || isSafari) && !window.mbIsStandalone?.();
  const [pwaCanInstall, setPwaCanInstall] = React.useState(false);
  const [pwaDismissed, setPwaDismissed]   = React.useState(() => !!localStorage.getItem("pwa-modal-dismissed"));
  const [pwaInstalled, setPwaInstalled]   = React.useState(false);
  const [pwaGuideOpen, setPwaGuideOpen]   = React.useState(false);
  const [updateReady, setUpdateReady]     = React.useState(false);
  const [updateStatus, setUpdateStatus]   = React.useState(null); // null | "checking" | "done" | "error"

  React.useEffect(() => {
    if (window.mbCanInstallPWA && window.mbCanInstallPWA()) setPwaCanInstall(true);
    const onInstallable   = () => setPwaCanInstall(true);
    const onInstalled     = () => { setPwaCanInstall(false); };
    const onUpdateAvail   = () => setUpdateReady(true);
    window.addEventListener("pwa-installable",     onInstallable);
    window.addEventListener("pwa-installed",       onInstalled);
    window.addEventListener("pwa-update-available", onUpdateAvail);
    return () => {
      window.removeEventListener("pwa-installable",     onInstallable);
      window.removeEventListener("pwa-installed",       onInstalled);
      window.removeEventListener("pwa-update-available", onUpdateAvail);
    };
  }, []);

  // Aciona a atualização: tenta via SW, se não tiver, limpa cache e recarrega
  const doAppUpdate = async () => {
    setUpdateStatus("checking");
    try {
      const triggered = await window.mbTriggerUpdate?.();
      if (!triggered) {
        // Sem SW esperando — limpa tudo e recarrega na força
        await window.mbClearCaches?.();
        setUpdateStatus("done");
        setTimeout(() => window.location.reload(true), 1200);
      }
      // Se triggered: o controllerchange vai recarregar automaticamente
    } catch {
      setUpdateStatus("error");
      setTimeout(() => setUpdateStatus(null), 3000);
    }
  };
  const [splashDone, setSplashDone] = React.useState(false);
  const [notifList, setNotifList] = React.useState([]);
  const [clubMember, setClubMember] = React.useState(false);
  const [clubOpen, setClubOpen] = React.useState(false);

  // ── endereços salvos (compartilhado com FiltersSheet e ShopScreen) ──
  const [savedAddresses, setSavedAddresses] = React.useState([]);
  React.useEffect(() => {
    if (!Auth.isLogged()) return;
    API.me.addresses().then(d => setSavedAddresses(d.addresses || [])).catch(() => {});
  }, [authed]);

  // Carrega dados se já estiver logado ao abrir o app (modo guest bypass)
  React.useEffect(() => {
    if (Auth.isLogged()) loadUserData();
  }, []);

  // ── segmentos da API (substitui o SEGMENTS hardcoded nos filhos) ──
  const [apiSegments, setApiSegments] = React.useState(null); // null = carregando
  React.useEffect(() => {
    API.segments().then(d => setApiSegments(d.segments || [])).catch(() => setApiSegments(SEGMENTS));
  }, []);

  // ── feature flags ──
  const [featureFlags, setFeatureFlags] = React.useState({ loja: false, cashback: false, compras: false });
  const [pilotEmails,  setPilotEmails]  = React.useState([]);
  React.useEffect(() => {
    API.home().then(d => {
      if (d?.feature_flags) setFeatureFlags(d.feature_flags);
      if (d?.pilot_emails)  setPilotEmails(d.pilot_emails.map(e => e.toLowerCase()));
    }).catch(() => {});
  }, []);
  const isPilot = (email) => pilotEmails.includes((email || "").toLowerCase());

  // ── dados reais da API ──
  const [apiUser, setApiUser] = React.useState(null);
  const [apiWallet, setApiWallet] = React.useState(null);
  // Cache de parceiros da API: id → objeto parceiro (formato apiCompanyToPartner)
  const [partnerMap, setPartnerMap] = React.useState({});
  const cachePartners = (list) => setPartnerMap(m => {
    const next = { ...m };
    list.forEach(p => { next[p.id] = p; });
    return next;
  });
  // Resolve parceiro: cache da API primeiro, fallback estático
  const resolvePartner = (id) => partnerMap[id] || partnerById(id);
  const storePartner = resolvePartner(storeId);
  const cartPartner  = resolvePartner(cart.partnerId);

  const flashToast = (msg) => { setToast(msg); setTimeout(() => setToast(null), 1800); };

  // Handle MP payment return (?payment=success|failure|pending&order=uuid)
  React.useEffect(() => {
    const params = new URLSearchParams(window.location.search);
    const payStatus = params.get("payment");
    const orderId   = params.get("order");
    if (!payStatus) return;
    // Clean URL
    window.history.replaceState({}, "", window.location.pathname);
    if (payStatus === "success") {
      flashToast("Pagamento confirmado! Pedido em andamento.");
      setTab("pedidos");
    } else if (payStatus === "failure") {
      flashToast("Pagamento não concluído. Tente novamente.");
    } else if (payStatus === "pending") {
      flashToast("Pagamento em processamento. Avisaremos quando confirmar.");
      setTab("pedidos");
    }
    if (orderId) {
      // Optionally open the order detail
      console.log("Payment return for order:", orderId, "status:", payStatus);
    }
  }, []);

  // Carrega wallet, notificações e perfil quando logado
  const loadUserData = async () => {
    try {
      const [walletData, txData, notifData, meData] = await Promise.all([
        API.wallet.get(),
        API.wallet.transactions(),
        API.me.notifications().catch(() => ({ notifications: [] })),
        API.me.get().catch(() => null),
      ]);
      setApiWallet(apiWalletToMock(walletData, txData.transactions));
      setNotifList((notifData.notifications || []).map(n => ({
        id: n.id, kind: n.kind, title: n.title, text: n.body,
        time: new Date(n.created_at).toLocaleDateString("pt-BR"),
        group: "Recentes", unread: !n.read,
      })));
      if (meData) setApiUser(meData);
    } catch (_) {}
  };

  const openStore = (id, partnerObj) => {
    // partnerObj opcional: pré-popula o cache para evitar lookup estático
    if (partnerObj) cachePartners([partnerObj]);
    const p = partnerObj || resolvePartner(id);
    if (!p) { setStoreId(id); return; }
    setStoreMode(p.delivery ? "delivery" : "pickup");
    setStoreId(id);
  };

  const reallyAdd = (item, qty, note, pid) => {
    setCart(c => {
      const base = c.partnerId === pid ? c.items : {};
      const ex = base[item.id];
      return { partnerId: pid, items: { ...base, [item.id]: { item, qty: (ex ? ex.qty : 0) + qty, note: note || (ex && ex.note) || "" } } };
    });
  };

  const confirmAdd = (qty, note) => {
    const item = product;
    setProduct(null);
    if (cart.partnerId && cart.partnerId !== storeId && cartCount > 0) {
      setReplaceItem({ item, qty, note });
    } else {
      reallyAdd(item, qty, note, storeId);
      flashToast("Adicionado à sacola");
    }
  };

  const inc = (id) => setCart(c => ({ ...c, items: { ...c.items, [id]: { ...c.items[id], qty: c.items[id].qty + 1 } } }));
  const dec = (id) => setCart(c => {
    const q = c.items[id].qty - 1;
    const items = { ...c.items };
    if (q <= 0) delete items[id]; else items[id] = { ...items[id], qty: q };
    return { partnerId: Object.keys(items).length ? c.partnerId : null, items };
  });
  const getQty = (id) => cart.items[id] ? cart.items[id].qty : 0;

  const placeOrder = (o) => {
    setCheckoutOpen(false); setCartOpen(false);
    setSuccess({ ...o, partnerId: storeId });
    setCart({ partnerId: null, items: {} });
  };

  const closeSuccess = () => { setSuccess(null); setStoreId(null); };

  const enterApp = (userFromApi, goToPerfil = false) => {
    if (userFromApi) setApiUser(userFromApi);
    setAuthed(true);
    setPerfilAuthOpen(false);
    setTab(goToPerfil ? "perfil" : "home");
    loadUserData();
  };
  const subscribeClub = () => { setClubMember(true); flashToast("Bem-vinda ao Clube Morar Bem!"); };
  const cancelClub = () => { setClubMember(false); flashToast("Assinatura cancelada"); };

  const logout = () => {
    Auth.clear();
    setApiUser(null); setApiWallet(null);
    setProfileView(null); setStoreId(null); setNovoLarOpen(false); setServicesOpen(false); setGastroOpen(false);
    setNotifsOpen(false); setCartOpen(false); setCheckoutOpen(false); setSuccess(null);
    setClubOpen(false);
    setTab("home"); setCart({ partnerId: null, items: {} }); setAuthed(false);
  };

  // Gate: perfil requer login
  const handleTab = (id) => {
    if (id === "perfil" && !Auth.isLogged()) {
      setPerfilAuthOpen(true);
      return;
    }
    setTab(id);
  };

  const confirmBooking = async ({ dateISO, dateLabel, time, local }) => {
    const partner = bookInfo.partner;
    const service = bookInfo.service;
    const companyId = partner._raw?.id || partner.id;
    const serviceId = service._raw?.id || service.id;
    try {
      await API.appointments.create({
        company_id: companyId,
        service_id: typeof serviceId === "string" && serviceId.includes("-") ? serviceId : undefined,
        date: dateISO,
        time,
        local,
      });
    } catch (_) {}
    setSuccess({ kind: "agendamento", partnerId: partner.id, service: service.name, date: dateLabel, time, local });
    setBookInfo(null);
  };
  const confirmLead = async ({ pref, msg }) => {
    const partner = leadInfo.partner;
    const listing = leadInfo.listing;
    const companyId = partner._raw?.id || partner.id;
    const user = apiUser || USER;
    try {
      await API.leads.create({
        company_id: companyId,
        listing_id: listing?._raw?.id || listing?.id || undefined,
        name:    user.name,
        phone:   user.phone,
        message: msg || "",
        channel: pref === "whats" ? "whatsapp" : "ligacao",
      });
    } catch (_) {}
    setSuccess({ kind: "contato", partnerId: partner.id, pref });
    setLeadInfo(null);
  };

  return (
    <div style={{ ...rootVars, width: "100%", height: "100%", position: "relative", background: "var(--bg)", color: "var(--text)" }}>
      {/* Splash screen de abertura */}
      {!splashDone && <SplashScreen onDone={() => setSplashDone(true)} />}

      {/* Container responsivo — sem frame iOS fixo */}
      <div style={{ position: "absolute", inset: 0, background: "var(--bg)", fontFamily: "var(--ui)", overflow: "hidden" }}>
          {!authed ? (
            <AuthFlow onAuthed={enterApp} onToast={flashToast} />
          ) : (
          <React.Fragment>
          {/* tabs */}
          {tab === "home" && <HomeIntro user={apiUser} onOpenClub={() => setClubOpen(true)} canInstallPwa={canShowInstallUI} onInstallApp={async () => {
                if (pwaCanInstall) {
                  const ok = await window.mbInstallPWA?.();
                  if (ok) setPwaInstalled(true);
                } else if (isIOS && navigator.share) {
                  try { await navigator.share({ title: "Morar Bem", url: window.location.href }); }
                  catch (_) { setPwaGuideOpen(true); }
                } else {
                  setPwaGuideOpen(true);
                }
              }} onDescobrir={() => setTab("descobrir")} onNovoLar={() => setNovoLarOpen(true)} onServices={() => setServicesOpen(true)} onShop={() => setTab("shop")} onOpenBlog={openBlog}
              updateReady={updateReady} updateStatus={updateStatus} onUpdate={doAppUpdate} />}
          {tab === "descobrir" && <DescobrirScreen filt={filt} setFilt={setFilt} segments={apiSegments || SEGMENTS} onOpenStore={openStore} openFilters={() => setFiltersOpen(true)} onNovoLar={() => setNovoLarOpen(true)} onServices={() => setServicesOpen(true)} onGastro={() => setGastroOpen(true)} onCachePartners={cachePartners} />}
          {tab === "blog" && typeof BlogScreen !== "undefined" && <BlogScreen initialPost={blogInitialPost} onClearInitial={() => setBlogInitialPost(null)} />}
          {tab === "blog" && typeof BlogScreen === "undefined" && (
            <div style={{ position: "absolute", inset: 0, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", background: "var(--bg)", gap: 12 }}>
              <div style={{ width: 28, height: 28, borderRadius: 999, border: "3px solid var(--line)", borderTopColor: "var(--accent)", animation: "spin .7s linear infinite" }} />
              <div style={{ font: "500 13px var(--ui)", color: "var(--muted)" }}>Carregando Blog…</div>
            </div>
          )}
          {tab === "shop" && <ShopScreen segments={apiSegments || SEGMENTS} onOpenStore={openStore} wallet={apiWallet || WALLET} onNovoLar={() => setNovoLarOpen(true)} onServices={() => setServicesOpen(true)} onGastro={() => setGastroOpen(true)} onOpenNotifs={() => setNotifsOpen(true)} unread={unreadCount(notifList)} />}
          {tab === "perfil" && <PerfilScreen wallet={apiWallet || WALLET} user={apiUser || USER} onOpenCarteira={() => setTab("home")} onOpen={(id) => setProfileView(id)} onLogout={logout} onOpenClub={() => setClubOpen(true)} clubMember={clubMember} />}

          {/* PWA install modal — só quando há prompt nativo (Android Chrome) e fora da aba home */}
          {pwaCanInstall && !pwaDismissed && !window.mbIsStandalone?.() && tab !== "home" && (
            <div style={{ position: "absolute", inset: 0, zIndex: 900, display: "flex", alignItems: "flex-end", justifyContent: "center", background: "rgba(16,18,45,.55)", backdropFilter: "blur(3px)" }}
              onClick={e => { if (e.target === e.currentTarget) { setPwaDismissed(true); localStorage.setItem("pwa-modal-dismissed","1"); } }}>
              <div style={{ width: "100%", background: "var(--surface)", borderRadius: "24px 24px 0 0", padding: "28px 24px 36px", boxShadow: "0 -16px 48px rgba(16,18,45,.22)" }}>

                {!pwaInstalled ? (<>
                  <div style={{ width: 40, height: 4, borderRadius: 99, background: "var(--line)", margin: "0 auto 22px" }} />
                  <div style={{ display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", marginBottom: 24 }}>
                    <img src="/icon-192-v2.png" alt="Morar Bem" style={{ width: 72, height: 72, borderRadius: 18, boxShadow: "0 8px 24px rgba(24,27,87,.18)", marginBottom: 16 }} />
                    <div style={{ font: "800 22px var(--ui)", color: "var(--text)", lineHeight: 1.25, marginBottom: 8 }}>Os melhores serviços<br />na palma da sua mão</div>
                    <div style={{ font: "500 14px var(--ui)", color: "var(--muted)", lineHeight: 1.55, maxWidth: 300 }}>Instale o Morar Bem e acesse delivery, agendamentos, cashback e muito mais — sem abrir o navegador.</div>
                  </div>
                  <div style={{ display: "flex", flexDirection: "column", gap: 10, marginBottom: 26 }}>
                    {[["⚡","Acesso rápido pela tela inicial, a qualquer hora"],["💰","BemCash e cashback em cada compra ou pedido"],["🔔","Notificações de ofertas, pedidos e agendamentos"]].map(([em,txt]) => (
                      <div key={txt} style={{ display: "flex", alignItems: "center", gap: 12 }}>
                        <span style={{ font: "18px serif", lineHeight: 1, width: 28, textAlign: "center", flexShrink: 0 }}>{em}</span>
                        <span style={{ font: "500 13.5px var(--ui)", color: "var(--text)", lineHeight: 1.4 }}>{txt}</span>
                      </div>
                    ))}
                  </div>
                  <button onClick={async () => {
                    const ok = await window.mbInstallPWA?.();
                    if (ok) { setPwaInstalled(true); setPwaCanInstall(false); }
                  }} style={{ width: "100%", height: 52, borderRadius: 14, border: "none", background: "var(--accent)", color: "#fff", font: "800 16px var(--ui)", cursor: "pointer", marginBottom: 12, display: "flex", alignItems: "center", justifyContent: "center", gap: 10 }}>
                    <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fff" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><path d="M12 2v13M8 11l4 4 4-4"/><path d="M3 17v2a2 2 0 002 2h14a2 2 0 002-2v-2"/></svg>
                    Instalar agora — é grátis
                  </button>
                  <button onClick={() => { setPwaDismissed(true); localStorage.setItem("pwa-modal-dismissed","1"); }}
                    style={{ width: "100%", background: "none", border: "none", cursor: "pointer", font: "500 13px var(--ui)", color: "var(--muted)", padding: "8px 0" }}>
                    Agora não
                  </button>
                </>) : (<>
                  <div style={{ display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", padding: "8px 0 4px" }}>
                    <div style={{ width: 64, height: 64, borderRadius: 999, background: "#E6F9F0", display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 18 }}>
                      <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#0FA968" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12.5l4.5 4.5L19 7"/></svg>
                    </div>
                    <div style={{ font: "800 20px var(--ui)", color: "var(--text)", marginBottom: 10 }}>App instalado!</div>
                    <div style={{ font: "500 14px var(--ui)", color: "var(--muted)", lineHeight: 1.6, maxWidth: 280, marginBottom: 28 }}>
                      Procure o ícone do <b style={{ color: "var(--text)" }}>Morar Bem</b> na sua tela inicial e abra de lá para a experiência completa do app.
                    </div>
                    <button onClick={() => { setPwaDismissed(true); localStorage.setItem("pwa-modal-dismissed","1"); try { window.close(); } catch(_){} }}
                      style={{ width: "100%", height: 50, borderRadius: 14, border: "none", background: "var(--accent)", color: "#fff", font: "700 15px var(--ui)", cursor: "pointer", marginBottom: 10 }}>
                      Fechar e abrir pelo app
                    </button>
                    <button onClick={() => { setPwaDismissed(true); localStorage.setItem("pwa-modal-dismissed","1"); }}
                      style={{ background: "none", border: "none", cursor: "pointer", font: "500 13px var(--ui)", color: "var(--muted)", padding: "6px 0" }}>
                      Continuar no navegador
                    </button>
                  </div>
                </>)}
              </div>
            </div>
          )}

          {/* Guia de instalação manual — aberto pelo botão do HomeIntro, zIndex acima do HomeIntro */}
          {pwaGuideOpen && !window.mbIsStandalone?.() && (
            <div style={{ position: "absolute", inset: 0, zIndex: 1100, display: "flex", alignItems: "flex-end", justifyContent: "center", background: "rgba(16,18,45,.6)", backdropFilter: "blur(4px)" }}
              onClick={e => { if (e.target === e.currentTarget) setPwaGuideOpen(false); }}>
              <div style={{ width: "100%", background: "var(--surface)", borderRadius: "24px 24px 0 0", padding: "28px 24px 36px", boxShadow: "0 -16px 48px rgba(16,18,45,.22)" }}>
                <div style={{ width: 40, height: 4, borderRadius: 99, background: "var(--line)", margin: "0 auto 22px" }} />
                <div style={{ display: "flex", flexDirection: "column", alignItems: "center", textAlign: "center", marginBottom: 22 }}>
                  <img src="/icon-192-v2.png" alt="Morar Bem" style={{ width: 64, height: 64, borderRadius: 16, boxShadow: "0 8px 24px rgba(24,27,87,.18)", marginBottom: 14 }} />
                  <div style={{ font: "800 20px var(--ui)", color: "var(--text)", lineHeight: 1.25, marginBottom: 6 }}>Instalar o Morar Bem</div>
                  <div style={{ font: "500 13px var(--ui)", color: "var(--muted)", lineHeight: 1.55 }}>Adicione à sua tela inicial para acesso rápido</div>
                </div>
                {(() => {
                  const iconShare = <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M4 12v8a2 2 0 002 2h12a2 2 0 002-2v-8"/><polyline points="16 6 12 2 8 6"/><line x1="12" y1="2" x2="12" y2="15"/></svg>;
                  const iconPlus  = <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><rect x="3" y="3" width="18" height="18" rx="3"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/></svg>;
                  const iconCheck = <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M5 12.5l4.5 4.5L19 7"/></svg>;
                  const iconDots  = <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><circle cx="12" cy="5" r="1"/><circle cx="12" cy="12" r="1"/><circle cx="12" cy="19" r="1"/></svg>;
                  const steps = isIOS
                    ? { label: "No Safari — iPhone / iPad", list: [
                        { icon: iconShare, txt: "Toque no botão Compartilhar na barra inferior do Safari" },
                        { icon: iconPlus,  txt: 'Role a lista e toque em "Adicionar à Tela de Início"' },
                        { icon: iconCheck, txt: 'Toque em "Adicionar" no canto superior direito' },
                      ]}
                    : isAndroid
                    ? { label: "No Chrome — Android", list: [
                        { icon: iconDots,  txt: "Toque nos três pontos (⋮) no canto superior do Chrome" },
                        { icon: iconPlus,  txt: 'Toque em "Adicionar à tela inicial"' },
                        { icon: iconCheck, txt: 'Confirme tocando em "Adicionar"' },
                      ]}
                    : { label: "No Safari — Mac", list: [
                        { icon: iconShare, txt: 'No menu "Arquivo" do Safari, clique em "Adicionar ao Dock…"' },
                        { icon: iconCheck, txt: 'Clique em "Adicionar" para confirmar' },
                      ]};
                  return (
                    <div style={{ background: "var(--bg)", borderRadius: 14, padding: "16px", marginBottom: 14 }}>
                      <div style={{ font: "700 13px var(--ui)", color: "var(--text)", marginBottom: 12 }}>{steps.label}:</div>
                      {steps.list.map((s, i) => (
                        <div key={i} style={{ display: "flex", alignItems: "flex-start", gap: 10, marginBottom: i < steps.list.length - 1 ? 10 : 0 }}>
                          <div style={{ width: 28, height: 28, borderRadius: 8, background: "var(--accent)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0, color: "#fff" }}>{s.icon}</div>
                          <span style={{ font: "500 13px var(--ui)", color: "var(--text)", lineHeight: 1.45, paddingTop: 4 }}>{s.txt}</span>
                        </div>
                      ))}
                    </div>
                  );
                })()}
                <button onClick={() => setPwaGuideOpen(false)}
                  style={{ width: "100%", background: "none", border: "none", cursor: "pointer", font: "500 13px var(--ui)", color: "var(--muted)", padding: "8px 0" }}>
                  Entendi
                </button>
              </div>
            </div>
          )}

          {/* Auth gate para aba Perfil */}
          {perfilAuthOpen && (
            <div style={{ position: "absolute", inset: 0, zIndex: 1100 }}>
              <AuthFlow onAuthed={(u) => enterApp(u, true)} onToast={flashToast} onCancel={() => setPerfilAuthOpen(false)} />
            </div>
          )}

          {splashDone && <TabBar tab={tab} onTab={handleTab} cartCount={cartCount} />}

          {/* Novo Lar (pushed) */}
          <Pushed open={novoLarOpen}>
            {novoLarOpen && <NovoLarScreen onBack={() => setNovoLarOpen(false)} onOpenStore={openStore} />}
          </Pushed>

          {/* Serviços do Lar (pushed) */}
          <Pushed open={servicesOpen}>
            {servicesOpen && <ServicesScreen onBack={() => setServicesOpen(false)} onOpenStore={openStore} />}
          </Pushed>

          {/* Roteiro Gastronômico (pushed) */}
          <Pushed open={gastroOpen}>
            {gastroOpen && <RoteiroGastrScreen onBack={() => setGastroOpen(false)} onOpenStore={openStore} />}
          </Pushed>

          {/* Perfil sub-telas (pushed) */}
          <Pushed open={!!profileView}>
            {profileView && <ProfileScreen view={profileView} onBack={() => setProfileView(null)} onToast={flashToast} onOpenStore={openStore} wallet={apiWallet || WALLET} />}
          </Pushed>

          {/* Detalhe do agendamento (pushed) */}
          <Pushed open={!!agendaDetail}>
            {agendaDetail && <AgendaDetail booking={agendaDetail} onBack={() => setAgendaDetail(null)} onToast={flashToast} />}
          </Pushed>

          {/* Central de notificações (pushed) */}
          <Pushed open={notifsOpen}>
            {notifsOpen && <NotificationsCenter list={notifList} setList={setNotifList} onBack={() => setNotifsOpen(false)} onToast={flashToast} />}
          </Pushed>

          {/* Clube de benefícios (pushed) */}
          <Pushed open={clubOpen}>
            {clubOpen && <ClubScreen member={clubMember} onSubscribe={() => subscribeClub()} onCancel={cancelClub} onBack={() => setClubOpen(false)} />}
          </Pushed>

          {/* Store (pushed) — branches by type */}
          <Pushed open={!!storeId}>
            {storePartner && (
              storePartner.type === "agenda"
                ? <AgendaStore partner={storePartner} onBack={() => setStoreId(null)} onBook={(s) => setBookInfo({ partner: storePartner, service: s })} onNeedLogin={() => setPerfilAuthOpen(true)} />
                : storePartner.type === "vitrine"
                ? <VitrineStore partner={storePartner} onBack={() => setStoreId(null)} onLead={(l) => setLeadInfo({ partner: storePartner, listing: l })} onNeedLogin={() => setPerfilAuthOpen(true)} />
                : <StoreScreen partner={storePartner} mode={storeMode} setMode={setStoreMode}
                    onBack={() => setStoreId(null)} onPick={setProduct} getQty={getQty}
                    cartCount={cart.partnerId === storeId ? cartCount : 0}
                    cartTotal={cart.partnerId === storeId ? cartTotal : 0}
                    onOpenCart={() => setCartOpen(true)} onNeedLogin={() => setPerfilAuthOpen(true)} />
            )}
          </Pushed>

          {/* Cart (pushed) */}
          <Pushed open={cartOpen && !!cartPartner}>
            {cartPartner && (
              <CartScreen cart={cart} partner={cartPartner} mode={storeMode} setMode={setStoreMode}
                onInc={inc} onDec={dec} onBack={() => setCartOpen(false)}
                onAddMore={() => { setCartOpen(false); if (storeId !== cart.partnerId) openStore(cart.partnerId); }}
                onCheckout={() => setCheckoutOpen(true)} />
            )}
          </Pushed>

          {/* Checkout (pushed) */}
          <Pushed open={checkoutOpen && !!cartPartner}>
            {cartPartner && (
              <CheckoutScreen cart={cart} partner={cartPartner} mode={storeMode} setMode={setStoreMode}
                wallet={apiWallet || { balance: 0, pending: 0, movements: [] }} onBack={() => setCheckoutOpen(false)} onConfirm={placeOrder} />
            )}
          </Pushed>

          {/* Success (pushed) */}
          <Pushed open={!!success}>
            {success && <SuccessScreen order={success} partner={resolvePartner(success.partnerId)}
              onReview={() => { const p = resolvePartner(success.partnerId); const m = success.mode; setSuccess(null); setStoreId(null); setReview({ partner: p, mode: m }); }}
              onClose={closeSuccess}
              onGoToCompras={() => { closeSuccess(); setTab("compras"); }} />}
          </Pushed>

          {/* Product sheet */}
          <Sheet open={!!product} onClose={() => setProduct(null)} title="Detalhes do item">
            {product && <ProductSheet item={product} startQty={getQty(product.id) || 1}
              totalCb={(storePartner ? storePartner.cashback + storePartner.turbo : 0)} onConfirm={confirmAdd} />}
          </Sheet>

          {/* Filters sheet */}
          <Sheet open={filtersOpen} onClose={() => setFiltersOpen(false)} title="Filtrar parceiros">
            <FiltersSheet filt={filt} setFilt={setFilt} addresses={savedAddresses} segments={apiSegments || SEGMENTS} />
            <Btn full onClick={() => setFiltersOpen(false)} style={{ marginTop: 18 }}>Ver parceiros</Btn>
          </Sheet>

          {/* Cashback info sheet */}
          <Sheet open={cashbackOpen} onClose={() => setCashbackOpen(false)} title="BemCash">
            <CashbackInfo />
          </Sheet>

          {/* Booking sheet (agenda) */}
          <Sheet open={!!bookInfo} onClose={() => setBookInfo(null)} title="Agendar serviço">
            {bookInfo && <BookingSheet partner={bookInfo.partner} service={bookInfo.service} onConfirm={confirmBooking} />}
          </Sheet>

          {/* Lead sheet (vitrine) */}
          <Sheet open={!!leadInfo} onClose={() => setLeadInfo(null)} title="Solicitar contato">
            {leadInfo && <LeadSheet partner={leadInfo.partner} listing={leadInfo.listing} onConfirm={confirmLead} user={apiUser || USER} />}
          </Sheet>

          {/* Review sheet */}
          <Sheet open={!!review} onClose={() => setReview(null)} title="Avaliar pedido">
            {review && <ReviewSheet partner={review.partner} mode={review.mode}
              onSubmit={() => { setReview(null); flashToast("Avaliação enviada. Obrigado!"); }} />}
          </Sheet>

          {/* Replace cart confirm */}
          <Sheet open={!!replaceItem} onClose={() => setReplaceItem(null)} title="Trocar de loja?">
            {replaceItem && (
              <div>
                <p style={{ font: "500 14.5px var(--ui)", color: "var(--muted)", lineHeight: 1.5, margin: "0 0 18px" }}>
                  Sua sacola tem itens de <b style={{ color: "var(--text)" }}>{cartPartner && cartPartner.name}</b>. Cada pedido é de um parceiro por vez. Deseja esvaziar e começar uma nova sacola em <b style={{ color: "var(--text)" }}>{storePartner && storePartner.name}</b>?
                </p>
                <div style={{ display: "flex", gap: 10 }}>
                  <Btn variant="ghost" style={{ flex: 1 }} onClick={() => setReplaceItem(null)}>Cancelar</Btn>
                  <Btn style={{ flex: 1 }} onClick={() => { setCart({ partnerId: null, items: {} }); reallyAdd(replaceItem.item, replaceItem.qty, replaceItem.note, storeId); setReplaceItem(null); flashToast("Nova sacola criada"); }}>Esvaziar e adicionar</Btn>
                </div>
              </div>
            )}
          </Sheet>
          </React.Fragment>
          )}

          {/* toast */}
          {toast && (
            <div style={{ position: "absolute", left: "50%", bottom: 100, transform: "translateX(-50%)", zIndex: 80, background: "var(--brand)", color: "#fff", font: "700 13.5px var(--ui)", padding: "11px 18px", borderRadius: 999, boxShadow: "0 8px 24px rgba(16,18,45,.3)", display: "flex", alignItems: "center", gap: 8, animation: "mbPop .3s ease" }}>
              <Icon name="check" size={16} color="#fff" sw={3} />{toast}
            </div>
          )}
        </div>

      <TweaksPanel>
        <TweakSection label="Estilo visual" />
        <TweakRadio label="Tema" value={t.theme} options={["marinho", "litoral", "coral"]} onChange={v => setTweak("theme", v)} />
        <TweakSelect label="Tipografia" value={t.font} options={Object.keys(FONTS)} onChange={v => setTweak("font", v)} />
        <TweakRadio label="Aparência" value={t.appearance} options={["Claro", "Escuro"]} onChange={v => setTweak("appearance", v)} />
      </TweaksPanel>
    </div>
  );
}

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