/* JARVIS Overlay — floating launcher + slide-in chat panel.
   Available on every page. Carries the brain of the site. */

const JarvisLogo = window.JarvisLogo || (({ size = 32, pulse = false, glow = true }) => (
  <svg width={size} height={size} viewBox="0 0 40 40" style={{ display: "block", flexShrink: 0 }}>
    <defs>
      <linearGradient id="jv-grad-ov" x1="0" y1="0" x2="1" y2="1">
        <stop offset="0%" stopColor="oklch(0.85 0.18 248)" />
        <stop offset="50%" stopColor="oklch(0.72 0.17 270)" />
        <stop offset="100%" stopColor="oklch(0.58 0.18 300)" />
      </linearGradient>
      <radialGradient id="jv-core-ov" cx="50%" cy="50%" r="50%">
        <stop offset="0%" stopColor="oklch(0.98 0.04 250)" stopOpacity="1"/>
        <stop offset="60%" stopColor="oklch(0.78 0.18 250)" stopOpacity="0.9"/>
        <stop offset="100%" stopColor="oklch(0.55 0.18 270)" stopOpacity="0"/>
      </radialGradient>
      <filter id="jv-blur-ov"><feGaussianBlur stdDeviation="1.2" /></filter>
    </defs>
    <polygon points="20,3 34,11 34,29 20,37 6,29 6,11" fill="none" stroke="url(#jv-grad-ov)" strokeWidth="1.5"
             style={pulse ? { animation: "jv-rotate 12s linear infinite", transformOrigin: "center" } : null}/>
    <polygon points="20,9 29,14 29,26 20,31 11,26 11,14" fill="none" stroke="url(#jv-grad-ov)" strokeWidth="1" opacity="0.5"/>
    {glow && <circle cx="20" cy="20" r="9" fill="url(#jv-core-ov)" filter="url(#jv-blur-ov)"/>}
    <circle cx="20" cy="20" r="3" fill="oklch(0.95 0.05 250)"
            style={pulse ? { animation: "jv-pulse 2s ease-in-out infinite" } : null}/>
    <circle cx="20" cy="3" r="1.2" fill="oklch(0.85 0.18 248)"/>
    <circle cx="34" cy="29" r="1.2" fill="oklch(0.72 0.17 270)"/>
    <circle cx="6" cy="29" r="1.2" fill="oklch(0.58 0.18 300)"/>
  </svg>
));

// Local intent answer used when cloud proxies are unreachable (local preview, missing secrets, etc.).
// Lightweight rules — looks at the question and answers from in-memory PRODUCTS / SUPPLIERS / ALERTS / trash.
const localAnswer = (q) => {
  const lower = (q || "").toLowerCase();
  const products  = (typeof PRODUCTS  !== "undefined" ? PRODUCTS  : []);
  const suppliers = (typeof SUPPLIERS !== "undefined" ? SUPPLIERS : []);
  const alerts    = (typeof ALERTS    !== "undefined" ? ALERTS    : []);
  const trash     = window.KCCTrash ? window.KCCTrash.list() : [];

  if (/combien.*produits?|nombre.*produits?|inventaire/.test(lower)) {
    return { text: `Tu as **${products.length}** produits en base. ${products.length === 0 ? "Ajoute-en via Recherche de produits." : ""}` };
  }
  if (/combien.*fournisseurs?|nombre.*fournisseurs?|annuaire/.test(lower)) {
    return { text: `**${suppliers.length}** fournisseurs dans l'annuaire.` };
  }
  if (/alertes?|alerte/.test(lower)) {
    return { text: `**${alerts.length}** alerte(s) actives.` };
  }
  if (/corbeille|trash|supprim/.test(lower)) {
    return { text: `Corbeille : **${trash.length}** élément(s). Restaurables depuis Paramètres → Corbeille.` };
  }
  if (/bonjour|salut|hello|hi\b/.test(lower)) {
    return { text: `Bonjour. Je suis en mode local — pose-moi des questions sur tes produits, fournisseurs, alertes, ou demande-moi d'ouvrir une page.` };
  }
  if (/aide|help|que peux-tu|capacit/.test(lower)) {
    return { text: `Je peux :\n- Naviguer entre pages (\"ouvre dashboard\", \"montre les fournisseurs\")\n- Compter produits, fournisseurs, alertes\n- Lister la corbeille\n\nPour réponses IA complètes : déployer sur Cloudflare avec ANTHROPIC_KEY ou GEMINI_API_KEY.` };
  }
  return null;
};
window.localAnswer = localAnswer;

