/* ============================================================
   ADMIN · MARKETING & SOCIAL — powered by the Zernio API
   ------------------------------------------------------------
   Read-only marketing cockpit + unified inbox:
     · Overview   — social KPIs + web reservations & leads pulse
     · Analytics  — per-network audience/engagement (Zernio)
     · Posts      — latest published posts w/ metrics (read-only)
     · Inbox      — DMs/comments across platforms, reply in place
     · Ads        — campaigns & ads performance (read-only)
   Publishing/scheduling is intentionally NOT here — the client
   (window.PPZernio, web/app/zernio.js) and the relay whitelist
   only read endpoints + inbox replies. Setup: docs/ZERNIO.md.
   When Zernio isn't connected yet, a clearly-labeled DEMO
   dataset renders so the team can see the full experience.
   ============================================================ */

const MKT_NETS = {
  instagram: { label: "Instagram", c: "#E1306C" },
  facebook:  { label: "Facebook",  c: "#1877F2" },
  whatsapp:  { label: "WhatsApp",  c: "#25D366" },
  tiktok:    { label: "TikTok",    c: "#8ee5ee" },
  x:         { label: "X",         c: "#9aa0aa" },
  google:    { label: "Google",    c: "#F4B400" },
};
const mktNet = (id) => MKT_NETS[String(id || "").toLowerCase()] || { label: id || "—", c: "#888" };
const mktN = (n) => { n = Number(n) || 0; return n >= 1e6 ? (n / 1e6).toFixed(1) + "M" : n >= 1e3 ? (n / 1e3).toFixed(1) + "K" : String(n); };

/* ---------- DEMO dataset (shown until Zernio is connected) ---------- */
const MKT_DEMO = {
  accounts: [
    { id: "ig", platform: "instagram", username: "@clubpinkpony", followers: 24800, engagement: 4.7, delta: 3.2 },
    { id: "fb", platform: "facebook", username: "Club Pink Pony", followers: 11200, engagement: 2.1, delta: 1.1 },
    { id: "tt", platform: "tiktok", username: "@clubpinkpony", followers: 18400, engagement: 8.9, delta: 6.4 },
    { id: "wa", platform: "whatsapp", username: "+1 (786) 503-2909", followers: 3150, engagement: 0, delta: 2.0 },
    { id: "gb", platform: "google", username: "Pink Pony Club · Doral", followers: 0, engagement: 0, rating: 4.6, delta: 0.2 },
  ],
  posts: [
    { id: "p1", platform: "instagram", type: "reel", caption: "CHACAL & YAKARTA · JUL 30 — Official Release Party 🔥 Tickets $50", at: "2026-07-15T18:00:00Z", likes: 2140, comments: 187, shares: 96, reach: 48200, img: "assets/venue/club-main-stage.webp", url: "https://www.instagram.com/p/DawXCqcu19s/" },
    { id: "p2", platform: "tiktok", type: "video", caption: "Baby's on Fire release party — la noche que Doral estaba esperando 🎤", at: "2026-07-14T22:00:00Z", likes: 5320, comments: 402, shares: 611, reach: 112000, img: "assets/photos/fire-show.webp", url: "" },
    { id: "p3", platform: "instagram", type: "photo", caption: "Free Lunch Dayshift · Lun–Vie desde 12PM — solo pagas tu entrada 🍔", at: "2026-07-13T16:00:00Z", likes: 640, comments: 41, shares: 12, reach: 9800, img: "assets/photos/burger-1.jpg", url: "" },
    { id: "p4", platform: "facebook", type: "photo", caption: "Martes de Cariñosas — luces bajas, buena compañía y botellas $150++ 💕", at: "2026-07-12T14:00:00Z", likes: 310, comments: 22, shares: 45, reach: 7400, img: "assets/photos/performers-tape.webp", url: "" },
  ],
  conversations: [
    { id: "c1", platform: "instagram", from: "maria.doral", kind: "dm", last: "Hola! Cuánto están las mesas para el 30 de julio? Somos 6 🙌", at: "2026-07-17T02:10:00Z", unread: true },
    { id: "c2", platform: "whatsapp", from: "+1 305 555 0187", kind: "dm", last: "Do you have hookah service at the tables?", at: "2026-07-16T23:40:00Z", unread: true },
    { id: "c3", platform: "facebook", from: "Carlos M.", kind: "comment", last: "Qué hora abren el jueves?", at: "2026-07-16T20:15:00Z", unread: false },
    { id: "c4", platform: "google", from: "Ana R. ★★★★★", kind: "review", last: "Best night in Doral — the show was insane!", at: "2026-07-16T04:00:00Z", unread: false },
  ],
  messages: {
    c1: [
      { id: "m1", dir: "in", text: "Hola! Cuánto están las mesas para el 30 de julio? Somos 6 🙌", at: "2026-07-17T02:10:00Z" },
    ],
    c2: [{ id: "m2", dir: "in", text: "Do you have hookah service at the tables?", at: "2026-07-16T23:40:00Z" }],
    c3: [{ id: "m3", dir: "in", text: "Qué hora abren el jueves?", at: "2026-07-16T20:15:00Z" }],
    c4: [{ id: "m4", dir: "in", text: "Best night in Doral — the show was insane!", at: "2026-07-16T04:00:00Z" }],
  },
  campaigns: [
    { id: "a1", platform: "instagram", name: "Chacal & Yakarta · Jul 30 — Tickets", status: "active", budget: 1500, spend: 486, impressions: 96300, clicks: 3120, results: 214, resultLabel: "landing visits" },
    { id: "a2", platform: "facebook", name: "VIP Tables — Always On", status: "active", budget: 800, spend: 312, impressions: 40100, clicks: 980, results: 45, resultLabel: "reservation leads" },
    { id: "a3", platform: "tiktok", name: "Baby's on Fire · Teaser", status: "paused", budget: 600, spend: 205, impressions: 88400, clicks: 2210, results: 0, resultLabel: "video views 68K" },
  ],
};

