// Recursive MLS — Screen 8: Inbox (unified activity + messaging).
// Horizontal top tabs (Showings / Offers / Alerts / Clients / Agents) — no second
// left rail. Below: list + detail. Activity items route to their screen; Clients &
// Agents tabs open full chat threads.
function Inbox({ go }) {
  const I = window.RC_INBOX;
  const [view, setView] = useState("all");        // all | showings | offers | alerts | clients | agents
  const [convId, setConvId] = useState(null);     // open chat thread
  const [composing, setComposing] = useState(false);
  const [agentInfo, setAgentInfo] = useState(null);

  const aUnread = (kinds) => I.activity.filter((a) => a.unread && kinds.includes(a.kind)).length;
  const tUnread = (party) => I.threadOrder.filter((id) => I.conversations[id].party === party).reduce((s, id) => s + I.unread[id], 0);
  const totalUnread = aUnread(["showing", "feedback", "offer", "alert"]) + tUnread("client") + tUnread("agent");

  const TABS = [
    { id: "all", icon: "layout-list", label: "All" },
    { id: "showings", icon: "calendar-clock", label: "Showings", count: aUnread(["showing", "feedback"]) },
    { id: "offers", icon: "file-signature", label: "Offers", count: aUnread(["offer"]) },
    { id: "alerts", icon: "bell", label: "Alerts", count: aUnread(["alert"]) },
    { id: "clients", icon: "users", label: "Clients", count: tUnread("client") },
    { id: "agents", icon: "briefcase", label: "Agents", count: tUnread("agent") },
  ];

  const isMessages = view === "clients" || view === "agents";
  const party = view === "clients" ? "client" : "agent";
  const feedKinds = { showings: ["showing", "feedback"], offers: ["offer"], alerts: ["alert"] }[view];
  const feed = view === "all" ? I.activity : (feedKinds ? I.activity.filter((a) => feedKinds.includes(a.kind)) : I.activity);
  const switchView = (id) => { setView(id); setConvId(null); setComposing(false); setAgentInfo(null); };

  return (
    <div style={{ display: "flex", flexDirection: "column", height: "100%" }}>
      <div style={{ flex: "none", padding: "18px 24px 0", display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 14, flexWrap: "wrap" }}>
        <div>
          <h1 style={{ margin: 0, fontSize: 23, fontWeight: 600, letterSpacing: "-0.5px", color: "#1d241f" }}>Inbox</h1>
          <p style={{ margin: "4px 0 0", fontSize: 13.5, color: "#8a8e88" }}>{totalUnread} unread · everything in one place — requests, offers, feedback & messages</p>
        </div>
        <button onClick={() => { setView("clients"); setComposing(true); setConvId(null); }} style={btnPrimary}><Icon name="pen-square" size={15} color="#fff" /> New Message</button>
      </div>

      {/* HORIZONTAL TABS + presence */}
      <div style={{ flex: "none", padding: "14px 24px 0", display: "flex", alignItems: "center", gap: 12, borderBottom: "1px solid #ece9e0" }}>
        <div style={{ display: "flex", gap: 4, flex: 1, minWidth: 0, overflowX: "auto" }}>
        {TABS.map((t) => {
          const on = view === t.id;
          return (
            <button key={t.id} onClick={() => switchView(t.id)} style={{ display: "inline-flex", alignItems: "center", gap: 8, fontFamily: "inherit", cursor: "pointer", border: 0, background: "transparent", flex: "none",
              padding: "9px 14px", fontSize: 13.5, fontWeight: 600, color: on ? "#006747" : "#8a8e88", borderBottom: on ? "2px solid #006747" : "2px solid transparent", marginBottom: -1 }}>
              <Icon name={t.icon} size={16} color={on ? "#006747" : "#a8aca6"} />
              {t.label}
              {t.count > 0 && <span style={{ fontSize: 11, fontWeight: 700, color: "#fff", background: on ? "#006747" : "#b8bdb6", borderRadius: 999, padding: "1px 7px", minWidth: 8, textAlign: "center" }}>{t.count}</span>}
            </button>
          );
        })}
        </div>
        <PresenceBar I={I} onOpenAgent={(id) => { setView("agents"); setConvId(id); setComposing(false); setAgentInfo(null); }} onDirectory={() => { setView("agents"); setComposing(true); setConvId(null); }} />
      </div>

      <div style={{ flex: 1, display: "grid", gridTemplateColumns: "minmax(320px, 0.85fr) 1.5fr", minHeight: 0, padding: "16px 24px 0" }}>
        {/* LIST */}
        <div style={{ display: "flex", flexDirection: "column", minHeight: 0, background: "#fff", boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", borderRadius: "3px 0 0 3px" }}>
          {isMessages
            ? <ThreadList I={I} party={party} convId={convId} onOpen={(id) => { setConvId(id); setComposing(false); setAgentInfo(null); }} />
            : <FeedList feed={feed} I={I} onOpen={(a) => { if (a.kind === "message" && a.convId) { const c = I.conversations[a.convId]; setView(c && c.party === "agent" ? "agents" : "clients"); setConvId(a.convId); } else if (a.route) { go && go(a.route); } }} />}
        </div>

        {/* DETAIL */}
        <div style={{ display: "flex", flexDirection: "column", minHeight: 0, background: "#fbfaf7", boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", borderRadius: "0 3px 3px 0" }}>
          {composing ? <ComposeMessage I={I} onClose={() => setComposing(false)} onPick={(id) => { const c = I.conversations[id]; setView(c && c.party === "agent" ? "agents" : "clients"); setConvId(id); setComposing(false); }} />
            : agentInfo ? <AgentInfo agent={agentInfo} I={I} onBack={() => setAgentInfo(null)} />
            : isMessages && convId ? <ChatThread key={convId} conv={I.conversations[convId]} I={I} go={go} onAgentInfo={(ag) => setAgentInfo(ag)} />
            : isMessages ? <Empty icon="message-circle" title={party === "client" ? "Client messages" : "Agent messages"} body={party === "client" ? "Talk with your clients about homes you sent, showings they completed, and offers. Pick a conversation or start a new one." : "Message any agent in the MLS — Slack-style. Pick a conversation or start a new one."} />
            : <ActivityPreview feed={feed} I={I} go={go} view={view} />}
        </div>
      </div>
    </div>
  );
}

// ---- presence (scales to a 100k-agent MLS: scoped, not a flat roster) ----
function PresenceBar({ I, onOpenAgent, onDirectory }) {
  const [open, setOpen] = useState(false);
  // conversations I have with agents, so the avatar stack opens a real chat
  const convByAgent = {};
  Object.values(I.conversations).forEach((c) => { if (c.agentId) convByAgent[c.agentId] = c.id; });
  const contacts = I.presence.recentContactIds.map((id) => I.agents.find((a) => a.id === id)).filter(Boolean);
  const onlineContacts = contacts.filter((a) => a.online);
  const fmt = (n) => n.toLocaleString("en-US");
  return (
    <div style={{ position: "relative", flex: "none" }}>
      <button onClick={() => setOpen(!open)} style={{ display: "inline-flex", alignItems: "center", gap: 9, fontFamily: "inherit", cursor: "pointer", border: "1px solid #e2e0d8", background: "#fff", borderRadius: 999, padding: "5px 12px 5px 7px", marginBottom: 6 }}>
        {/* stacked avatars of MY online contacts */}
        <span style={{ display: "inline-flex" }}>
          {onlineContacts.slice(0, 3).map((a, i) => (
            <span key={a.id} style={{ width: 24, height: 24, borderRadius: "50%", background: "#e7e1d4", color: "#006747", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 9.5, fontWeight: 700, border: "2px solid #fff", marginLeft: i ? -8 : 0 }}>{a.initials}</span>
          ))}
        </span>
        <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12.5, fontWeight: 600, color: "#1d241f" }}>
          <span style={{ width: 8, height: 8, borderRadius: "50%", background: "#1f8a5b" }} />
          {fmt(I.presence.mlsOnline)} online
        </span>
        <Icon name="chevron-down" size={14} color="#a8aca6" />
      </button>

      {open && (
        <React.Fragment>
          <div onClick={() => setOpen(false)} style={{ position: "fixed", inset: 0, zIndex: 30 }} />
          <div style={{ position: "absolute", top: "calc(100% + 4px)", right: 0, width: 290, background: "#fff", borderRadius: 10, boxShadow: "0 10px 32px rgba(0,0,0,.18), inset 0 0 0 1px rgba(0,0,0,.06)", padding: 8, zIndex: 31 }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", padding: "6px 8px 8px" }}>
              <span style={{ fontSize: 13, fontWeight: 600, color: "#1d241f" }}>Your contacts</span>
              <span style={{ fontSize: 11, fontWeight: 600, color: "#1f8a5b", background: "#e8f4ee", borderRadius: 999, padding: "2px 8px" }}>{onlineContacts.length} online</span>
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 2, maxHeight: 220, overflowY: "auto" }}>
              {contacts.map((a) => {
                const cid = convByAgent[a.id];
                return (
                  <button key={a.id} onClick={() => { if (cid) onOpenAgent(cid); setOpen(false); }} className="rc-nav-item" style={{ display: "flex", alignItems: "center", gap: 10, fontFamily: "inherit", cursor: cid ? "pointer" : "default", border: 0, background: "transparent", borderRadius: 7, padding: "7px 8px", textAlign: "left", width: "100%" }}>
                    <span style={{ position: "relative", flex: "none" }}>
                      <span style={{ width: 30, height: 30, borderRadius: "50%", background: "#e7e1d4", color: "#006747", display: "flex", alignItems: "center", justifyContent: "center", fontSize: 11, fontWeight: 700 }}>{a.initials}</span>
                      <span style={{ position: "absolute", bottom: -1, right: -1, width: 9, height: 9, borderRadius: "50%", background: a.online ? "#1f8a5b" : "#c4c7c1", border: "2px solid #fff" }} />
                    </span>
                    <span style={{ flex: 1, minWidth: 0 }}>
                      <span style={{ display: "block", fontSize: 13, fontWeight: 600, color: "#1d241f", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{a.name}</span>
                      <span style={{ display: "block", fontSize: 11, color: a.online ? "#1f8a5b" : "#a8aca6" }}>{a.online ? "Active now" : "Offline"} · {a.brokerage}</span>
                    </span>
                  </button>
                );
              })}
            </div>
            <div style={{ borderTop: "1px solid #f1f0ea", margin: "8px 0 0", paddingTop: 8 }}>
              <div style={{ fontSize: 11.5, color: "#8a8e88", padding: "0 8px 8px", lineHeight: 1.45 }}>
                <b style={{ fontFamily: "'Space Mono', monospace", color: "#1d241f" }}>{I.presence.mlsOnline.toLocaleString("en-US")}</b> of {I.presence.mlsTotal.toLocaleString("en-US")} agents online across the MLS
              </div>
              <button onClick={() => { onDirectory(); setOpen(false); }} className="rc-nav-item" style={{ display: "flex", alignItems: "center", gap: 8, width: "100%", fontFamily: "inherit", cursor: "pointer", border: 0, background: "transparent", borderRadius: 7, padding: "8px", fontSize: 13, fontWeight: 600, color: "#006747" }}>
                <Icon name="search" size={15} color="#006747" /> Search the agent directory
              </button>
            </div>
          </div>
        </React.Fragment>
      )}
    </div>
  );
}

// ---- unified activity list ----
function FeedList({ feed, I, onOpen }) {
  return (
    <div style={{ flex: 1, overflowY: "auto" }}>
      {feed.map((a) => {
        const m = I.kindMeta[a.kind];
        return (
          <div key={a.id} onClick={() => onOpen(a)} className="rc-row" style={{ display: "flex", gap: 11, padding: "13px 15px", cursor: "pointer", borderBottom: "1px solid #f6f5f0", background: a.unread ? "#fbfcfb" : "transparent" }}>
            <span style={{ width: 34, height: 34, borderRadius: 8, background: m.b, display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}><Icon name={m.icon} size={17} color={m.c} /></span>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
                {a.unread && <span style={{ width: 7, height: 7, borderRadius: "50%", background: "#006747", flex: "none" }} />}
                <span style={{ fontSize: 13.5, fontWeight: a.unread ? 600 : 500, color: "#1d241f", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{a.title}</span>
              </div>
              <div style={{ fontSize: 12, color: "#8a8e88", marginTop: 3, lineHeight: 1.45, display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden" }}>{a.summary}</div>
              <div style={{ display: "flex", alignItems: "center", gap: 7, marginTop: 7 }}>
                <span style={{ fontSize: 10.5, fontWeight: 600, color: m.c, background: m.b, borderRadius: 999, padding: "2px 8px" }}>{m.label}</span>
                {a.meta && a.meta.tag && <span style={{ fontSize: 10.5, fontWeight: 600, color: "#6b706a", background: "#f1f0ea", borderRadius: 999, padding: "2px 8px" }}>{a.meta.tag}</span>}
              </div>
            </div>
            {a.photo && <div style={{ width: 46, height: 46, borderRadius: 6, backgroundImage: `url(${I.img(a.photo)})`, backgroundSize: "cover", backgroundPosition: "center", flex: "none" }} />}
            <span style={{ fontSize: 11, color: "#bcbfba", flex: "none" }}>{a.time}</span>
          </div>
        );
      })}
    </div>
  );
}

// ---- right pane when on a feed (not a chat) ----
function ActivityPreview({ feed, I, go, view }) {
  const counts = ["showing", "offer", "feedback", "alert", "message"].map((k) => ({ k, m: I.kindMeta[k], n: I.activity.filter((a) => a.kind === k).length }));
  const heads = { all: ["Today at a glance", "Everything routed to one place. Click any item to jump to it."], showings: ["Showings", "Requests on your listings and feedback from tours."], offers: ["Offers", "Incoming offers and counters across your deals."], alerts: ["Alerts", "Price drops and saved-search matches for your clients."] };
  const [title, sub] = heads[view] || heads.all;
  const attention = (view === "all" ? I.activity : feed).filter((a) => a.unread);
  return (
    <div style={{ flex: 1, overflowY: "auto", padding: 22 }}>
      <h3 style={{ margin: "0 0 4px", fontSize: 16, fontWeight: 600, color: "#1d241f" }}>{title}</h3>
      <p style={{ margin: "0 0 18px", fontSize: 13, color: "#8a8e88" }}>{sub}</p>
      {view === "all" && <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 22 }}>
        {counts.map(({ k, m, n }) => (
          <div key={k} style={{ background: "#fff", borderRadius: 8, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", padding: "14px 15px", display: "flex", alignItems: "center", gap: 12 }}>
            <span style={{ width: 38, height: 38, borderRadius: 9, background: m.b, display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}><Icon name={m.icon} size={19} color={m.c} /></span>
            <div>
              <div style={{ fontFamily: "'Space Mono', monospace", fontSize: 20, fontWeight: 700, color: "#1d241f", lineHeight: 1 }}>{n}</div>
              <div style={{ fontSize: 12, color: "#8a8e88", marginTop: 3 }}>{m.label}{n !== 1 ? "s" : ""}</div>
            </div>
          </div>
        ))}
      </div>}
      <div style={{ background: "#fff", borderRadius: 8, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", padding: 16 }}>
        <div style={{ fontSize: 12.5, fontWeight: 600, color: "#1d241f", marginBottom: 12 }}>Needs your attention</div>
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {attention.length ? attention.map((a) => {
            const m = I.kindMeta[a.kind];
            return (
              <div key={a.id} onClick={() => a.route && go && go(a.route)} className="rc-row" style={{ display: "flex", alignItems: "center", gap: 10, cursor: a.route ? "pointer" : "default", padding: "4px 2px", borderRadius: 6 }}>
                <span style={{ width: 26, height: 26, borderRadius: 7, background: m.b, display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}><Icon name={m.icon} size={14} color={m.c} /></span>
                <span style={{ flex: 1, fontSize: 12.5, color: "#4a504a", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{a.title}</span>
                {a.route && <Icon name="chevron-right" size={15} color="#c4c7c1" />}
              </div>
            );
          }) : <div style={{ fontSize: 12.5, color: "#a8aca6" }}>All caught up.</div>}
        </div>
      </div>
    </div>
  );
}

// ---- agent info panel ----
function AgentInfo({ agent, I, onBack }) {
  const stat = (label, val) => (
    <div style={{ background: "#fff", borderRadius: 8, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", padding: "12px 14px" }}>
      <div style={{ fontSize: 10.5, color: "#8a8e88", textTransform: "uppercase", letterSpacing: ".6px" }}>{label}</div>
      <div style={{ fontFamily: "'Space Mono', monospace", fontSize: 18, fontWeight: 700, color: "#1d241f", marginTop: 3 }}>{val}</div>
    </div>
  );
  const line = (icon, val) => (
    <div style={{ display: "flex", alignItems: "center", gap: 10, padding: "10px 0", borderBottom: "1px solid #f4f3ee" }}>
      <Icon name={icon} size={15} color="#8a8e88" /><span style={{ fontSize: 13, color: "#1d241f" }}>{val}</span>
    </div>
  );
  return (
    <React.Fragment>
      <div style={{ flex: "none", padding: "14px 18px", borderBottom: "1px solid #f1f0ea", background: "#fff", borderRadius: "0 3px 0 0", display: "flex", alignItems: "center", gap: 10 }}>
        <button onClick={onBack} style={{ border: 0, background: "none", cursor: "pointer", padding: 4, display: "flex" }}><Icon name="arrow-left" size={18} color="#4a504a" /></button>
        <h2 style={{ margin: 0, fontSize: 16, fontWeight: 600, color: "#1d241f" }}>Agent info</h2>
      </div>
      <div style={{ flex: 1, overflowY: "auto", padding: 22 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 14, marginBottom: 18 }}>
          <span style={{ position: "relative", flex: "none" }}>
            <span style={{ width: 56, height: 56, borderRadius: "50%", background: "#e7e1d4", color: "#006747", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 600, fontSize: 19 }}>{agent.initials}</span>
            {agent.online && <span style={{ position: "absolute", bottom: 1, right: 1, width: 12, height: 12, borderRadius: "50%", background: "#1f8a5b", border: "2.5px solid #fbfaf7" }} />}
          </span>
          <div>
            <div style={{ fontSize: 18, fontWeight: 600, color: "#1d241f" }}>{agent.name}</div>
            <div style={{ fontSize: 13, color: "#8a8e88" }}>{agent.brokerage}{agent.online ? " · online" : ""}</div>
          </div>
        </div>
        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 18 }}>
          {stat("Active listings", agent.listings)}
          {stat("Deals together", agent.dealsTogether)}
        </div>
        <div style={{ background: "#fff", borderRadius: 8, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.07)", padding: "4px 14px 8px", marginBottom: 18 }}>
          {line("phone", agent.phone)}
          {line("mail", agent.email)}
          {line("badge-check", "License " + agent.license)}
        </div>
        <div style={{ display: "flex", gap: 9 }}>
          <button onClick={onBack} style={{ ...btnPrimary, flex: 1, justifyContent: "center" }}><Icon name="message-circle" size={15} color="#fff" /> Back to chat</button>
          <button style={{ ...btnOutline, flex: 1, justifyContent: "center" }}><Icon name="building-2" size={15} color="#006747" /> View their listings</button>
        </div>
      </div>
    </React.Fragment>
  );
}

// ---- conversation list ----
function ThreadList({ I, party, convId, onOpen }) {
  const ids = I.threadOrder.filter((id) => I.conversations[id].party === party);
  return (
    <React.Fragment>
      <div style={{ flex: 1, overflowY: "auto" }}>
        {ids.map((id) => {
          const c = I.conversations[id]; const on = id === convId; const un = I.unread[id];
          return (
            <div key={id} onClick={() => onOpen(id)} className="rc-row" style={{ display: "flex", gap: 11, padding: "12px 14px", cursor: "pointer", borderBottom: "1px solid #f6f5f0", background: on ? "#f3f6f4" : "transparent", borderLeft: on ? "2.5px solid #006747" : "2.5px solid transparent" }}>
              <span style={{ position: "relative", flex: "none" }}>
                <span style={{ width: 38, height: 38, borderRadius: "50%", background: c.party === "client" ? "#006747" : "#e7e1d4", color: c.party === "client" ? "#fff" : "#006747", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 600, fontSize: 13 }}>{c.initials}</span>
                {c.online && <span style={{ position: "absolute", bottom: 0, right: 0, width: 10, height: 10, borderRadius: "50%", background: "#1f8a5b", border: "2px solid #fff" }} />}
              </span>
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 }}>
                  <span style={{ fontSize: 13.5, fontWeight: un ? 700 : 600, color: "#1d241f", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{c.name}</span>
                  <span style={{ fontSize: 11, color: "#bcbfba", flex: "none" }}>{I.lastTime[id]}</span>
                </div>
                <div style={{ display: "flex", alignItems: "center", gap: 6, marginTop: 2 }}>
                  <span style={{ fontSize: 10, fontWeight: 600, color: c.party === "client" ? "#006747" : "#9a6a12", background: c.party === "client" ? "#eef4f1" : "#fbf2dc", borderRadius: 4, padding: "0 6px", flex: "none" }}>{c.party === "client" ? "Client" : "Agent"}</span>
                  <span style={{ fontSize: 12, color: un ? "#4a504a" : "#a8aca6", fontWeight: un ? 600 : 400, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{I.lastPreview[id]}</span>
                </div>
              </div>
              {un > 0 && <span style={{ alignSelf: "center", fontSize: 11, fontWeight: 700, color: "#fff", background: "#006747", borderRadius: 999, padding: "1px 7px", flex: "none" }}>{un}</span>}
            </div>
          );
        })}
      </div>
    </React.Fragment>
  );
}

// ---- chat thread ----
function ChatThread({ conv, I, go, onAgentInfo }) {
  const [msgs, setMsgs] = useState(conv.messages);
  const [draft, setDraft] = useState(conv.blockedDraft ? conv.blockedDraft.text : "");
  const agent = conv.agentId && I.agents.find((a) => a.id === conv.agentId);
  // platform content moderation: super-user-defined policies screen outbound messages
  const screen = (text) => {
    if (conv.blockedDraft && text.trim() === conv.blockedDraft.text.trim()) return conv.blockedDraft.moderation;
    return null;
  };
  const [mod, setMod] = useState(() => (conv.blockedDraft ? conv.blockedDraft.moderation : null));
  const scrollRef = React.useRef(null);
  React.useEffect(() => { if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight; }, [msgs]);
  const send = (text) => {
    const t = (text || draft).trim(); if (!t) return;
    const flagged = screen(t);
    if (flagged) { setMod(flagged); return; }   // blocked by moderation — not sent
    setMsgs([...msgs, { from: "me", text: t, time: "Just now" }]);
    setDraft(""); setMod(null);
  };
  const onDraft = (v) => { setDraft(v); setMod(screen(v)); };
  return (
    <React.Fragment>
      {/* chat header */}
      <div style={{ flex: "none", display: "flex", alignItems: "center", gap: 12, padding: "13px 18px", background: "#fff", borderRadius: "0 3px 0 0", borderBottom: "1px solid #f1f0ea" }}>
        <span style={{ position: "relative", flex: "none" }}>
          <span style={{ width: 38, height: 38, borderRadius: "50%", background: conv.party === "client" ? "#006747" : "#e7e1d4", color: conv.party === "client" ? "#fff" : "#006747", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 600, fontSize: 14 }}>{conv.initials}</span>
          {conv.online && <span style={{ position: "absolute", bottom: 0, right: 0, width: 10, height: 10, borderRadius: "50%", background: "#1f8a5b", border: "2px solid #fff" }} />}
        </span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 14.5, fontWeight: 600, color: "#1d241f" }}>{conv.name}</div>
          <div style={{ fontSize: 11.5, color: "#8a8e88" }}>{conv.sub}{conv.online ? " · online" : ""}</div>
        </div>
        {conv.party === "client"
          ? <button onClick={() => go && go("clients")} style={{ ...btnOutline, padding: "7px 11px", fontSize: 12.5 }}><Icon name="user" size={14} color="#006747" /> View in CRM</button>
          : <button onClick={() => agent && onAgentInfo && onAgentInfo(agent)} style={{ ...btnOutline, padding: "7px 11px", fontSize: 12.5 }}><Icon name="id-card" size={14} color="#006747" /> View agent info</button>}
        <button style={{ ...btnOutline, padding: "7px 10px", fontSize: 12.5 }}><Icon name="phone" size={14} color="#006747" /></button>
      </div>

      {/* pinned listing this conversation is about */}
      {conv.pinnedListing && (
        <div onClick={() => conv.pinnedListing.route && go && go(conv.pinnedListing.route)} style={{ flex: "none", display: "flex", alignItems: "center", gap: 11, padding: "10px 18px", background: "#f4f6f4", borderBottom: "1px solid #e6ece8", cursor: conv.pinnedListing.route ? "pointer" : "default" }}>
          <div style={{ width: 40, height: 40, borderRadius: 6, backgroundImage: `url(${I.img(conv.pinnedListing.photo)})`, backgroundSize: "cover", backgroundPosition: "center", flex: "none" }} />
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 10, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".6px", color: "#006747" }}>{conv.pinnedListing.context}</div>
            <div style={{ fontSize: 13, fontWeight: 600, color: "#1d241f", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{conv.pinnedListing.addr}</div>
            <div style={{ fontSize: 11.5, color: "#8a8e88" }}>{conv.pinnedListing.info}</div>
          </div>
          <Icon name="chevron-right" size={16} color="#a8b5ad" />
        </div>
      )}

      {/* messages */}
      <div ref={scrollRef} style={{ flex: 1, overflowY: "auto", padding: "18px 18px 8px", display: "flex", flexDirection: "column", gap: 12 }}>
        {msgs.map((msg, i) => {
          const mine = msg.from === "me";
          return (
            <div key={i} style={{ display: "flex", flexDirection: "column", alignItems: mine ? "flex-end" : "flex-start" }}>
              {!mine && msg.who && <span style={{ fontSize: 10.5, color: "#a8aca6", margin: "0 0 3px 12px" }}>{msg.who}</span>}
              <div style={{ maxWidth: "76%", display: "flex", flexDirection: "column", gap: 6 }}>
                {msg.card && <ChatCard card={msg.card} mine={mine} I={I} />}
                {msg.text && (
                  <div style={{ fontSize: 13.5, lineHeight: 1.5, padding: "9px 13px", borderRadius: mine ? "13px 13px 3px 13px" : "13px 13px 13px 3px",
                    background: mine ? "#006747" : "#fff", color: mine ? "#fff" : "#1d241f", boxShadow: mine ? "none" : "inset 0 0 0 1px rgba(0,0,0,.07)" }}>{msg.text}</div>
                )}
              </div>
              <span style={{ fontSize: 10.5, color: "#bcbfba", margin: mine ? "4px 6px 0 0" : "4px 0 0 12px" }}>{msg.time}</span>
            </div>
          );
        })}
      </div>

      {/* suggestions + composer */}
      <div style={{ flex: "none", padding: "10px 16px 16px", background: "#fbfaf7" }}>
        {mod ? <ModerationPanel mod={mod} onClear={() => { setDraft(""); setMod(null); }} />
          : conv.suggestions && (
          <div style={{ display: "flex", gap: 7, flexWrap: "wrap", marginBottom: 10 }}>
            {conv.suggestions.map((s) => (
              <button key={s} onClick={() => send(s)} style={{ display: "inline-flex", alignItems: "center", gap: 5, fontFamily: "inherit", fontSize: 12, fontWeight: 500, color: "#006747", background: "#fff", border: "1px solid #d7e6dd", borderRadius: 999, padding: "6px 11px", cursor: "pointer" }}>
                <Icon name="sparkles" size={12} color="#006747" /> {s}
              </button>
            ))}
          </div>
        )}
        <div style={{ display: "flex", alignItems: "flex-end", gap: 8, background: "#fff", borderRadius: 12, padding: "8px 8px 8px 14px", boxShadow: mod ? "inset 0 0 0 1.5px #e6b0aa" : "inset 0 0 0 1px rgba(0,0,0,.1)" }}>
          <button title="Attach a listing" style={{ background: "none", border: 0, cursor: "pointer", padding: "4px", flex: "none" }}><Icon name="home" size={18} color="#8a8e88" /></button>
          <button title="Attach file" style={{ background: "none", border: 0, cursor: "pointer", padding: "4px", flex: "none" }}><Icon name="paperclip" size={18} color="#8a8e88" /></button>
          <textarea value={draft} onChange={(e) => onDraft(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter" && !e.shiftKey) { e.preventDefault(); send(); } }} rows={mod ? 2 : 1} placeholder={`Message ${conv.name.split(" ")[0]}…`}
            style={{ flex: 1, border: 0, outline: 0, background: "transparent", resize: "none", fontFamily: "inherit", fontSize: 13.5, color: mod ? "#9a2820" : "#1d241f", lineHeight: 1.5, maxHeight: 90, padding: "5px 0" }} />
          <button onClick={() => send()} disabled={!draft.trim() || !!mod} title={mod ? "Blocked by moderation" : "Send"} style={{ width: 34, height: 34, borderRadius: 9, border: 0, background: mod ? "#e6b0aa" : (draft.trim() ? "#006747" : "#d2d0c7"), color: "#fff", cursor: (draft.trim() && !mod) ? "pointer" : "not-allowed", display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}><Icon name={mod ? "shield-alert" : "arrow-up"} size={17} color="#fff" /></button>
        </div>
        {mod && <div style={{ fontSize: 10.5, color: "#a8aca6", marginTop: 7, display: "flex", alignItems: "center", gap: 5 }}><Icon name="shield" size={11} color="#a8aca6" /> Outbound messages are screened by Recursive MLS policy. Ref {mod.ref}.</div>}
      </div>
    </React.Fragment>
  );
}

// ---- moderation panel (super-user-defined policies block the send) ----
function ModerationPanel({ mod, onClear }) {
  return (
    <div style={{ borderRadius: 10, background: "#fdf3f1", boxShadow: "inset 0 0 0 1px #f0d6d3", padding: "13px 15px", marginBottom: 10 }}>
      <div style={{ display: "flex", alignItems: "flex-start", gap: 11 }}>
        <span style={{ width: 30, height: 30, borderRadius: 8, background: "#fbe3df", display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}><Icon name="shield-alert" size={17} color="#b3261e" /></span>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 8, flexWrap: "wrap" }}>
            <span style={{ fontSize: 13.5, fontWeight: 700, color: "#9a2820" }}>Message blocked</span>
            <span style={{ fontSize: 10.5, fontWeight: 700, color: "#b3261e", background: "#fbe3df", borderRadius: 999, padding: "2px 8px", textTransform: "uppercase", letterSpacing: ".4px" }}>{mod.policy}</span>
          </div>
          <div style={{ fontSize: 12.5, color: "#7a3a34", lineHeight: 1.5, marginTop: 5 }}>{mod.reason}</div>

          {mod.flagged && mod.flagged.length > 0 && (
            <div style={{ display: "flex", flexWrap: "wrap", gap: 6, marginTop: 9 }}>
              {mod.flagged.map((f) => <span key={f} style={{ fontSize: 11, color: "#9a2820", background: "#fbe3df", borderRadius: 4, padding: "2px 7px" }}>“{f}”</span>)}
            </div>
          )}

          {/* policy checklist the platform screens for */}
          <div style={{ marginTop: 11, paddingTop: 10, borderTop: "1px solid #f0d6d3" }}>
            <div style={{ fontSize: 10, fontWeight: 700, textTransform: "uppercase", letterSpacing: ".6px", color: "#b08a86", marginBottom: 7 }}>Screened against MLS policy</div>
            <div style={{ display: "flex", flexDirection: "column", gap: 5 }}>
              {mod.policies.map((p) => (
                <div key={p.id} style={{ display: "flex", alignItems: "center", gap: 8, fontSize: 12 }}>
                  <Icon name={p.matched ? "x-circle" : "check-circle-2"} size={14} color={p.matched ? "#b3261e" : "#1f8a5b"} />
                  <span style={{ color: p.matched ? "#9a2820" : "#6b706a", fontWeight: p.matched ? 600 : 400 }}>{p.label}</span>
                  {p.matched && <span style={{ marginLeft: "auto", fontSize: 10, fontWeight: 700, color: "#b3261e" }}>VIOLATION</span>}
                </div>
              ))}
            </div>
          </div>

          <div style={{ display: "flex", alignItems: "center", gap: 9, marginTop: 12 }}>
            <button onClick={onClear} style={{ ...btnOutline, padding: "6px 12px", fontSize: 12.5 }}><Icon name="trash-2" size={13} color="#006747" /> Discard draft</button>
            <button style={{ display: "inline-flex", alignItems: "center", gap: 6, fontFamily: "inherit", fontSize: 12.5, fontWeight: 600, color: "#6b706a", background: "none", border: 0, cursor: "pointer" }}><Icon name="flag" size={13} color="#8a8e88" /> Request review</button>
            <span style={{ marginLeft: "auto", fontSize: 11, color: "#b08a86", fontFamily: "'Space Mono', monospace" }}>{mod.ref}</span>
          </div>
        </div>
      </div>
    </div>
  );
}

// ---- in-chat attachment card (listing / tour) ----
function ChatCard({ card, mine, I }) {
  if (card.type === "listing") {
    return (
      <div style={{ display: "flex", gap: 10, padding: 9, borderRadius: 10, background: mine ? "rgba(255,255,255,.12)" : "#fff", boxShadow: mine ? "none" : "inset 0 0 0 1px rgba(0,0,0,.08)" }}>
        <div style={{ width: 52, height: 52, borderRadius: 6, backgroundImage: `url(${I.img(card.photo)})`, backgroundSize: "cover", backgroundPosition: "center", flex: "none" }} />
        <div style={{ minWidth: 0, display: "flex", flexDirection: "column", justifyContent: "center" }}>
          <div style={{ fontSize: 12.5, fontWeight: 600, color: mine ? "#fff" : "#1d241f", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{card.addr}</div>
          <div style={{ fontSize: 11.5, color: mine ? "rgba(255,255,255,.8)" : "#8a8e88", marginTop: 2 }}>{card.info}</div>
        </div>
      </div>
    );
  }
  return (
    <div style={{ display: "flex", gap: 10, alignItems: "center", padding: "10px 12px", borderRadius: 10, background: mine ? "rgba(255,255,255,.12)" : "#fff", boxShadow: mine ? "none" : "inset 0 0 0 1px rgba(0,0,0,.08)" }}>
      <span style={{ width: 36, height: 36, borderRadius: 8, background: mine ? "rgba(255,255,255,.18)" : "#eef4f1", display: "flex", alignItems: "center", justifyContent: "center", flex: "none" }}><Icon name="route" size={18} color={mine ? "#fff" : "#006747"} /></span>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 12.5, fontWeight: 600, color: mine ? "#fff" : "#1d241f" }}>{card.info}</div>
        <div style={{ fontSize: 11.5, color: mine ? "rgba(255,255,255,.8)" : "#8a8e88", marginTop: 2 }}>{card.sub}</div>
      </div>
    </div>
  );
}

// ---- new message composer ----
function ComposeMessage({ I, onClose, onPick }) {
  const [q, setQ] = useState("");
  const clients = I.threadOrder.map((id) => I.conversations[id]).filter((c) => c.party === "client");
  const agentConvs = I.threadOrder.map((id) => I.conversations[id]).filter((c) => c.party === "agent");
  const dirAgents = I.agents.filter((a) => !agentConvs.find((c) => c.agentId === a.id));
  const match = (name) => name.toLowerCase().includes(q.toLowerCase());
  const Row = ({ initials, name, sub, online, party, onClick }) => (
    <div onClick={onClick} className="rc-row" style={{ display: "flex", alignItems: "center", gap: 11, padding: "10px 12px", borderRadius: 8, cursor: "pointer" }}>
      <span style={{ position: "relative", flex: "none" }}>
        <span style={{ width: 34, height: 34, borderRadius: "50%", background: party === "client" ? "#006747" : "#e7e1d4", color: party === "client" ? "#fff" : "#006747", display: "flex", alignItems: "center", justifyContent: "center", fontWeight: 600, fontSize: 12 }}>{initials}</span>
        {online && <span style={{ position: "absolute", bottom: -1, right: -1, width: 9, height: 9, borderRadius: "50%", background: "#1f8a5b", border: "1.5px solid #fff" }} />}
      </span>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 13.5, fontWeight: 600, color: "#1d241f" }}>{name}</div>
        <div style={{ fontSize: 11.5, color: "#8a8e88" }}>{sub}</div>
      </div>
      <Icon name="message-circle" size={16} color="#c4c7c1" />
    </div>
  );
  return (
    <React.Fragment>
      <div style={{ flex: "none", padding: "16px 20px", borderBottom: "1px solid #f1f0ea", background: "#fff", borderRadius: "0 3px 0 0", display: "flex", alignItems: "center", justifyContent: "space-between" }}>
        <div>
          <h2 style={{ margin: 0, fontSize: 18, fontWeight: 600, color: "#1d241f" }}>New message</h2>
          <p style={{ margin: "3px 0 0", fontSize: 12.5, color: "#8a8e88" }}>Message any MLS agent or one of your clients</p>
        </div>
        <button onClick={onClose} style={{ border: "1px solid #e2e0d8", background: "#fff", borderRadius: 7, width: 34, height: 34, display: "flex", alignItems: "center", justifyContent: "center", cursor: "pointer" }}><Icon name="x" size={16} color="#4a504a" /></button>
      </div>
      <div style={{ flex: 1, overflowY: "auto", padding: 16 }}>
        <div style={{ display: "flex", alignItems: "center", gap: 8, background: "#fff", borderRadius: 8, padding: "9px 12px", boxShadow: "inset 0 0 0 1px rgba(0,0,0,.1)", marginBottom: 16 }}>
          <Icon name="search" size={15} color="#a8aca6" />
          <input autoFocus value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search agents & clients…" style={{ flex: 1, border: 0, outline: 0, background: "transparent", fontFamily: "inherit", fontSize: 13.5 }} />
        </div>
        <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".6px", color: "#a8aca6", margin: "4px 6px 6px" }}>Your clients</div>
        {clients.filter((c) => match(c.name)).map((c) => <Row key={c.id} initials={c.initials} name={c.name} sub={c.sub} online={c.online} party="client" onClick={() => onPick(c.id)} />)}
        <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: ".6px", color: "#a8aca6", margin: "14px 6px 6px" }}>MLS agents</div>
        {agentConvs.filter((c) => match(c.name)).map((c) => <Row key={c.id} initials={c.initials} name={c.name} sub={c.sub} online={c.online} party="agent" onClick={() => onPick(c.id)} />)}
        {dirAgents.filter((a) => match(a.name)).map((a) => <Row key={a.id} initials={a.initials} name={a.name} sub={a.brokerage} online={a.online} party="agent" onClick={onClose} />)}
      </div>
    </React.Fragment>
  );
}

function Empty({ icon, title, body }) {
  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", padding: "48px 30px", textAlign: "center" }}>
      <span style={{ width: 56, height: 56, borderRadius: "50%", background: "#eef4f1", display: "flex", alignItems: "center", justifyContent: "center", marginBottom: 16 }}><Icon name={icon} size={26} color="#006747" /></span>
      <div style={{ fontSize: 16, fontWeight: 600, color: "#1d241f", marginBottom: 6 }}>{title}</div>
      <div style={{ fontSize: 13.5, color: "#8a8e88", maxWidth: 340, lineHeight: 1.5 }}>{body}</div>
    </div>
  );
}

window.Inbox = Inbox;