const JARVIS_INTRO = "JARVIS opère le portail en continu. Recalcul KPIs · surveillance stocks · arbitrage marges. Demandez-moi n'importe quoi, ou laissez-moi agir.";

const QUICK_ACTIONS = [
  { icon: "dashboard",  label: "Ouvrir Dashboard",     navigate: "dashboard" },
  { icon: "grid",       label: "Recherche produits",   navigate: "research" },
  { icon: "dollar",     label: "ProfitCalcPro",        navigate: "profit-calc" },
  { icon: "chart",      label: "Finances",             navigate: "finance" },
];

// Live activity feed shown in the overlay — JARVIS is "operating"
const ACTIVITY_LINES = [
  { t: "il y a 12s",  ic: "refresh",  text: "Synchronisation Amazon SP-API · 18 ASIN · 142 datapoints",         tone: "blue" },
  { t: "il y a 38s",  ic: "chart",    text: "Recalculé marge nette 30j : $36,910 (+$210 vs cache)",              tone: "green" },
  { t: "il y a 1m",   ic: "bell",     text: "Détecté risque rupture · Couvre-volant cuir · alerte rouge créée",   tone: "red" },
  { t: "il y a 2m",   ic: "dollar",   text: "Réconciliation CIBC · 4 transactions matchées automatiquement",     tone: "green" },
  { t: "il y a 3m",   ic: "target",   text: "OpportunityFinder · 3 candidats BSR<2k & marge>30% détectés",       tone: "blue" },
  { t: "il y a 5m",   ic: "truck",    text: "FBA-2034 mis à jour · douanes dégagées · ETA 18 mai confirmée",     tone: "blue" },
  { t: "il y a 7m",   ic: "sparkles", text: "Suggestion Autopilot générée · seuil stock 25→30 · en attente",     tone: "amber" },
  { t: "il y a 12m",  ic: "lock",     text: "Lecture refusée · table 'audit_log' · table sensible · noté",        tone: "muted" },
];

// Simple intent parser — looks for navigation triggers in user input
const NAV_KEYWORDS = {
  dashboard:      ["dashboard", "tableau", "accueil", "récap"],
  research:       ["recherche", "produits", "catalogue", "asin"],
  "profit-calc":  ["calc", "marge", "profit", "rentabilité"],
  finance:        ["finance", "trésorerie", "cashflow", "revenus"],
  supplier:       ["fournisseur", "supplier", "approvisionnement"],
  email:          ["digest", "email"],
  settings:       ["paramètres", "settings", "réglages", "préférences"],
  jarvis:         ["console", "agent"],
};

const detectNav = (text) => {
  const lower = text.toLowerCase();
  if (!/(ouvre|va à|montre|affiche|navigue)/.test(lower)) return null;
  for (const [page, words] of Object.entries(NAV_KEYWORDS)) {
    if (words.some(w => lower.includes(w))) return page;
  }
  return null;
};