/* pull a list out of whatever envelope Zernio returns */
function mktList(res) {
  if (!res) return [];
  if (Array.isArray(res)) return res;
  return res.data || res.items || res.results || res.conversations || res.posts || res.accounts || [];
}

function useMktData() {
  const live = window.PPZernio && window.PPZernio.enabled();
  const [state, setState] = useState({ loading: !!live, live: !!live, error: "", accounts: MKT_DEMO.accounts, posts: MKT_DEMO.posts, conversations: MKT_DEMO.conversations, campaigns: MKT_DEMO.campaigns, analytics: null });
  const refresh = async () => {
    if (!(window.PPZernio && window.PPZernio.enabled())) { setState((s) => ({ ...s, live: false, loading: false })); return; }
    setState((s) => ({ ...s, loading: true, error: "" }));
    try {
      const [accounts, posts, conversations, campaigns, analytics] = await Promise.all([
        window.PPZernio.accounts().then(mktList).catch(() => []),
        window.PPZernio.posts({ limit: 12, sortBy: "publishedAt" }).then(mktList).catch(() => []),
        window.PPZernio.conversations({ limit: 30 }).then(mktList).catch(() => []),
        window.PPZernio.adCampaigns({ limit: 20 }).then(mktList).catch(() => []),
        window.PPZernio.analytics({ limit: 50 }).catch(() => null),
      ]);
      setState({ loading: false, live: true, error: "", accounts, posts, conversations, campaigns, analytics });
    } catch (e) {
      setState((s) => ({ ...s, loading: false, live: true, error: String((e && e.message) || e) }));
    }
  };
  useEffect(() => { if (live) refresh(); }, []);
  return [state, refresh];
}