const JarvisOverlay = ({ onNavigate, currentPage, openTick = 0 }) => {
  const toast = useToast();
  const [currentUser] = (window.useCurrentUser || (() => ["clarens"]))();
  const userInfo = {
    clarens: { name: "Clarens", role: "CFO", focus: "finance, marges, trésorerie" },
    kevin:   { name: "Kevin",   role: "COO", focus: "fournisseurs, MOQ, délais" },
    carly:   { name: "Carly",   role: "CPO", focus: "produits, BSR, opportunités" },
  }[currentUser] || { name: "Clarens", role: "CFO", focus: "finance" };
  const intro = `Bonjour ${userInfo.name}. JARVIS opère le portail en continu. Recalcul KPIs · surveillance stocks · arbitrage marges. Comme ${userInfo.role}, demandez-moi ce qui touche ${userInfo.focus} — ou n'importe quoi d'autre.`;
  const [open, setOpen] = useState(false);
  const [tab, setTab] = useState("chat");
  const [messages, setMessages] = useState([
    { role: "assistant", content: intro, t: new Date().toLocaleTimeString("fr-CA", { hour: "2-digit", minute: "2-digit" }) }
  ]);
  const [input, setInput] = useState("");
  const [thinking, setThinking] = useState(false);
  const scrollRef = useRef(null);

  // Reset greeting when user switches accounts
  useEffect(() => {
    setMessages([{ role: "assistant", content: intro, t: new Date().toLocaleTimeString("fr-CA", { hour: "2-digit", minute: "2-digit" }) }]);
  }, [currentUser]);

  // Open overlay when topbar pill or hotkey requests
  useEffect(() => { if (openTick > 0) setOpen(true); }, [openTick]);
  useEffect(() => {
    const onKey = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === "j") {
        e.preventDefault(); setOpen(o => !o);
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, []);

  // Heartbeat pulse for the launcher
  const [pulse, setPulse] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setPulse(p => p + 1), 4000);
    return () => clearInterval(id);
  }, []);

  useEffect(() => {
    if (open && tab === "chat") {
      scrollRef.current?.scrollTo({ top: scrollRef.current.scrollHeight, behavior: "smooth" });
    }
  }, [open, messages, thinking, tab]);

  // Cache live context across messages (5 min TTL) to avoid re-hitting APIs
  const liveCacheRef = useRef({ data: null, fetched: 0 });

  const fetchLiveContext = async () => {
    const now = Date.now();
    if (liveCacheRef.current.data && (now - liveCacheRef.current.fetched) < 5 * 60 * 1000) {
      return liveCacheRef.current.data;
    }
    const live = { finance: null, inventory: null, alerts_live: null, sync: null, errors: [] };
    if (window.kccAPI) {
      const settled = await Promise.allSettled([
        window.kccAPI.amazon.finance({ days: 30 }),
        window.kccAPI.amazon.inventory({}),
        window.kccAPI.sync.pull(),
      ]);
      if (settled[0].status === "fulfilled") live.finance = settled[0].value;
      else live.errors.push(`finance: ${settled[0].reason?.message || settled[0].reason}`);
      if (settled[1].status === "fulfilled") live.inventory = settled[1].value;
      else live.errors.push(`inventory: ${settled[1].reason?.message || settled[1].reason}`);
      if (settled[2].status === "fulfilled") live.sync = settled[2].value;
      else live.errors.push(`sync: ${settled[2].reason?.message || settled[2].reason}`);
    }
    liveCacheRef.current = { data: live, fetched: now };
    return live;
  };

  const buildContext = async () => {
    const live = await fetchLiveContext();
    const today = new Date().toISOString().slice(0, 10);
    return {
      page: currentPage,
      today,
      products: (typeof PRODUCTS !== "undefined" ? PRODUCTS : []).map(p => ({ asin: p.asin, name: p.name, cat: p.cat, status: p.status, price: p.price, cost: p.cost, margin: p.margin, bsr: p.bsr, stock: p.stock, vel: p.vel, owner: p.owner })),
      suppliers: (typeof SUPPLIERS !== "undefined" ? SUPPLIERS : []).map(s => ({ name: s.name, rating: s.rating, leadDays: s.leadDays, score: s.score, terms: s.terms })),
      alerts: (typeof ALERTS !== "undefined" ? ALERTS : []),
      // Real live data via Cloudflare proxies
      live: {
        amazon_finance: live.finance,
        amazon_inventory: live.inventory,
        kv_sync: live.sync,
        fetch_errors: live.errors,
      },
    };
  };

  const ask = async (text) => {
    const q = (text ?? input).trim();
    if (!q || thinking) return;
    const now = new Date().toLocaleTimeString("fr-CA", { hour: "2-digit", minute: "2-digit" });

    // Intent: navigation
    const navTo = detectNav(q);
    setMessages(m => [...m, { role: "user", content: q, t: now }]);
    setInput("");

    if (navTo) {
      setMessages(m => [...m, { role: "assistant", content: `J'ouvre **${navTo === "profit-calc" ? "ProfitCalcPro" : navTo}** pour vous.`, t: now, action: { type: "nav", page: navTo } }]);
      setTimeout(() => { onNavigate(navTo); toast({ message: `JARVIS → ${navTo}`, tone: "blue" }); }, 400);
      return;
    }

    setThinking(true);
    try {
      const ctx = await buildContext();
      const sys = `Tu es JARVIS, l'opérateur du portail KCC Holdings. Tu es responsable des calculs et de la surveillance temps réel : KPIs, marges, stocks, alertes.
Tu PARLES AVEC : ${userInfo.name} (${userInfo.role}). Centre d'intérêt principal : ${userInfo.focus}. Adapte tes réponses à ce rôle.
Tu as accès LIVE (via Cloudflare proxies) aux: Amazon SP-API (finance, inventaire, orders), Keepa (BSR/price history), Resend (emails), D1/KV (sync multi-appareils), Anthropic/Gemini (raisonnement).
Les données "live.*" ci-dessous viennent des vrais endpoints. Si fetch_errors n'est pas vide, signale-le.
Tu n'as pas accès aux mots de passe, secrets 2FA, données bancaires détaillées, ou logs IP.
Tu réponds en français, concis, comme un analyste senior. Phrases courtes. Listes à puces, chiffres précis. Cite les vraies valeurs de live.* quand pertinent. Pas d'intro inutile.
Page courante: ${ctx.page}. Date: ${ctx.today}.

DONNÉES:
${JSON.stringify(ctx, null, 2)}`;
      // Route via Cloudflare proxy → Anthropic (with Gemini fallback)
      const msgs = [
        ...messages.slice(-4).map(m => ({ role: m.role, content: m.content })),
        { role: "user", content: q },
      ];
      let reply = "";
      let lastErr = null;
      try {
        const r = await window.kccAPI.anthropic({
          model: "claude-sonnet-4-6",
          system: sys,
          messages: msgs,
          max_tokens: 1024,
        });
        reply = r?.content?.[0]?.text || r?.content || r?.text || "";
      } catch (anthErr) {
        lastErr = anthErr;
        // Fallback to Gemini if Anthropic proxy fails
        try {
          const g = await window.kccAPI.gemini({ prompt: sys + "\n\nUser: " + q });
          reply = g?.text || g?.response || g?.candidates?.[0]?.content?.parts?.[0]?.text || "";
          if (reply) lastErr = null;
        } catch (gemErr) {
          lastErr = gemErr;
        }
      }
      if (!reply) {
        // Final fallback: local intent answer using PRODUCTS/SUPPLIERS/REVENUE
        const localFn = typeof localAnswer === "function" ? localAnswer : (window.localAnswer || null);
        const local = localFn ? localFn(q) : null;
        if (local && local.text) {
          reply = local.text + "\n\n_(JARVIS en mode local — proxies cloud indisponibles)_";
        } else {
          const isLocalhost = /^(localhost|127\.|0\.0\.0\.0)/.test(location.hostname);
          reply = isLocalhost
            ? "⚠️ JARVIS cloud indisponible en local. Déploie sur kcc-admin.pages.dev pour réponses IA complètes."
            : `⚠️ JARVIS indisponible : ${lastErr?.message || "erreur inconnue"}. Vérifie les secrets Cloudflare (ANTHROPIC_KEY, GEMINI_API_KEY).`;
        }
      }
      setMessages(m => [...m, { role: "assistant", content: reply, t: new Date().toLocaleTimeString("fr-CA", { hour: "2-digit", minute: "2-digit" }) }]);
    } catch (e) {
      setMessages(m => [...m, { role: "assistant", content: `⚠️ Erreur JARVIS : ${e.message || "inconnue"}. Réessayez ou vérifiez la console.`, t: now }]);
    } finally {
      setThinking(false);
    }
  };

  const renderContent = (text) => text.split("\n").map((line, i) => {
    const isBullet = /^[-•*]\s/.test(line.trim());
    const clean = line.trim().replace(/^[-•*]\s/, "");
    const html = clean
      .replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>")
      .replace(/`([^`]+)`/g, '<code style="font-family:var(--font-mono);background:var(--bg-3);padding:1px 5px;border-radius:3px;font-size:11px">$1</code>');
    if (line.trim() === "") return <div key={i} style={{ height: 5 }}/>;
    if (isBullet) return <div key={i} style={{ display: "flex", gap: 6, marginTop: 3 }}><span style={{ color: "var(--accent)", flexShrink: 0 }}>•</span><span dangerouslySetInnerHTML={{ __html: html }}/></div>;
    return <div key={i} style={{ marginTop: i ? 3 : 0 }} dangerouslySetInnerHTML={{ __html: html }}/>;
  });

  return (
    <>
      {/* Floating launcher */}
      {!open && (
        <button onClick={() => setOpen(true)} style={{
          position: "fixed", bottom: 20, right: 20, zIndex: 50,
          width: 56, height: 56, borderRadius: "50%",
          background: "linear-gradient(135deg, oklch(0.55 0.18 270), oklch(0.4 0.15 280))",
          border: "1px solid color-mix(in oklch, var(--accent) 50%, transparent)",
          boxShadow: "0 8px 32px oklch(0.45 0.18 270 / 0.4), 0 0 0 1px oklch(0.85 0.18 248 / 0.2) inset",
          cursor: "pointer", display: "grid", placeItems: "center",
          transition: "transform 200ms",
        }}
        title="Parler à JARVIS"
        onMouseEnter={(e) => e.currentTarget.style.transform = "scale(1.06)"}
        onMouseLeave={(e) => e.currentTarget.style.transform = "scale(1)"}>
          <JarvisLogo size={36} pulse/>
          {/* Activity pulse ring */}
          <span key={pulse} style={{
            position: "absolute", inset: 0, borderRadius: "50%",
            border: "2px solid oklch(0.78 0.18 270)",
            animation: "jv-ring 2s ease-out forwards", pointerEvents: "none",
          }}/>
        </button>
      )}

      {/* Slide-in panel */}
      {open && (
        <div style={{
          position: "fixed", bottom: 16, right: 16, zIndex: 50,
          width: 420, height: "calc(100vh - 32px)", maxHeight: 720,
          background: "var(--bg-1)",
          border: "1px solid var(--border)",
          borderRadius: 16, overflow: "hidden",
          boxShadow: "0 24px 60px -10px oklch(0 0 0 / 0.6), 0 0 0 1px oklch(0.85 0.18 248 / 0.1)",
          display: "flex", flexDirection: "column",
          animation: "jv-slide-in 250ms cubic-bezier(0.2, 0.7, 0.3, 1)",
        }}>
          {/* Header */}
          <div style={{
            padding: "12px 14px",
            borderBottom: "1px solid var(--border-subtle)",
            background: "linear-gradient(135deg, color-mix(in oklch, var(--accent) 10%, var(--bg-1)), var(--bg-1) 60%)",
          }}>
            <div className="row" style={{ gap: 10 }}>
              <JarvisLogo size={28} pulse/>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div className="row" style={{ gap: 6 }}>
                  <span style={{ fontSize: 13, fontWeight: 600 }}>JARVIS</span>
                  <Badge tone="green" dot>opère</Badge>
                </div>
                <div className="mono" style={{ fontSize: 10, color: "var(--text-dim)", marginTop: 2 }}>
                  47ms · dernier recalcul KPI à 14:32:18
                </div>
              </div>
              <button className="icon-btn" onClick={() => onNavigate("jarvis")} title="Ouvrir console pleine">
                <Icon name="layers" size={13}/>
              </button>
              <button className="icon-btn" onClick={() => setOpen(false)} title="Fermer">
                <Icon name="x" size={13}/>
              </button>
            </div>

            {/* Tab switcher */}
            <div style={{ display: "flex", gap: 0, background: "var(--bg-2)", borderRadius: 6, padding: 2, marginTop: 10 }}>
              {[["chat", "Chat"], ["activity", "Activité live"]].map(([id, label]) => (
                <button key={id} onClick={() => setTab(id)} style={{
                  flex: 1, height: 24, padding: 0, borderRadius: 4, fontSize: 11.5,
                  background: tab === id ? "var(--bg-4)" : "transparent",
                  color: tab === id ? "var(--text)" : "var(--text-dim)",
                  fontWeight: tab === id ? 600 : 400, cursor: "pointer", border: "none",
                }}>{label}</button>
              ))}
            </div>
          </div>

          {/* Body */}
          {tab === "chat" ? (
            <>
              <div ref={scrollRef} style={{ flex: 1, overflow: "auto", padding: 14 }}>
                {messages.map((m, i) => (
                  <div key={i} style={{ display: "flex", gap: 8, marginBottom: 14 }}>
                    {m.role === "assistant" ? <JarvisLogo size={20} glow={false}/> : <Avatar user={currentUser} size="sm"/>}
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div className="row" style={{ gap: 6, marginBottom: 3 }}>
                        <span style={{ fontSize: 11, fontWeight: 600 }}>{m.role === "assistant" ? "JARVIS" : "Vous"}</span>
                        <span className="mono" style={{ fontSize: 10, color: "var(--text-faint)" }}>{m.t}</span>
                      </div>
                      <div style={{ fontSize: 12.5, lineHeight: 1.5 }}>{renderContent(m.content)}</div>
                      {m.action?.type === "nav" && (
                        <div className="mono" style={{ marginTop: 6, fontSize: 10.5, color: "var(--accent)" }}>
                          → navigation: {m.action.page}
                        </div>
                      )}
                    </div>
                  </div>
                ))}
                {thinking && (
                  <div style={{ display: "flex", gap: 8 }}>
                    <JarvisLogo size={20} glow={false} pulse/>
                    <div className="row" style={{ gap: 3, paddingTop: 6 }}>
                      {[0,1,2].map(i => <span key={i} style={{ width: 5, height: 5, borderRadius: 999, background: "var(--accent)", animation: `jv-bounce 1.2s ${i*0.18}s infinite ease-in-out` }}/>)}
                    </div>
                  </div>
                )}
                {messages.length <= 1 && (
                  <div style={{ marginTop: 8 }}>
                    <div style={{ fontSize: 10, color: "var(--text-faint)", textTransform: "uppercase", letterSpacing: ".08em", marginBottom: 8 }}>Actions rapides</div>
                    <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 6 }}>
                      {QUICK_ACTIONS.map((a, i) => (
                        <button key={i} onClick={() => { onNavigate(a.navigate); setOpen(false); }} style={{
                          display: "flex", alignItems: "center", gap: 8,
                          padding: "8px 10px", background: "var(--bg-2)",
                          border: "1px solid var(--border-subtle)", borderRadius: 6,
                          fontSize: 11.5, color: "var(--text)", cursor: "pointer", textAlign: "left",
                        }}>
                          <Icon name={a.icon} size={12} style={{ color: "var(--accent)" }}/>
                          {a.label}
                        </button>
                      ))}
                    </div>
                  </div>
                )}
              </div>

              {/* Input */}
              <div style={{ padding: 12, borderTop: "1px solid var(--border-subtle)" }}>
                <div style={{
                  display: "flex", alignItems: "flex-end", gap: 6,
                  background: "var(--bg-2)", border: "1px solid var(--border)",
                  borderRadius: 10, padding: "6px 6px 6px 10px",
                }}>
                  <textarea
                    value={input}
                    onChange={(e) => setInput(e.target.value)}
                    onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); ask(); } }}
                    placeholder="Demandez ou ordonnez…"
                    rows={1}
                    style={{ flex: 1, resize: "none", background: "transparent", border: "none", outline: "none", color: "var(--text)", fontSize: 12.5, lineHeight: 1.4, fontFamily: "inherit", maxHeight: 80, padding: "4px 0" }}
                  />
                  <button className="btn" data-variant="primary" data-size="sm" disabled={!input.trim() || thinking} onClick={() => ask()} style={{ height: 26, padding: "0 8px" }}>
                    <Icon name="zap" size={11}/>
                  </button>
                </div>
              </div>
            </>
          ) : (
            /* Activity feed */
            <div style={{ flex: 1, overflow: "auto", padding: "8px 0" }}>
              <div style={{ padding: "8px 14px 4px", fontSize: 10, color: "var(--text-faint)", textTransform: "uppercase", letterSpacing: ".08em" }}>
                Opérations temps réel · 8 dernières
              </div>
              {ACTIVITY_LINES.map((a, i) => (
                <div key={i} style={{ display: "flex", gap: 10, padding: "9px 14px", borderTop: i ? "1px solid var(--border-subtle)" : "none" }}>
                  <div style={{
                    width: 22, height: 22, borderRadius: 5, flexShrink: 0,
                    background: `var(--${a.tone === "muted" ? "bg-3" : a.tone}-soft)`,
                    color: a.tone === "muted" ? "var(--text-muted)" : `var(--${a.tone})`,
                    display: "grid", placeItems: "center", marginTop: 1,
                  }}>
                    <Icon name={a.ic} size={11}/>
                  </div>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 11.5, lineHeight: 1.4 }}>{a.text}</div>
                    <div className="mono" style={{ fontSize: 10, color: "var(--text-faint)", marginTop: 2 }}>{a.t}</div>
                  </div>
                </div>
              ))}
              <div style={{ padding: 14, borderTop: "1px solid var(--border-subtle)" }}>
                <button className="btn" data-variant="ghost" data-size="sm" onClick={() => onNavigate("jarvis")} style={{ width: "100%", justifyContent: "center" }}>
                  Console pleine · historique 30j
                </button>
              </div>
            </div>
          )}
        </div>
      )}

      <style>{`
        @keyframes jv-slide-in { from { transform: translateX(20px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
        @keyframes jv-ring { 0% { transform: scale(1); opacity: 0.8; } 100% { transform: scale(1.4); opacity: 0; } }
      `}</style>
    </>
  );
};

window.JarvisOverlay = JarvisOverlay;