/* ---------- settings (relay URL / API key) ---------- */
function MktSettings({ onClose, onSaved }) {
  const t = useT();
  const cfg = window.PPZernio.config();
  const [relayUrl, setRelayUrl] = useState(cfg.relayUrl || "");
  const [apiKey, setApiKey] = useState(cfg.apiKey || "");
  const [testing, setTesting] = useState(false);
  const inputCls = "w-full bg-ink border border-white/12 rounded-xl px-4 py-3 text-sm text-white focus:outline-none focus:border-coral placeholder:text-white/30";
  const save = () => { window.PPZernio.saveConfig({ relayUrl: relayUrl.trim(), apiKey: apiKey.trim() }); window.toast && window.toast(t("Zernio settings saved", "Configuración de Zernio guardada"), "ok"); onSaved(); };
  const test = async () => {
    window.PPZernio.saveConfig({ relayUrl: relayUrl.trim(), apiKey: apiKey.trim() });
    setTesting(true);
    try { await window.PPZernio.accounts(); window.toast && window.toast(t("Connected to Zernio ✓", "Conectado a Zernio ✓"), "ok"); onSaved(); }
    catch (e) { window.toast && window.toast(String((e && e.message) || e), "error"); }
    setTesting(false);
  };
  return (
    <div className="rounded-2xl border border-white/12 bg-card p-6 mb-6 fade-view">
      <div className="flex items-center justify-between mb-4">
        <div className="font-black uppercase tracking-wide flex items-center gap-2"><Icon name="plug-zap" className="w-4 h-4 text-coral" />{t("Zernio connection", "Conexión Zernio")}</div>
        <button onClick={onClose} className="text-white/50 hover:text-white"><Icon name="x" className="w-5 h-5" /></button>
      </div>
      <div className="grid md:grid-cols-2 gap-4">
        <label className="block"><span className="label text-white/45 text-[10px] block mb-1.5">{t("Relay URL (recommended)", "URL del Relay (recomendado)")}</span>
          <input value={relayUrl} onChange={(e) => setRelayUrl(e.target.value)} placeholder="https://…cloudfunctions.net/zernioRelay" className={inputCls} /></label>
        <label className="block"><span className="label text-white/45 text-[10px] block mb-1.5">{t("API key (direct mode — this browser only)", "API key (modo directo — solo este navegador)")}</span>
          <input value={apiKey} onChange={(e) => setApiKey(e.target.value)} type="password" placeholder="zrn_…" className={inputCls} /></label>
      </div>
      <p className="text-white/40 text-xs mt-3">{t("The relay (relay/zernio.js) holds the key server-side and only allows read + inbox-reply actions. Full setup: docs/ZERNIO.md.", "El relay (relay/zernio.js) guarda la key en el servidor y solo permite lectura + respuestas de inbox. Guía completa: docs/ZERNIO.md.")}</p>
      <div className="flex gap-3 mt-4">
        <button onClick={save} className="gbtn px-5 py-2.5 rounded-full bg-coral hover:bg-coral-deep text-white text-[11px] font-bold uppercase tracking-wider">{t("Save", "Guardar")}</button>
        <button onClick={test} disabled={testing} className="gbtn px-5 py-2.5 rounded-full border border-white/15 text-white/75 text-[11px] font-bold uppercase tracking-wider hover:bg-white/5">{testing ? t("Testing…", "Probando…") : t("Test connection", "Probar conexión")}</button>
      </div>
    </div>
  );
}

/* ---------- Overview ---------- */
function MktOverview({ D }) {
  const t = useT(); const { lang } = useLang();
  const resv = (window.PPDB.reservations.all() || []);
  const leads = (window.PPDB.leads.all() || []);
  const pend = resv.filter((r) => (r.status || "pending") === "pending").length;
  const ck = resv.filter((r) => String(r.experienceId || "").startsWith("ck-")).length;
  const followers = D.accounts.reduce((a, x) => a + (Number(x.followers) || 0), 0);
  const unread = D.conversations.filter((c) => c.unread).length;
  const spend = D.campaigns.reduce((a, x) => a + (Number(x.spend) || 0), 0);
  const cards = [
    ["users-round", t("Total audience", "Audiencia total"), mktN(followers), t("across connected accounts", "en cuentas conectadas")],
    ["inbox", t("Inbox pending", "Inbox pendiente"), unread, t("unanswered conversations", "conversaciones sin responder")],
    ["calendar-check", t("Reservations", "Reservas"), resv.length + " · " + pend + " " + t("pending", "pendientes"), ck + " " + t("for Chacal & Yakarta", "para Chacal & Yakarta")],
    ["badge-dollar-sign", t("Ads spend (period)", "Inversión Ads (período)"), "$" + mktN(spend), D.campaigns.filter((c) => c.status === "active").length + " " + t("active campaigns", "campañas activas")],
  ];
  return (
    <div>
      <div className="grid sm:grid-cols-2 xl:grid-cols-4 gap-4 mb-6">
        {cards.map(([ic, lbl, big, sub], i) => (
          <div key={i} className="rounded-2xl border border-white/12 bg-card p-5">
            <div className="flex items-center gap-2 text-white/45 mb-3"><Icon name={ic} className="w-4 h-4 text-coral" /><span className="label text-[9px]">{lbl}</span></div>
            <div className="text-3xl font-black">{big}</div>
            <div className="text-white/40 text-xs mt-1">{sub}</div>
          </div>
        ))}
      </div>
      <div className="grid lg:grid-cols-2 gap-4">
        <div className="rounded-2xl border border-white/12 bg-card p-5">
          <div className="label text-white/45 text-[10px] mb-4">{t("Accounts", "Cuentas")}</div>
          <div className="space-y-3">
            {D.accounts.map((a) => { const n = mktNet(a.platform); return (
              <div key={a.id} className="flex items-center gap-3">
                <span className="w-2.5 h-2.5 rounded-full shrink-0" style={{ background: n.c }}></span>
                <span className="font-bold text-sm">{n.label}</span>
                <span className="text-white/45 text-xs truncate">{a.username}</span>
                <span className="ml-auto text-sm font-bold">{a.rating ? "★ " + a.rating : mktN(a.followers)}</span>
                {a.delta != null && <span className={"text-[11px] font-bold " + (a.delta >= 0 ? "text-emerald-400" : "text-red-400")}>{a.delta >= 0 ? "+" : ""}{a.delta}%</span>}
              </div>
            ); })}
          </div>
        </div>
        <div className="rounded-2xl border border-white/12 bg-card p-5">
          <div className="label text-white/45 text-[10px] mb-4">{t("Latest web leads", "Últimos leads de la web")}</div>
          <div className="space-y-2.5">
            {leads.slice(0, 5).map((l, i) => (
              <div key={i} className="flex items-center gap-3 text-sm"><Icon name="circle-dot" className="w-3.5 h-3.5 text-coral shrink-0" /><span className="truncate text-white/75">{l.title || t("Lead", "Lead")}</span><span className="ml-auto text-white/35 text-xs shrink-0">{(() => { try { return new Date(l.at).toLocaleDateString(lang === "es" ? "es" : "en", { month: "short", day: "numeric" }); } catch (e) { return ""; } })()}</span></div>
            ))}
            {!leads.length && <div className="text-white/35 text-sm">{t("No leads captured yet.", "Aún no hay leads capturados.")}</div>}
          </div>
        </div>
      </div>
    </div>
  );
}

/* ---------- Analytics ---------- */
function MktAnalytics({ D }) {
  const t = useT();
  const max = Math.max(...D.accounts.map((a) => Number(a.followers) || 0), 1);
  return (
    <div className="space-y-4">
      <div className="rounded-2xl border border-white/12 bg-card p-5">
        <div className="label text-white/45 text-[10px] mb-4">{t("Audience by network", "Audiencia por red")}</div>
        <div className="space-y-4">
          {D.accounts.filter((a) => a.followers).map((a) => { const n = mktNet(a.platform); return (
            <div key={a.id}>
              <div className="flex items-center justify-between text-xs mb-1.5"><span className="font-bold">{n.label} <span className="text-white/40 font-normal">{a.username}</span></span><span className="font-bold">{mktN(a.followers)}</span></div>
              <div className="h-2.5 rounded-full bg-white/8 overflow-hidden"><div className="h-full rounded-full" style={{ width: (100 * (Number(a.followers) || 0) / max) + "%", background: n.c }}></div></div>
            </div>
          ); })}
        </div>
      </div>
      <div className="grid sm:grid-cols-3 gap-4">
        {D.accounts.filter((a) => a.engagement).map((a) => { const n = mktNet(a.platform); return (
          <div key={a.id} className="rounded-2xl border border-white/12 bg-card p-5 text-center">
            <div className="label text-[9px] mb-2" style={{ color: n.c }}>{n.label}</div>
            <div className="text-3xl font-black">{a.engagement}%</div>
            <div className="text-white/40 text-xs mt-1">{t("engagement rate", "tasa de engagement")}</div>
          </div>
        ); })}
      </div>
      <p className="text-white/35 text-xs">{t("Live metrics come from Zernio Analytics (per-post and per-account) once connected.", "Las métricas en vivo vienen de Zernio Analytics (por publicación y por cuenta) al conectar.")}</p>
    </div>
  );
}

/* ---------- Posts (read-only) ---------- */
function MktPosts({ D }) {
  const t = useT(); const { lang } = useLang();
  const fmt = (iso) => { try { return new Date(iso).toLocaleDateString(lang === "es" ? "es" : "en", { month: "short", day: "numeric" }); } catch (e) { return ""; } };
  return (
    <div>
      <div className="grid sm:grid-cols-2 xl:grid-cols-4 gap-4">
        {D.posts.map((p) => { const n = mktNet(p.platform); return (
          <div key={p.id} className="rounded-2xl border border-white/12 bg-card overflow-hidden flex flex-col">
            <div className="relative h-40 bg-black/50">
              {p.img && <Photo src={p.img} alt="" className="absolute inset-0 w-full h-full" imgClass="object-cover" />}
              <span className="absolute top-2.5 left-2.5 text-[9px] font-bold uppercase tracking-wider px-2 py-1 rounded-full text-white" style={{ background: n.c }}>{n.label}{p.type ? " · " + p.type : ""}</span>
            </div>
            <div className="p-4 flex-1 flex flex-col">
              <p className="text-white/75 text-xs leading-relaxed line-clamp-3 flex-1">{p.caption}</p>
              <div className="flex items-center gap-3 text-[11px] text-white/50 mt-3">
                <span className="inline-flex items-center gap-1"><Icon name="heart" className="w-3.5 h-3.5" />{mktN(p.likes)}</span>
                <span className="inline-flex items-center gap-1"><Icon name="message-circle" className="w-3.5 h-3.5" />{mktN(p.comments)}</span>
                <span className="inline-flex items-center gap-1"><Icon name="eye" className="w-3.5 h-3.5" />{mktN(p.reach)}</span>
                <span className="ml-auto">{fmt(p.at)}</span>
              </div>
              {p.url ? <a href={p.url} target="_blank" rel="noopener" className="mt-3 text-coral text-[10px] font-bold uppercase tracking-wider inline-flex items-center gap-1 hover:brightness-125">{t("Open post", "Ver publicación")} <Icon name="arrow-up-right" className="w-3 h-3" /></a> : null}
            </div>
          </div>
        ); })}
      </div>
      <p className="text-white/35 text-xs mt-4 flex items-center gap-2"><Icon name="lock" className="w-3.5 h-3.5" />{t("Read-only by design — publishing & scheduling are disabled in this portal.", "Solo lectura por diseño — publicar y programar posts está deshabilitado en este portal.")}</p>
    </div>
  );
}

/* ---------- Inbox ---------- */
function MktInbox({ D, live }) {
  const t = useT(); const { lang } = useLang();
  const [openId, setOpenId] = useState(D.conversations[0] ? D.conversations[0].id : null);
  const [thread, setThread] = useState(null);
  const [reply, setReply] = useState("");
  const [sending, setSending] = useState(false);
  const conv = D.conversations.find((c) => c.id === openId) || null;
  const fmt = (iso) => { try { return new Date(iso).toLocaleString(lang === "es" ? "es" : "en", { month: "short", day: "numeric", hour: "numeric", minute: "2-digit" }); } catch (e) { return ""; } };

  useEffect(() => {
    let on = true;
    setThread(null);
    if (!openId) return;
    if (live && window.PPZernio.enabled()) {
      window.PPZernio.messages(openId).then(mktList).then((m) => { if (on) setThread(m); }).catch(() => { if (on) setThread([]); });
    } else {
      setThread(MKT_DEMO.messages[openId] || []);
    }
    return () => { on = false; };
  }, [openId, live]);

  const send = async () => {
    const text = reply.trim();
    if (!text || !conv) return;
    setSending(true);
    try {
      if (live && window.PPZernio.enabled()) await window.PPZernio.sendMessage(conv.id, text);
      setThread((th) => [...(th || []), { id: "loc" + Date.now(), dir: "out", text, at: new Date().toISOString() }]);
      setReply("");
      window.toast && window.toast(t("Reply sent", "Respuesta enviada"), "ok");
    } catch (e) { window.toast && window.toast(String((e && e.message) || e), "error"); }
    setSending(false);
  };

  return (
    <div className="grid lg:grid-cols-[300px_1fr] gap-4 items-start">
      <div className="rounded-2xl border border-white/12 bg-card overflow-hidden">
        {D.conversations.map((c) => { const n = mktNet(c.platform); return (
          <button key={c.id} onClick={() => setOpenId(c.id)} className={"w-full text-left px-4 py-3.5 border-b border-white/6 transition-colors " + (openId === c.id ? "bg-coral/10" : "hover:bg-white/4")}>
            <div className="flex items-center gap-2 mb-1">
              <span className="w-2 h-2 rounded-full shrink-0" style={{ background: n.c }}></span>
              <span className="font-bold text-sm truncate">{c.from}</span>
              {c.unread && <span className="w-1.5 h-1.5 rounded-full bg-coral shrink-0"></span>}
              <span className="ml-auto text-[10px] text-white/35 shrink-0 uppercase">{c.kind}</span>
            </div>
            <div className="text-white/50 text-xs truncate">{c.last}</div>
          </button>
        ); })}
        {!D.conversations.length && <div className="p-5 text-white/35 text-sm">{t("No conversations.", "Sin conversaciones.")}</div>}
      </div>
      <div className="rounded-2xl border border-white/12 bg-card flex flex-col min-h-[380px]">
        {conv ? (
          <React.Fragment>
            <div className="px-5 py-4 border-b border-white/8 flex items-center gap-2.5">
              <span className="w-2.5 h-2.5 rounded-full" style={{ background: mktNet(conv.platform).c }}></span>
              <span className="font-bold">{conv.from}</span>
              <span className="text-white/35 text-xs">{mktNet(conv.platform).label} · {conv.kind}</span>
              <span className="ml-auto text-white/35 text-xs">{fmt(conv.at)}</span>
            </div>
            <div className="flex-1 p-5 space-y-3 overflow-y-auto">
              {thread == null && <div className="text-white/35 text-sm">{t("Loading…", "Cargando…")}</div>}
              {(thread || []).map((m) => (
                <div key={m.id} className={"max-w-[80%] rounded-2xl px-4 py-2.5 text-sm " + (m.dir === "out" ? "ml-auto bg-coral text-white" : "bg-white/8 text-white/85")}>{m.text}</div>
              ))}
            </div>
            <div className="p-4 border-t border-white/8 flex gap-2.5">
              <input value={reply} onChange={(e) => setReply(e.target.value)} onKeyDown={(e) => e.key === "Enter" && send()} placeholder={t("Type a reply…", "Escribe una respuesta…")} className="flex-1 bg-ink border border-white/12 rounded-full px-4 py-3 text-sm text-white focus:outline-none focus:border-coral placeholder:text-white/30" />
              <button onClick={send} disabled={sending || !reply.trim()} className="gbtn w-11 h-11 rounded-full bg-coral hover:bg-coral-deep text-white flex items-center justify-center disabled:opacity-40"><Icon name="send" className="w-4 h-4" /></button>
            </div>
          </React.Fragment>
        ) : <div className="m-auto text-white/35 text-sm p-8">{t("Pick a conversation.", "Elige una conversación.")}</div>}
      </div>
    </div>
  );
}

/* ---------- Ads (read-only) ---------- */
function MktAds({ D }) {
  const t = useT();
  const ST = { active: { l: t("Active", "Activa"), c: "#34d399" }, paused: { l: t("Paused", "Pausada"), c: "#CBA35C" }, ended: { l: t("Ended", "Terminada"), c: "#888" } };
  return (
    <div className="rounded-2xl border border-white/12 bg-card overflow-x-auto">
      <table className="w-full text-sm min-w-[720px]">
        <thead><tr className="text-left text-white/40 text-[10px] uppercase tracking-wider border-b border-white/8">
          {[t("Campaign", "Campaña"), t("Network", "Red"), t("Status", "Estado"), t("Budget", "Presupuesto"), t("Spend", "Gastado"), "Impr.", "Clicks", t("Results", "Resultados")].map((h, i) => <th key={i} className="px-4 py-3 font-semibold">{h}</th>)}
        </tr></thead>
        <tbody>
          {D.campaigns.map((c) => { const n = mktNet(c.platform); const st = ST[c.status] || ST.ended; return (
            <tr key={c.id} className="border-b border-white/5 hover:bg-white/3">
              <td className="px-4 py-3.5 font-bold">{c.name}</td>
              <td className="px-4 py-3.5"><span className="inline-flex items-center gap-1.5"><span className="w-2 h-2 rounded-full" style={{ background: n.c }}></span>{n.label}</span></td>
              <td className="px-4 py-3.5"><span className="text-[10px] font-bold uppercase tracking-wider px-2 py-1 rounded-full" style={{ background: st.c + "22", color: st.c }}>{st.l}</span></td>
              <td className="px-4 py-3.5 text-white/70">${mktN(c.budget)}</td>
              <td className="px-4 py-3.5 font-bold">${mktN(c.spend)}</td>
              <td className="px-4 py-3.5 text-white/70">{mktN(c.impressions)}</td>
              <td className="px-4 py-3.5 text-white/70">{mktN(c.clicks)}</td>
              <td className="px-4 py-3.5 text-white/70">{c.results ? c.results + " " + (c.resultLabel || "") : (c.resultLabel || "—")}</td>
            </tr>
          ); })}
        </tbody>
      </table>
    </div>
  );
}

/* ---------- module shell ---------- */
function MarketingModule() {
  const t = useT();
  const [D, refresh] = useMktData();
  const [tab, setTab] = useState("overview");
  const [showCfg, setShowCfg] = useState(false);
  const connected = window.PPZernio && window.PPZernio.enabled();
  const tabs = [
    ["overview", t("Overview", "Resumen"), "layout-dashboard"],
    ["analytics", t("Analytics", "Analíticas"), "chart-no-axes-combined"],
    ["posts", t("Posts", "Publicaciones"), "image"],
    ["inbox", t("Inbox", "Inbox"), "inbox"],
    ["ads", "Ads", "badge-dollar-sign"],
  ];
  return (
    <div>
      {/* status bar */}
      <div className="flex flex-wrap items-center gap-3 mb-5">
        <span className={"inline-flex items-center gap-2 px-3.5 py-2 rounded-full border text-[11px] font-bold uppercase tracking-wider " + (connected ? "border-emerald-400/40 bg-emerald-400/10 text-emerald-300" : "border-[#CBA35C]/40 bg-[#CBA35C]/10 text-[#e5c07b]")}>
          <span className={"w-1.5 h-1.5 rounded-full " + (connected ? "bg-emerald-400" : "bg-[#CBA35C]")}></span>
          {connected ? "Zernio · " + (window.PPZernio.mode() === "relay" ? t("connected via relay", "conectado vía relay") : t("direct mode", "modo directo")) : t("Demo data — connect Zernio", "Datos demo — conecta Zernio")}
        </span>
        {D.error && <span className="text-red-400 text-xs">{D.error}</span>}
        <div className="ml-auto flex gap-2">
          {connected && <button onClick={refresh} disabled={D.loading} className="px-4 py-2 rounded-full border border-white/12 text-white/60 hover:text-white text-[11px] font-bold uppercase tracking-wider inline-flex items-center gap-2"><Icon name="refresh-cw" className={"w-3.5 h-3.5 " + (D.loading ? "animate-spin" : "")} />{t("Refresh", "Actualizar")}</button>}
          <button onClick={() => setShowCfg((v) => !v)} className="px-4 py-2 rounded-full border border-white/12 text-white/60 hover:text-white text-[11px] font-bold uppercase tracking-wider inline-flex items-center gap-2"><Icon name="settings-2" className="w-3.5 h-3.5" />{t("Connect", "Conectar")}</button>
        </div>
      </div>
      {showCfg && <MktSettings onClose={() => setShowCfg(false)} onSaved={() => { setShowCfg(false); refresh(); }} />}
      {/* tabs */}
      <div className="flex gap-2 overflow-x-auto pb-1 mb-5">
        {tabs.map(([id, lbl, ic]) => (
          <button key={id} onClick={() => setTab(id)} className={"shrink-0 inline-flex items-center gap-2 px-4 py-2.5 rounded-full text-[11px] font-bold uppercase tracking-wider transition-all " + (tab === id ? "bg-coral text-white" : "bg-card border border-white/12 text-white/60 hover:text-white")}>
            <Icon name={ic} className="w-4 h-4" />{lbl}
          </button>
        ))}
      </div>
      <div key={tab} className="fade-view">
        {tab === "overview" && <MktOverview D={D} />}
        {tab === "analytics" && <MktAnalytics D={D} />}
        {tab === "posts" && <MktPosts D={D} />}
        {tab === "inbox" && <MktInbox D={D} live={connected} />}
        {tab === "ads" && <MktAds D={D} />}
      </div>
    </div>
  );
}

Object.assign(window, { MarketingModule });
