// screens-settings.jsx
const { useState } = React;
const SETTINGS_TABS = [
  { key: "whatsapp", label: "WhatsApp", icon: "phoneDevice" },
  { key: "automation", label: "Auto-reply", icon: "zap" },
  { key: "statuses", label: "Lead statuses", icon: "tag" },
  { key: "ai", label: "AI Providers", icon: "sparkles" },
  { key: "users", label: "Team", icon: "users" },
  { key: "brand", label: "Brand", icon: "tag" },
];

function Switch({ on, onChange, disabled }) {
  return (
    <button onClick={() => !disabled && onChange(!on)} aria-pressed={on} disabled={disabled}
      style={{ width: 46, height: 28, borderRadius: 999, background: on ? "var(--color-secondary)" : "var(--border-2)",
        position: "relative", flexShrink: 0, transition: "background var(--motion-fast)", opacity: disabled ? 0.45 : 1, cursor: disabled ? "not-allowed" : "pointer" }}>
      <span style={{ position: "absolute", top: 3, insetInlineStart: on ? 21 : 3, width: 22, height: 22, borderRadius: 999, background: "#fff",
        transition: "inset-inline-start var(--motion-fast)", boxShadow: "var(--shadow-xs)" }} />
    </button>
  );
}

/* small modal header */
function MHead({ title, sub, onClose }) {
  return (
    <div className="between" style={{ padding: "18px 22px", borderBottom: "1px solid var(--border-1)" }}>
      <div><div style={{ fontWeight: 800, fontSize: 16 }}>{title}</div>{sub && <div style={{ fontSize: 12, color: "var(--fg-4)" }}>{sub}</div>}</div>
      <button className="iconbtn" onClick={onClose}><Icon name="x" size={20} /></button>
    </div>
  );
}

const TRUST_NAMES = ["", "Observe", "Drafts only", "Send with approval", "Auto-send (low risk)", "Director"];
function AutomationSettings() {
  const data = useStore();
  const s = data.SETTINGS || {};
  const ar = s.autoReply || { enabled: true, businessHoursOnly: false, maxPerDay: 120 };
  const autoSendTrust = s.ai?.autoSendTrust ?? 4;
  const [maxPerDay, setMaxPerDay] = useState(ar.maxPerDay);
  const [saving, setSaving] = useState(false);
  React.useEffect(() => { setMaxPerDay(ar.maxPerDay); }, [ar.maxPerDay]);

  const patch = (next) => {
    setSaving(true);
    Actions.updateSettings(next).catch((e) => console.error("settings save failed", e)).finally(() => setSaving(false));
  };
  const setAR = (k, v) => patch({ autoReply: { ...ar, [k]: v } });
  const setThreshold = (v) => patch({ ai: { ...(s.ai || {}), autoSendTrust: v } });

  const agents = data.AGENTS || [];
  const autoCount = agents.filter((a) => a.trust >= autoSendTrust).length;
  const replyMode = s.defaultReplyMode || "manual";
  const REPLY_MODES = [
    { id: "manual", label: "Manual approval", icon: "shield", desc: "Every reply waits in your approval queue before it sends." },
    { id: "auto_safe", label: "Auto-safe", icon: "checkcircle", desc: "Low-risk replies send automatically; anything sensitive (anger, pricing, payment, legal) holds for you." },
    { id: "auto", label: "Full auto", icon: "zap", desc: "Replies send automatically. Hard-risk messages still hold for safety." },
  ];

  return (
    <div className="col" style={{ gap: 16 }}>
      <p className="muted" style={{ fontSize: 14, maxWidth: 520 }}>Decide when agents can send replies on their own. Auto-reply answers instantly; below the trust threshold, agents keep sending drafts to your queue.</p>
      <Card>
        <div style={{ fontWeight: 700, marginBottom: 4 }}>Reply mode</div>
        <div style={{ fontSize: 12.5, color: "var(--fg-4)", marginBottom: 14 }}>The default for new inbound messages. Per-agent trust and the safety guard below still apply.</div>
        <div className="col" style={{ gap: 8 }}>
          {REPLY_MODES.map((m) => (
            <button key={m.id} onClick={() => patch({ defaultReplyMode: m.id })} disabled={saving} className="between"
              style={{ padding: "12px 14px", borderRadius: "var(--radius-sm)", cursor: saving ? "default" : "pointer", textAlign: "start",
                border: "1.5px solid " + (replyMode === m.id ? "var(--color-secondary)" : "var(--border-2)"),
                background: replyMode === m.id ? "var(--color-primary-tint-soft)" : "#fff" }}>
              <span className="row" style={{ gap: 12 }}>
                <Icon name={m.icon} size={18} style={{ color: replyMode === m.id ? "var(--color-secondary)" : "var(--fg-3)", flexShrink: 0 }} />
                <span><span style={{ fontSize: 14, fontWeight: 700, display: "block" }}>{m.label}</span><span style={{ fontSize: 12, color: "var(--fg-4)" }}>{m.desc}</span></span>
              </span>
              {replyMode === m.id && <Icon name="checkcircle" size={18} style={{ color: "var(--color-secondary)", flexShrink: 0 }} />}
            </button>
          ))}
        </div>
      </Card>
      <Card>
        <div className="between">
          <div className="row" style={{ gap: 14 }}>
            <span className="opp" style={{ width: 44, height: 44, borderRadius: 12, background: "var(--color-primary-tint-soft)", color: "var(--color-secondary)" }}><Icon name="zap" size={22} /></span>
            <div>
              <div style={{ fontWeight: 700 }}>Auto-reply</div>
              <div style={{ fontSize: 12.5, color: "var(--fg-4)" }}>Master switch. When off, every agent sends drafts for approval.</div>
            </div>
          </div>
          <Switch on={!!ar.enabled} onChange={(v) => setAR("enabled", v)} disabled={saving} />
        </div>
        <div className="between" style={{ paddingTop: 14, marginTop: 14, borderTop: "1px solid var(--border-1)" }}>
          <div><div style={{ fontWeight: 600, fontSize: 14 }}>Business hours only</div><div style={{ fontSize: 12, color: "var(--fg-4)" }}>Hold auto-replies outside each contact's working hours.</div></div>
          <Switch on={!!ar.businessHoursOnly} onChange={(v) => setAR("businessHoursOnly", v)} disabled={saving} />
        </div>
        <div className="between" style={{ paddingTop: 14, marginTop: 14, borderTop: "1px solid var(--border-1)" }}>
          <div><div style={{ fontWeight: 600, fontSize: 14 }}>Daily send cap</div><div style={{ fontSize: 12, color: "var(--fg-4)" }}>Across all agents, protects your numbers.</div></div>
          <input className="input" type="number" min="0" value={maxPerDay} style={{ width: 110 }}
            onChange={(e) => setMaxPerDay(e.target.value)}
            onBlur={() => { const n = Number(maxPerDay) || 0; if (n !== ar.maxPerDay) setAR("maxPerDay", n); }} />
        </div>
      </Card>
      <Card>
        <div className="between">
          <div>
            <div style={{ fontWeight: 700 }}>Auto-send trust threshold</div>
            <div style={{ fontSize: 12.5, color: "var(--fg-4)" }}>Agents at or above this trust level send on their own. Below it, they draft for approval.</div>
          </div>
          <select className="select" value={autoSendTrust} onChange={(e) => setThreshold(Number(e.target.value))} disabled={saving} style={{ width: 220 }}>
            {[1, 2, 3, 4, 5].map((n) => <option key={n} value={n}>Level {n} · {TRUST_NAMES[n]}</option>)}
          </select>
        </div>
      </Card>
      <Card flush>
        <div className="between" style={{ padding: "16px 20px", borderBottom: "1px solid var(--border-1)" }}>
          <b>Per agent</b>
          <Badge tone={autoCount ? "green" : "neutral"} dot={autoCount ? "#22C55E" : "#9CA3AF"}>{autoCount} of {agents.length} auto-replying</Badge>
        </div>
        {agents.map((a) => {
          const on = ar.enabled && a.trust >= autoSendTrust;
          return (
            <div key={a.id} className="between" style={{ padding: "14px 20px", borderBottom: "1px solid var(--border-1)" }}>
              <div className="row" style={{ gap: 12 }}>
                <Avatar name={a.name} color={a.color} />
                <div>
                  <div style={{ fontWeight: 700, fontSize: 14 }}>{a.name}</div>
                  <div style={{ fontSize: 12, color: "var(--fg-4)" }}>{a.role} · trust {a.trust}</div>
                </div>
              </div>
              <Badge tone={on ? "green" : "neutral"} dot={on ? "#22C55E" : "#9CA3AF"}>{on ? "Auto-reply" : "Approval first"}</Badge>
            </div>
          );
        })}
      </Card>
      <div className="row" style={{ gap: 10, background: "var(--color-primary-tint-soft)", border: "1px solid var(--color-primary-tint)", borderRadius: 12, padding: 14, alignItems: "flex-start" }}>
        <Icon name="shield" size={18} style={{ color: "var(--color-secondary)", flexShrink: 0, marginTop: 1 }} />
        <span style={{ fontSize: 13, color: "var(--fg-2)", lineHeight: 1.5 }}>Even with auto-reply on, agents pause and ask you first on high-value leads, pricing commitments and anything they're unsure about — those still reach your approval queue.</span>
      </div>
    </div>
  );
}

/* ============================ WHATSAPP ================================== */
// relative-time helper for the provider card ("32s ago", "just now")
function waAgo(iso) {
  if (!iso && iso !== 0) return "—";
  const t = typeof iso === "number" ? iso : Date.parse(iso);
  if (!t) return "—";
  const s = Math.max(0, Math.floor((Date.now() - t) / 1000));
  if (s < 5) return "just now";
  if (s < 60) return s + "s ago";
  const m = Math.floor(s / 60); if (m < 60) return m + "m ago";
  const h = Math.floor(m / 60); if (h < 24) return h + "h ago";
  return Math.floor(h / 24) + "d ago";
}
// per-line state → badge + bar colours (matches the design)
const WA_LINE_STATE = {
  active: { label: "Active", tone: "green", dot: "#22C55E", bar: "#22C55E" },
  cooled_down: { label: "Cooled down", tone: "orange", dot: "#EA580C", bar: "#EF4444" },
  over_limit: { label: "Over limit", tone: "red", dot: "#EF4444", bar: "#EF4444" },
  paused: { label: "Paused", tone: "neutral", dot: "#9CA3AF", bar: "#9CA3AF" },
  connecting: { label: "Connecting…", tone: "blue", dot: "#2563EB", bar: "#2563EB" },
  disconnected: { label: "Disconnected", tone: "neutral", dot: "#9CA3AF", bar: "#D1D5DB" },
};
function WaDot({ ok }) { return <span className="sdot" style={{ background: ok ? "#22C55E" : "#9CA3AF" }} />; }
function WaModeToggle({ mode, onChange }) {
  return (
    <div className="row" style={{ gap: 0, background: "var(--bg-2)", borderRadius: 8, padding: 2, width: "fit-content" }}>
      {[["simulation", "Simulation"], ["live", "Live"]].map(([k, lbl]) => (
        <button key={k} type="button" onClick={() => onChange(k === "live")}
          style={{ padding: "5px 14px", fontSize: 12.5, fontWeight: 700, borderRadius: 6, cursor: "pointer", border: "none",
            background: mode === k ? "#fff" : "transparent", color: mode === k ? "var(--color-secondary)" : "var(--fg-4)", boxShadow: mode === k ? "var(--shadow-xs)" : "none" }}>
          {lbl}
        </button>
      ))}
    </div>
  );
}
function WaRow({ icon, label, children }) {
  return (
    <div className="between" style={{ fontSize: 12.5, gap: 12 }}>
      <span className="row" style={{ gap: 7, color: "var(--fg-4)", flexShrink: 0 }}><Icon name={icon} size={14} />{label}</span>
      <span className="row" style={{ gap: 6, fontWeight: 600, textAlign: "end" }}>{children}</span>
    </div>
  );
}
// Provider status card — the design's top card (provider, mode, IDs, webhook,
// last events, retry queue) with real Refresh + Send test, all backend-wired.
function ProviderStatusCard() {
  const data = useStore();
  const [st, setSt] = useState(data.meta?.whatsapp || null);
  const [busy, setBusy] = useState("");
  const [refreshedAt, setRefreshedAt] = useState(Date.now());
  const [test, setTest] = useState(null);
  const refresh = () => { setBusy("refresh"); return API.whatsapp.status().then((r) => { setSt(r); setRefreshedAt(Date.now()); }).catch((e) => console.error("wa status failed", e)).finally(() => setBusy("")); };
  React.useEffect(() => { refresh(); const id = setInterval(refresh, 5000); return () => clearInterval(id); }, []);
  const settings = data.SETTINGS || {};
  const live = st ? st.live : false;
  // The toggle reflects the user's PERSISTED preference (so it never snaps back
  // after a click); the liveBlocked note explains when Live can't take effect yet.
  const pref = settings.whatsapp?.simulation;
  const mode = pref === true ? "simulation" : pref === false ? "live" : (st?.mode === "live" ? "live" : "simulation");
  const liveBlocked = mode === "live" && !live; // wants Live but no Cloud creds yet
  const setMode = (toLive) => {
    Actions.updateSettings({ whatsapp: { ...(settings.whatsapp || {}), simulation: !toLive } }).then(refresh).catch((e) => console.error(e));
  };
  const sendTest = () => { setBusy("test"); setTest(null); API.whatsapp.sendTest().then((r) => setTest(r)).catch((e) => setTest({ ok: false, error: (e.message || "").replace(/^API[^{]*/, "").slice(0, 120) || "failed" })).finally(() => setBusy("")); };
  const lastWh = st?.lastWebhookEvent;
  const lastSend = st?.lastSendStatus;
  const retry = st?.retryQueue ?? 0;
  const webhookOk = st?.webhookHealth === "subscribed" || st?.webhookConfigured;
  const providerLabel = st?.provider === "whatsapp_web" ? "WhatsApp Web (Baileys)" : (st?.provider === "whatsapp_cloud" || st?.provider === "cloud" ? "WhatsApp Cloud API" : (st?.provider || "—"));
  // explicit send-readiness gate (server computes it; UI never claims send-ready otherwise)
  const RD_LABEL = { send_ready: "Send-ready", connected: "Connected", no_session: "No session", qr_required: "QR required", pairing_required: "Pairing required", not_send_ready: "Not send-ready", provider_error: "Provider error", uncertain: "Uncertain" };
  const rd = st?.readiness || { state: "uncertain", sendReady: false, reason: "Status unavailable" };
  return (
    <Card>
      <div className="between" style={{ marginBottom: 16 }}>
        <div style={{ fontWeight: 800, fontSize: 16 }}>Provider status</div>
        <div className="row" style={{ gap: 8 }}>
          <button className="btn btn--ghost btn--sm" disabled={busy === "refresh"} onClick={refresh}><Icon name="refresh" size={14} />{busy === "refresh" ? "…" : "Refresh"}</button>
          <button className="btn btn--ghost btn--sm" disabled={busy === "test"} onClick={sendTest}><Icon name="send" size={14} />{busy === "test" ? "Sending…" : "Send test"}</button>
        </div>
      </div>
      <div className="row" style={{ gap: 8, marginBottom: 16, padding: "10px 14px", borderRadius: 10, alignItems: "flex-start", background: rd.sendReady ? "var(--color-success-soft)" : (rd.state === "provider_error" ? "var(--color-danger-soft)" : "var(--color-orange-soft)") }}>
        <Icon name={rd.sendReady ? "checkcircle" : "alert"} size={16} style={{ color: rd.sendReady ? "var(--color-success)" : (rd.state === "provider_error" ? "var(--color-danger)" : "var(--color-orange)"), flexShrink: 0, marginTop: 1 }} />
        <div style={{ fontSize: 13 }}><b>Send readiness: {RD_LABEL[rd.state] || rd.state}</b>{rd.reason ? <span style={{ color: "var(--fg-2)" }}> — {rd.reason}</span> : null}</div>
      </div>
      <div className="grid" style={{ gridTemplateColumns: "1fr 1fr", gap: "16px 28px" }}>
        <WaRow icon="globe" label="Provider"><b>{providerLabel}</b></WaRow>
        <WaRow icon="shield" label="Mode"><WaModeToggle mode={mode} onChange={setMode} /></WaRow>
        <WaRow icon="building" label="Business Account ID"><span style={{ fontFamily: "monospace" }} dir="ltr">{st?.businessAccountId || "not set"}</span></WaRow>
        <WaRow icon="phoneDevice" label="Phone Number ID"><span style={{ fontFamily: "monospace" }} dir="ltr">{st?.phoneNumberId || "not set"}</span></WaRow>
        <WaRow icon="link" label="Webhook"><WaDot ok={webhookOk} />{webhookOk ? "Healthy · subscribed" : "Not configured"}</WaRow>
        <WaRow icon="clock" label="Last webhook event">{lastWh ? `${lastWh.type} · ${waAgo(lastWh.at)}` : "none"}</WaRow>
        <WaRow icon="checkcircle" label="Last send status">{lastSend ? <><WaDot ok={/sent|deliv|read|200/i.test(lastSend.status)} />{lastSend.status}{lastSend.mode ? ` · ${lastSend.mode}` : ""}</> : "none"}</WaRow>
        <WaRow icon="refresh" label="Retry queue"><Badge tone={retry ? "orange" : "neutral"} dot={retry ? "#EA580C" : "#9CA3AF"}>{retry} job{retry === 1 ? "" : "s"}</Badge></WaRow>
      </div>
      {liveBlocked && <div className="row" style={{ gap: 8, marginTop: 12, fontSize: 12, color: "var(--color-warning)" }}><Icon name="alert" size={13} />Live needs WhatsApp Cloud API credentials — set them on the server to send live. Still simulated for now.</div>}
      {test && <div className="row" style={{ gap: 8, marginTop: 12, padding: "10px 12px", borderRadius: 10, fontSize: 12.5, background: test.ok ? "var(--color-success-soft)" : "var(--color-danger-soft)", color: test.ok ? "#15803D" : "var(--color-danger)" }}><Icon name={test.ok ? "checkcircle" : "alert"} size={14} />{test.ok ? `Test ${test.simulated ? "recorded (simulation)" : "sent"} to ${test.to || "the connected line"} · ${test.status || "ok"}` : `Test failed: ${test.message || test.error || "no active sender"}`}</div>}
      <div className="muted" style={{ fontSize: 12, marginTop: 12 }}>Status refreshed {waAgo(refreshedAt)}.</div>
    </Card>
  );
}

// Real WhatsApp Web (Baileys) linking — shown only when the server runs with
// WHATSAPP_MODE=web. Polls the real QR; no static/fake QR, no fake connected state.
const WAWEB_META = {
  connected: { tone: "green", c: "#22C55E", label: "Connected" },
  qr: { tone: "blue", c: "#2563EB", label: "Scan to link" },
  pairing_code: { tone: "blue", c: "#2563EB", label: "Enter code on phone" },
  connecting: { tone: "orange", c: "#EA580C", label: "Connecting…" },
  disconnected: { tone: "neutral", c: "#9CA3AF", label: "Disconnected" },
  logged_out: { tone: "red", c: "#B91C1C", label: "Logged out" },
  error: { tone: "red", c: "#B91C1C", label: "Error" },
};
// ====================== REAL MULTI-LINE WHATSAPP ======================
// Each line owns its own Baileys session (own QR / pairing / phone number) and a
// messaging sender the campaign queue rotates across. Nothing here is faked: a
// line is only "active" when its real session is open. Requires WHATSAPP_MODE=web.

function LineStatusBadge({ status }) {
  const m = WAWEB_META[status] || WAWEB_META.disconnected;
  return <Badge tone={m.tone} dot={m.c}>{m.label}</Badge>;
}

// Per-line connect modal — opens THIS line's own QR or phone-pairing flow and
// polls only that line's status.
function LineConnectModal({ line, onClose }) {
  const [method, setMethod] = useState("qr"); // "qr" | "phone"
  const [phone, setPhone] = useState("");
  const [live, setLive] = useState(line);
  const [busy, setBusy] = useState("");
  const [pairErr, setPairErr] = useState(null);
  React.useEffect(() => {
    let alive = true;
    if (method === "qr") API.whatsapp.lineQr(line.id).catch(() => {});
    const tick = () => API.whatsapp.lineStatus(line.id).then((r) => { if (alive && r) setLive(r); }).catch(() => {});
    tick(); const id = setInterval(tick, 2000);
    return () => { alive = false; clearInterval(id); };
  }, [line.id, method]);
  React.useEffect(() => { if (live?.status === "connected") { const t = setTimeout(onClose, 1100); return () => clearTimeout(t); } }, [live?.status]);
  const digits = phone.replace(/\D/g, "");
  const phoneValid = /^\d{8,15}$/.test(phone) && phone === digits;
  const generateCode = () => {
    setPairErr(null); setBusy("pair");
    API.whatsapp.linePairing(line.id, phone)
      .then((r) => { if (!(r?.ok || r?.pairingCode)) setPairErr(r?.message || r?.error || "Could not get a pairing code."); })
      .catch((e) => setPairErr(e.message || "Pairing failed"))
      .finally(() => setBusy(""));
  };
  const qr = live?.qr || null;
  const pairingCode = live?.pairingCode || null;
  const connected = live?.status === "connected";
  return (
    <Modal onClose={onClose} style={{ width: 440 }}>
      <div style={{ padding: 24 }}>
        <div className="between" style={{ marginBottom: 4 }}>
          <div style={{ fontWeight: 800, fontSize: 16 }}>Connect “{line.label}”</div>
          <LineStatusBadge status={live?.status || "connecting"} />
        </div>
        <p className="muted" style={{ fontSize: 12.5, marginBottom: 16 }}>This line opens its <b>own</b> WhatsApp session — link a different phone number than your other lines.</p>
        {connected ? (
          <div className="col" style={{ gap: 8, alignItems: "center", padding: "10px 0 4px" }}>
            <span className="opp" style={{ width: 48, height: 48, borderRadius: 14, background: "var(--color-success-soft)", color: "#15803D" }}><Icon name="checkcircle" size={24} /></span>
            <div style={{ fontWeight: 700 }}>Linked{live?.phoneNumber ? ` · +${live.phoneNumber}` : ""}</div>
            <div className="muted" style={{ fontSize: 12.5 }}>This line is now an active sender.</div>
          </div>
        ) : (
          <div className="col" style={{ gap: 14 }}>
            <div className="row" style={{ gap: 8 }}>
              {[["qr", "qr", "Link with QR"], ["phone", "phoneDevice", "Link with phone number"]].map(([k, ic, lbl]) => (
                <button key={k} type="button" onClick={() => { setMethod(k); setPairErr(null); }} className="row" style={{ gap: 6, padding: "8px 12px", fontSize: 12.5, fontWeight: 600, borderRadius: 10, cursor: "pointer", border: method === k ? "2px solid var(--color-secondary)" : "1px solid var(--border-1)", background: method === k ? "var(--color-primary-tint-soft)" : "#fff" }}><Icon name={ic} size={14} />{lbl}</button>
              ))}
            </div>
            {method === "qr" ? (
              qr ? (
                <div style={{ textAlign: "center", padding: "4px 0" }}>
                  <p className="muted" style={{ fontSize: 13, marginBottom: 12 }}>On the phone for this line: WhatsApp → <b>Linked devices</b> → <b>Link a device</b>, then scan:</p>
                  <img src={qr} alt="WhatsApp QR" style={{ width: 210, height: 210, borderRadius: 12, border: "1px solid var(--border-1)" }} />
                  <div className="row" style={{ gap: 6, justifyContent: "center", marginTop: 10, color: "var(--color-blue)", fontSize: 13, fontWeight: 600 }}><span className="spin" style={{ width: 14, height: 14 }} />Waiting for you to scan…</div>
                </div>
              ) : (
                <div className="row" style={{ gap: 12, padding: "8px 0" }}>
                  <span className="spin" style={{ width: 22, height: 22 }} />
                  <div style={{ fontSize: 13, color: "var(--fg-3)" }}>{live?.lastError ? `Last error: ${live.lastError}` : "Generating a secure QR for this line…"}</div>
                </div>
              )
            ) : (
              <div className="col" style={{ gap: 10 }}>
                <Field label="Phone number for this line (country code, digits only)" hint="Example: 9665XXXXXXXX — no +, spaces or brackets.">
                  <input className="input" inputMode="numeric" dir="ltr" placeholder="9665XXXXXXXX" value={phone} onChange={(e) => setPhone(e.target.value.replace(/[^\d]/g, ""))} />
                </Field>
                {phone && !phoneValid && <div className="row" style={{ gap: 6, color: "var(--color-danger)", fontSize: 12.5 }}><Icon name="alert" size={14} />Enter 8–15 digits including the country code, digits only.</div>}
                <Button variant="primary" icon="phoneDevice" disabled={!phoneValid || busy === "pair"} onClick={generateCode}>{busy === "pair" ? "Requesting…" : "Generate pairing code"}</Button>
                {pairErr && <div className="row" style={{ gap: 8, background: "var(--color-danger-soft)", color: "var(--color-danger)", borderRadius: 10, padding: "10px 12px", fontSize: 12.5 }}><Icon name="alert" size={14} />{pairErr}</div>}
                {pairingCode && (
                  <div style={{ background: "var(--color-primary-tint-soft)", border: "1px solid var(--color-primary-tint)", borderRadius: 12, padding: 16 }}>
                    <div className="muted" style={{ fontSize: 12, marginBottom: 6 }}>Pairing code for this line</div>
                    <div style={{ fontSize: 26, fontWeight: 800, letterSpacing: 4, fontFamily: "monospace" }}>{pairingCode}</div>
                    <ol style={{ fontSize: 12.5, color: "var(--fg-2)", margin: "12px 0 0", paddingInlineStart: 18, lineHeight: 1.7 }}>
                      <li>Open WhatsApp on this line's phone</li>
                      <li><b>Linked devices</b> → <b>Link a device</b></li>
                      <li>Tap <b>Link with phone number instead</b></li>
                      <li>Enter the code above</li>
                    </ol>
                    <div className="row" style={{ gap: 6, marginTop: 10, color: "var(--color-blue)", fontSize: 12.5, fontWeight: 600 }}><span className="spin" style={{ width: 12, height: 12 }} />Waiting for you to enter it…</div>
                  </div>
                )}
              </div>
            )}
          </div>
        )}
        <div className="row" style={{ marginTop: 18 }}><Button variant="ghost" block onClick={onClose}>{connected ? "Done" : "Close"}</Button></div>
      </div>
    </Modal>
  );
}

// Delete confirmation — exact design copy. Backend stops queued jobs on this
// number and removes the line + sender; conversations and leads are preserved.
function DeleteLineModal({ line, onClose, onDeleted }) {
  const [busy, setBusy] = useState(false);
  const del = () => { setBusy(true); API.whatsapp.deleteLine(line.id).then(() => { onDeleted ? onDeleted() : onClose(); }).catch((e) => console.error("delete line failed", e)).finally(() => setBusy(false)); };
  return (
    <Modal onClose={onClose} style={{ width: 430 }}>
      <div style={{ padding: 24 }}>
        <div style={{ marginBottom: 14 }}><span className="opp" style={{ width: 44, height: 44, borderRadius: 12, background: "var(--color-danger-soft)", color: "var(--color-danger)" }}><Icon name="trash" size={22} /></span></div>
        <div style={{ fontWeight: 800, fontSize: 17, marginBottom: 8 }}>Delete this line?</div>
        <p style={{ fontSize: 13.5, color: "var(--fg-2)", lineHeight: 1.6 }}>“{line.label}” will be unlinked and removed. Any queued jobs on this number stop. Campaigns using it need a new line. This cannot be undone.</p>
        <div className="row" style={{ gap: 10, justifyContent: "flex-end", marginTop: 20 }}>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button variant="dark" icon="trash" style={{ background: "var(--color-danger)" }} disabled={busy} onClick={del}>{busy ? "Deleting…" : "Delete line"}</Button>
        </div>
      </div>
    </Modal>
  );
}

// Manage line modal — name / assigned agent / daily limit / live mode, plus
// Disconnect (or Connect) + a Delete danger box. Everything persists to backend.
function ManageLineModal({ line, onClose, onChanged }) {
  const data = useStore();
  const agents = data.AGENTS || [];
  const [name, setName] = useState(line.label);
  const [agentId, setAgentId] = useState(line.agentId || "");
  const [limit, setLimit] = useState(String(line.dailyLimit ?? 500));
  const [liveMode, setLiveMode] = useState(line.enabled !== false);
  const [busy, setBusy] = useState("");
  const [confirmDel, setConfirmDel] = useState(false);
  const [connect, setConnect] = useState(false);
  const connected = line.status === "connected";
  const save = () => { setBusy("save"); API.whatsapp.updateLine(line.id, { label: name.trim() || line.label, agentId: agentId || null, dailyLimit: Number(limit) || line.dailyLimit, enabled: liveMode }).then(() => { onChanged && onChanged(); onClose(); }).catch((e) => console.error("save line failed", e)).finally(() => setBusy("")); };
  const disconnect = () => { setBusy("dc"); API.whatsapp.lineDisconnect(line.id).then(() => { onChanged && onChanged(); onClose(); }).catch((e) => console.error(e)).finally(() => setBusy("")); };
  return (
    <Modal onClose={onClose} style={{ width: 480 }}>
      <MHead title={line.label} sub={line.phoneNumber ? `+${line.phoneNumber}` : "Not linked yet"} onClose={onClose} />
      <div style={{ padding: 22 }}>
        <Field label="Line name"><input className="input" value={name} onChange={(e) => setName(e.target.value)} /></Field>
        <Field label="Assigned agent"><select className="select" value={agentId} onChange={(e) => setAgentId(e.target.value)}><option value="">Unassigned</option>{agents.map((a) => <option key={a.id} value={a.id}>{a.name}</option>)}</select></Field>
        <Field label="Daily send limit" hint="Protects the number from being flagged."><input className="input" inputMode="numeric" value={limit} onChange={(e) => setLimit(e.target.value.replace(/[^\d]/g, ""))} /></Field>
        <div className="between" style={{ padding: "14px 0", borderTop: "1px solid var(--border-1)", marginTop: 4 }}>
          <div><div style={{ fontWeight: 600, fontSize: 14 }}>Live mode</div><div style={{ fontSize: 12, color: "var(--fg-4)" }}>{liveMode ? "Messages send for real" : "Paused — this line won't send messages"}</div></div>
          <Switch on={liveMode} onChange={setLiveMode} />
        </div>
        <div className="between" style={{ background: "var(--color-danger-soft)", border: "1px solid #FCA5A5", borderRadius: 12, padding: "12px 14px", marginTop: 6 }}>
          <div><div style={{ fontWeight: 700, fontSize: 13.5, color: "var(--color-danger)" }}>Delete line</div><div style={{ fontSize: 12, color: "var(--fg-3)" }}>Unlink and remove this number</div></div>
          <button className="btn btn--ghost btn--sm" style={{ color: "var(--color-danger)", borderColor: "#FCA5A5" }} onClick={() => setConfirmDel(true)}><Icon name="trash" size={14} />Delete</button>
        </div>
        <div className="row" style={{ gap: 10, justifyContent: "space-between", marginTop: 16 }}>
          {connected
            ? <button className="btn btn--ghost btn--sm" disabled={busy === "dc"} style={{ color: "var(--color-danger)" }} onClick={disconnect}><Icon name="wifiOff" size={15} />{busy === "dc" ? "…" : "Disconnect"}</button>
            : <button className="btn btn--ghost btn--sm" onClick={() => setConnect(true)}><Icon name="link" size={15} />Connect</button>}
          <div className="row" style={{ gap: 10 }}>
            <Button variant="ghost" onClick={onClose}>Cancel</Button>
            <Button variant="primary" icon="check" disabled={busy === "save"} onClick={save}>{busy === "save" ? "Saving…" : "Save"}</Button>
          </div>
        </div>
      </div>
      {confirmDel && <DeleteLineModal line={line} onClose={() => setConfirmDel(false)} onDeleted={() => { setConfirmDel(false); onChanged && onChanged(); onClose(); }} />}
      {connect && <LineConnectModal line={line} onClose={() => { setConnect(false); onChanged && onChanged(); }} />}
    </Modal>
  );
}

// Connect WhatsApp lines — the design's batch connector: add several draft rows,
// fill name/phone/agent, then "Show QR to connect" creates a REAL line and asks
// for ITS own QR. No fake QR, no fake connected state.
// Map a real LINE's status → the modal's draft status (so an already-connected
// line is shown connected and counted — fixes the "0 of 1 connected" mismatch).
function lineDraftStatus(line) {
  if (line.canSend || ["connected", "active"].includes(line.status) || line.state === "connected" || line.state === "active") return "connected";
  if (["connecting", "qr", "qr_ready", "pairing_code", "pairing_ready"].includes(line.status) || ["connecting", "qr_ready", "pairing_ready"].includes(line.state)) return "connecting";
  return "disconnected";
}
function ConnectLinesModal({ onClose, onChanged }) {
  const data = useStore();
  const agents = data.AGENTS || [];
  const nextKey = React.useRef(2);
  const [drafts, setDrafts] = useState([{ key: "d1", name: "", phone: "", agentId: agents[0]?.id || "", lineId: null, status: "not_started", method: "qr" }]);
  const [sel, setSel] = useState("d1");
  const [live, setLive] = useState({});
  const [busy, setBusy] = useState("");
  const [errs, setErrs] = useState({}); // per-draft pairing/connect error message
  const hydrated = React.useRef(false);

  // Hydrate from the REAL existing lines on open so the count reflects reality.
  React.useEffect(() => {
    if (hydrated.current) return; hydrated.current = true;
    API.whatsapp.lines().then((r) => {
      const lines = (r && r.lines) || [];
      if (!lines.length) return;
      const existing = lines.map((l) => ({ key: "line_" + l.id, name: l.label || "Line", phone: l.phoneNumber ? "+" + l.phoneNumber : "", agentId: l.agentId || "", lineId: l.id, status: lineDraftStatus(l), method: l.connectionMethod === "phone" ? "phone" : "qr", existing: true }));
      setDrafts((ds) => [...existing, ...ds.filter((d) => !d.lineId)]);
      setSel(existing[0].key);
      const seed = {}; lines.forEach((l) => { seed[l.id] = l; }); setLive((p) => ({ ...seed, ...p }));
    }).catch(() => {});
  }, []);

  const pollKey = drafts.map((d) => d.lineId + ":" + d.status).join(",");
  React.useEffect(() => {
    const active = drafts.filter((d) => d.lineId && d.status !== "connected");
    if (!active.length) return;
    let alive = true;
    const tick = () => active.forEach((d) => API.whatsapp.lineStatus(d.lineId).then((r) => {
      if (!alive || !r) return;
      setLive((prev) => ({ ...prev, [d.lineId]: r }));
      const ds = lineDraftStatus(r);
      if (r.status === "connected") { setDrafts((dr) => dr.map((x) => x.lineId === d.lineId ? { ...x, status: "connected", phone: r.phoneNumber ? "+" + r.phoneNumber : x.phone } : x)); onChanged && onChanged(); }
      else if (ds !== d.status) setDrafts((dr) => dr.map((x) => x.lineId === d.lineId ? { ...x, status: ds } : x));
    }).catch(() => {}));
    tick(); const id = setInterval(tick, 2000);
    return () => { alive = false; clearInterval(id); };
  }, [pollKey]);

  const cur = drafts.find((d) => d.key === sel) || drafts[0];
  const digits = (cur?.phone || "").replace(/\D/g, "");
  const nameOk = !!(cur && cur.name.trim());
  const phoneOk = digits.length >= 8;
  const curLive = cur?.lineId ? live[cur.lineId] : null;
  const qr = curLive?.qr || null;
  const pairingCode = curLive?.pairingCode || null;
  const curConnected = cur?.status === "connected";
  const patchDraft = (key, p) => setDrafts((ds) => ds.map((d) => d.key === key ? { ...d, ...p } : d));
  const setErr = (key, m) => setErrs((e) => ({ ...e, [key]: m }));
  const addLine = () => { const key = "d" + (nextKey.current++); setDrafts((ds) => [...ds, { key, name: "", phone: "", agentId: agents[0]?.id || "", lineId: null, status: "not_started", method: "qr" }]); setSel(key); };

  // Ensure a real line exists for this draft (create on first connect), returning its id.
  const ensureLine = async (d) => {
    if (d.lineId) return d.lineId;
    const line = await API.whatsapp.createLine({ label: d.name.trim(), agentId: d.agentId, dailyLimit: 500 });
    patchDraft(d.key, { lineId: line.id });
    onChanged && onChanged();
    return line.id;
  };
  const connectQr = async () => {
    if (!nameOk) return; setBusy("qr"); setErr(cur.key, null);
    try { const id = await ensureLine(cur); patchDraft(cur.key, { status: "connecting", method: "qr" }); await API.whatsapp.lineQr(id); }
    catch (e) { setErr(cur.key, e.message || "Couldn't start QR linking."); }
    finally { setBusy(""); }
  };
  const connectPhone = async () => {
    if (!nameOk || !phoneOk) return; setBusy("phone"); setErr(cur.key, null);
    try {
      const id = await ensureLine(cur); patchDraft(cur.key, { status: "connecting", method: "phone" });
      const r = await API.whatsapp.linePairing(id, digits);
      if (!(r?.ok || r?.pairingCode)) setErr(cur.key, r?.message || r?.error || "Couldn't get a pairing code.");
    } catch (e) { setErr(cur.key, e.message || "Pairing failed."); }
    finally { setBusy(""); }
  };

  const STAT = { not_started: "Not started", connecting: "Connecting…", connected: "Connected", disconnected: "Disconnected" };
  const DOT = { connected: "#22C55E", connecting: "#2563EB", disconnected: "#EF4444", not_started: "#9CA3AF" };
  const connectedCount = drafts.filter((d) => d.status === "connected").length;
  const totalLines = drafts.filter((d) => d.lineId).length || drafts.length;
  const showForm = !curConnected && (!cur?.lineId || cur?.status === "disconnected" || cur?.status === "not_started");
  return (
    <Modal onClose={onClose} style={{ width: 760, maxWidth: "94vw" }}>
      <MHead title="Connect WhatsApp lines" sub="Link each number by QR or phone pairing — already-linked lines show as connected" onClose={onClose} />
      <div className="row wa-connect-body" style={{ alignItems: "stretch", minHeight: 360 }}>
        {/* left: draft list */}
        <div className="col wa-connect-list" style={{ gap: 8, width: 220, padding: 16, borderInlineEnd: "1px solid var(--border-1)", background: "var(--bg-2)" }}>
          {drafts.map((d, i) => (
            <button key={d.key} type="button" onClick={() => setSel(d.key)} className="row" style={{ gap: 10, padding: "10px 12px", borderRadius: 10, cursor: "pointer", textAlign: "start",
              border: sel === d.key ? "2px solid var(--color-secondary)" : "1px solid var(--border-1)", background: sel === d.key ? "#fff" : "transparent" }}>
              <span className="opp" style={{ width: 30, height: 30, borderRadius: 8, background: "var(--bg-2)", color: "var(--fg-3)", flexShrink: 0 }}><Icon name="phoneDevice" size={16} /></span>
              <div style={{ minWidth: 0 }}>
                <div style={{ fontWeight: 700, fontSize: 13, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{d.name.trim() || `Line ${i + 1}`}</div>
                <div className="row" style={{ gap: 5, fontSize: 11.5, color: d.status === "connected" ? "#15803D" : "var(--fg-4)" }}><span className="sdot" style={{ background: DOT[d.status] || "#9CA3AF" }} />{STAT[d.status] || d.status}</div>
              </div>
            </button>
          ))}
          <button type="button" className="btn btn--ghost btn--sm" style={{ marginTop: 4 }} onClick={addLine}><Icon name="plus" size={14} />Add another line</button>
        </div>
        {/* right: selected draft form / QR / pairing */}
        <div style={{ flex: 1, padding: 20 }}>
          {curConnected ? (
            <div className="col" style={{ gap: 8, alignItems: "center", padding: "24px 0" }}>
              <span className="opp" style={{ width: 52, height: 52, borderRadius: 14, background: "var(--color-success-soft)", color: "#15803D" }}><Icon name="checkcircle" size={26} /></span>
              <div style={{ fontWeight: 700 }}>Connected{curLive?.phoneNumber ? ` · +${curLive.phoneNumber}` : (cur?.phone ? ` · ${cur.phone}` : "")}</div>
              <div className="muted" style={{ fontSize: 12.5 }}>This line is an active sender.</div>
            </div>
          ) : showForm ? (
            <div className="col" style={{ gap: 14 }}>
              <Field label="Line name"><input className="input" autoFocus value={cur?.name || ""} placeholder="e.g. Maxab KSA · Outreach" onChange={(e) => patchDraft(cur.key, { name: e.target.value })} /></Field>
              <Field label="Phone number" hint="With country code (required for phone pairing)."><input className="input" dir="ltr" value={cur?.phone || ""} placeholder="+966 5x xxx xxxx" onChange={(e) => patchDraft(cur.key, { phone: e.target.value })} /></Field>
              <Field label="Assign to agent"><select className="select" value={cur?.agentId || ""} onChange={(e) => patchDraft(cur.key, { agentId: e.target.value })}><option value="">Unassigned</option>{agents.map((a) => <option key={a.id} value={a.id}>{a.name}</option>)}</select></Field>
              {/* QR or phone pairing — both available before final connect (Blocker 4) */}
              <div className="row" style={{ gap: 10 }}>
                <Button variant="primary" icon="qr" disabled={!nameOk || !!busy} onClick={connectQr}>{busy === "qr" ? "Starting…" : "Link with QR"}</Button>
                <Button variant="secondary" icon="phoneDevice" disabled={!nameOk || !phoneOk || !!busy} onClick={connectPhone}>{busy === "phone" ? "Requesting…" : "Link with phone number"}</Button>
              </div>
              {!phoneOk && <div className="muted" style={{ fontSize: 11.5 }}>Enter a phone number with its country code to enable phone pairing.</div>}
              {errs[cur.key] && <div className="row" style={{ gap: 8, background: "var(--color-danger-soft)", color: "var(--color-danger)", borderRadius: 10, padding: "10px 12px", fontSize: 12.5 }}><Icon name="alert" size={14} />{errs[cur.key]}</div>}
            </div>
          ) : cur?.method === "phone" ? (
            <div style={{ textAlign: "center" }}>
              {pairingCode ? (
                <div className="col" style={{ gap: 8, alignItems: "center", padding: "8px 0" }}>
                  <p className="muted" style={{ fontSize: 13 }}>On the phone for this line: WhatsApp → <b>Linked devices</b> → <b>Link with phone number instead</b>, then enter:</p>
                  <div style={{ fontSize: 26, fontWeight: 800, letterSpacing: 4, fontFamily: "monospace" }}>{pairingCode}</div>
                  <div className="row" style={{ gap: 6, justifyContent: "center", marginTop: 6, color: "var(--color-blue)", fontSize: 13, fontWeight: 600 }}><span className="spin" style={{ width: 14, height: 14 }} />Waiting for you to enter the code…</div>
                </div>
              ) : errs[cur.key] ? (
                <div className="col" style={{ gap: 10, padding: "8px 0" }}>
                  <div className="row" style={{ gap: 8, background: "var(--color-danger-soft)", color: "var(--color-danger)", borderRadius: 10, padding: "10px 12px", fontSize: 12.5 }}><Icon name="alert" size={14} />{errs[cur.key]}</div>
                  <div className="row" style={{ gap: 10, justifyContent: "center" }}>
                    <Button variant="ghost" size="sm" onClick={connectPhone}>Retry pairing</Button>
                    <Button variant="ghost" size="sm" onClick={connectQr}>Use QR instead</Button>
                  </div>
                </div>
              ) : (
                <div className="row" style={{ gap: 12, padding: "12px 0", justifyContent: "center" }}><span className="spin" style={{ width: 22, height: 22 }} /><div style={{ fontSize: 13, color: "var(--fg-3)" }}>Requesting a pairing code…</div></div>
              )}
            </div>
          ) : (
            qr ? (
              <div style={{ textAlign: "center" }}>
                <p className="muted" style={{ fontSize: 13, marginBottom: 12 }}>On the phone for this line: WhatsApp → <b>Linked devices</b> → <b>Link a device</b>, then scan:</p>
                <img src={qr} alt="WhatsApp QR" style={{ width: 210, height: 210, borderRadius: 12, border: "1px solid var(--border-1)" }} />
                <div className="row" style={{ gap: 6, justifyContent: "center", marginTop: 10, color: "var(--color-blue)", fontSize: 13, fontWeight: 600 }}><span className="spin" style={{ width: 14, height: 14 }} />Waiting for you to scan…</div>
                <div style={{ marginTop: 10 }}><Button variant="ghost" size="sm" onClick={connectPhone} disabled={!phoneOk}>Use phone number instead</Button></div>
              </div>
            ) : (
              <div className="col" style={{ gap: 10, alignItems: "center", padding: "12px 0" }}>
                <div className="row" style={{ gap: 12 }}><span className="spin" style={{ width: 22, height: 22 }} /><div style={{ fontSize: 13, color: "var(--fg-3)" }}>{curLive?.lastError ? `Last error: ${curLive.lastError}` : "Generating a secure QR for this line…"}</div></div>
                {curLive?.lastError && <Button variant="ghost" size="sm" onClick={connectPhone} disabled={!phoneOk}>Try phone pairing instead</Button>}
              </div>
            )
          )}
        </div>
      </div>
      {/* footer */}
      <div className="between" style={{ padding: "14px 20px", borderTop: "1px solid var(--border-1)" }}>
        <div className="row" style={{ gap: 6, fontSize: 12.5, color: "var(--fg-3)" }}><Icon name="checkcircle" size={15} style={{ color: connectedCount ? "#22C55E" : "var(--fg-4)" }} /><b>{connectedCount}</b> of {totalLines} connected</div>
        <Button variant="dark" onClick={onClose}>Done</Button>
      </div>
    </Modal>
  );
}

// A single line card — the design layout: icon, name, "phone · agent · N/M today
// · health N", a state badge, the contextual Pause/Resume/Manage action, a delete
// icon, and a coloured usage/health bar.
function WaLineCard({ line, onChanged }) {
  const [busy, setBusy] = useState("");
  const [manage, setManage] = useState(false);
  const [confirmDel, setConfirmDel] = useState(false);
  const [connect, setConnect] = useState(false);
  const state = line.state || "disconnected";
  const meta = WA_LINE_STATE[state] || WA_LINE_STATE.disconnected;
  const pct = Math.min(100, Math.round(((line.sentToday || 0) / Math.max(1, line.dailyLimit || 500)) * 100));
  const barPct = state === "over_limit" || state === "cooled_down" ? 100 : pct;
  const act = (key, p) => { setBusy(key); return p.then(() => onChanged()).catch((e) => console.error(e)).finally(() => setBusy("")); };
  const pause = () => act("pause", API.whatsapp.updateLine(line.id, { enabled: false }));
  const resume = () => act("resume", API.whatsapp.updateLine(line.id, { enabled: true }));
  const sub = [
    line.phoneNumber ? "+" + line.phoneNumber : "Not linked",
    line.agentName,
    `${line.sentToday || 0}/${line.warmup ? line.warmup.cap : (line.dailyLimit ?? 500)} today`,
    Number.isFinite(line.healthScore) ? `health ${Math.round(line.healthScore)}` : null,
  ].filter(Boolean).join(" · ");
  return (
    <Card>
      <div className="between wa-linecard-head" style={{ alignItems: "center" }}>
        <div className="row" style={{ gap: 14, cursor: "pointer", minWidth: 0 }} onClick={() => setManage(true)}>
          <span className="opp" style={{ width: 44, height: 44, borderRadius: 12, background: "var(--bg-2)", color: "var(--fg-3)", flexShrink: 0 }}><Icon name="phoneDevice" size={22} /></span>
          <div style={{ minWidth: 0 }}>
            <div style={{ fontWeight: 700 }}>{line.label}</div>
            <div style={{ fontSize: 12.5, color: "var(--fg-4)", marginTop: 2, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }} dir="ltr">{sub}</div>
          </div>
        </div>
        <div className="row" style={{ gap: 10, flexShrink: 0 }}>
          {line.warmup && <Badge tone="blue" dot="#2563EB" title={`New-line warm-up: sending capped at ${line.warmup.cap}/day, ramping to ${line.warmup.normalCap}/day over ${line.warmup.daysToFull} more day(s)`}>Warming up · {line.warmup.stage}</Badge>}
          <Badge tone={meta.tone} dot={meta.dot}>{meta.label}</Badge>
          {state === "active" && <button className="btn btn--ghost btn--sm" disabled={busy === "pause"} onClick={pause}><Icon name="pause" size={14} />{busy === "pause" ? "…" : "Pause"}</button>}
          {state === "paused" && <button className="btn btn--ghost btn--sm" disabled={busy === "resume"} onClick={resume}><Icon name="play" size={14} />{busy === "resume" ? "…" : "Resume"}</button>}
          {state === "disconnected" && <button className="btn btn--ghost btn--sm" onClick={() => setConnect(true)}><Icon name="link" size={14} />Connect</button>}
          {(state === "cooled_down" || state === "over_limit" || state === "connecting") && <button className="btn btn--ghost btn--sm" onClick={() => setManage(true)}>Manage</button>}
          <button className="iconbtn" title="Delete line" onClick={() => setConfirmDel(true)}><Icon name="trash" size={16} /></button>
        </div>
      </div>
      <div style={{ height: 4, borderRadius: 3, background: "var(--border-1)", marginTop: 14, overflow: "hidden" }}>
        <div style={{ height: "100%", width: barPct + "%", background: meta.bar, borderRadius: 3, transition: "width var(--motion-base)" }} />
      </div>
      {manage && <ManageLineModal line={line} onClose={() => setManage(false)} onChanged={onChanged} />}
      {confirmDel && <DeleteLineModal line={line} onClose={() => setConfirmDel(false)} onDeleted={() => { setConfirmDel(false); onChanged(); }} />}
      {connect && <LineConnectModal line={line} onClose={() => { setConnect(false); onChanged(); }} />}
    </Card>
  );
}

// Connected lines section — description + "Connect lines" + the line cards +
// the live-mode / retry-queue footer (design B).
function WhatsAppLinesCard() {
  const data = useStore();
  const webMode = data.meta?.whatsapp?.channel === "web";
  const [lines, setLines] = useState(null);
  const [st, setSt] = useState(data.meta?.whatsapp || null);
  const [connectOpen, setConnectOpen] = useState(false);
  const refresh = React.useCallback(() => { if (!webMode) return; API.whatsapp.lines().then((r) => setLines(r?.lines || [])).catch(() => {}); API.whatsapp.status().then(setSt).catch(() => {}); }, [webMode]);
  React.useEffect(() => { refresh(); if (!webMode) return; const id = setInterval(refresh, 3000); return () => clearInterval(id); }, [refresh, webMode]);

  if (!webMode) {
    return (
      <div className="between">
        <p className="muted" style={{ fontSize: 13.5, maxWidth: 540, lineHeight: 1.6 }}>Connected numbers your agents send from. Real per-line linking (a separate QR / phone pairing and session per number) runs in <b>WhatsApp Web mode</b> — start the server with <code style={{ fontFamily: "monospace" }}>WHATSAPP_MODE=web</code>.</p>
      </div>
    );
  }

  const list = lines || [];
  const active = list.filter((l) => l.canSend);
  const live = st?.live;
  const failed = st?.failedLast24h ?? st?.retryQueue ?? 0;
  return (
    <div className="col" style={{ gap: 14 }}>
      <div className="between">
        <p className="muted" style={{ fontSize: 13.5, maxWidth: 480, lineHeight: 1.6 }}>Connected numbers your agents send from. Scan the QR once — the line stays linked.</p>
        <Button variant="dark" icon="qr" onClick={() => setConnectOpen(true)}>Connect lines</Button>
      </div>
      {active.length === 1 && (
        <div className="row" style={{ gap: 8, background: "var(--color-warning-soft, #FEF3C7)", border: "1px solid #FDE68A", borderRadius: 10, padding: "10px 12px", fontSize: 12.5, color: "#92400E" }}>
          <Icon name="alert" size={14} style={{ flexShrink: 0, marginTop: 1 }} />Only one active line — high volume from a single number increases ban risk. Add more lines so sends rotate across numbers.
        </div>
      )}
      <div className="col" style={{ gap: 12 }}>
        {lines === null && <div className="muted" style={{ fontSize: 13 }}>Loading lines…</div>}
        {lines !== null && list.length === 0 && <div className="muted" style={{ fontSize: 13 }}>No lines yet — click “Connect lines” to add a number.</div>}
        {list.map((l) => <WaLineCard key={l.id} line={l} onChanged={refresh} />)}
      </div>
      {/* live-mode / retry-queue footer (design B) */}
      <div className="row" style={{ gap: 10, background: live ? "var(--color-success-soft)" : "var(--bg-2)", border: "1px solid " + (live ? "#A7F3D0" : "var(--border-1)"), borderRadius: 12, padding: 14, color: "var(--fg-2)", fontSize: 13 }}>
        <Icon name="shield" size={18} style={{ color: live ? "#15803D" : "var(--fg-3)", flexShrink: 0 }} />
        <span>{live ? <><b>Live mode</b> — messages send for real.</> : <><b>Simulation mode</b> — approved messages are recorded, not sent.</>}{failed > 0 ? ` ${failed} failed send${failed === 1 ? "" : "s"} in the last 24h ${failed === 1 ? "is" : "are"} in the retry queue.` : ""}</span>
      </div>
      {connectOpen && <ConnectLinesModal onClose={() => { setConnectOpen(false); refresh(); }} onChanged={refresh} />}
    </div>
  );
}

function WhatsAppSettings() {
  return (
    <div className="col" style={{ gap: 16 }}>
      <ProviderStatusCard />
      <WhatsAppLinesCard />
      <LineHealthCard />
    </div>
  );
}

/* ---- Line health monitoring (Phase 8) -------------------------------- */
function LineHealthCard() {
  const [lines, setLines] = React.useState(null);
  React.useEffect(() => {
    let on = true;
    const load = () => API.whatsapp.linesHealth().then((d) => { if (on) setLines(d.lines || []); }).catch(() => {});
    load(); const t = setInterval(load, 15000);
    return () => { on = false; clearInterval(t); };
  }, []);
  if (!lines) return null;
  const riskTone = { high: "red", elevated: "orange", low: "green" };
  const warnTone = { critical: "red", warning: "orange", ok: "green", disconnected: "neutral" };
  return (
    <Card title="Line health" action={<Badge tone="neutral">Live</Badge>}>
      <div className="muted" style={{ fontSize: 12.5, marginBottom: 12 }}>Per-line monitoring — connection, volume, reconnects and ban-risk indicators.</div>
      {!lines.length ? (
        <div className="muted" style={{ fontSize: 13 }}>No lines yet. Add and connect a WhatsApp line above to see its health here.</div>
      ) : (
        <div className="col" style={{ gap: 10 }}>
          {lines.map((l) => (
            <div key={l.id} style={{ border: "1px solid var(--border-1)", borderRadius: 12, padding: "12px 14px" }}>
              <div className="between" style={{ marginBottom: 8 }}>
                <div className="row" style={{ gap: 8 }}>
                  <b style={{ fontSize: 13.5 }}>{l.label}</b>
                  {l.phoneNumber ? <span className="muted" style={{ fontSize: 12 }}>+{l.phoneNumber}</span> : null}
                  <Badge tone={l.status === "connected" ? "green" : "neutral"}>{l.status}</Badge>
                </div>
                <div className="row" style={{ gap: 6 }}>
                  <Badge tone={warnTone[l.warningLevel] || "neutral"}>{l.warningLevel}</Badge>
                  <Badge tone={riskTone[l.banRisk] || "neutral"}>ban risk: {l.banRisk}</Badge>
                </div>
              </div>
              <div className="row wrap" style={{ gap: 16, fontSize: 12, color: "var(--fg-3)" }}>
                <span>Sent <b style={{ color: "var(--fg-1)" }}>{l.messagesSent}</b></span>
                <span>Received <b style={{ color: "var(--fg-1)" }}>{l.messagesReceived}</b></span>
                <span>Today <b style={{ color: "var(--fg-1)" }}>{l.sentToday}/{l.dailyLimit}</b> ({l.utilization}%)</span>
                <span>Reconnects <b style={{ color: "var(--fg-1)" }}>{l.reconnectCount}</b></span>
                <span>Health <b style={{ color: "var(--fg-1)" }}>{l.healthScore}</b></span>
              </div>
              {l.banRiskReasons && l.banRiskReasons.length ? <div style={{ marginTop: 6, fontSize: 11.5, color: "#B45309" }}>⚠ {l.banRiskReasons.join(" · ")}</div> : null}
            </div>
          ))}
        </div>
      )}
    </Card>
  );
}

/* ============================ AI PROVIDERS ============================== */
const PROVIDER_LABELS = { anthropic: "Anthropic Claude", openai: "OpenAI", deepseek: "DeepSeek", gemini: "Google Gemini" };
const AI_TASKS = [["reasoning", "Premium reasoning"], ["draft", "Sales copy / drafting"], ["fast", "Fast qualification"], ["cheap", "Low-cost batch"]];

function ProviderCard({ p, active, onChanged, onActive }) {
  const data = useStore();
  const provider = p.provider;
  const [key, setKey] = useState("");
  const [busy, setBusy] = useState("");
  const [test, setTest] = useState(null);
  const [discovered, setDiscovered] = useState(null);
  const selected = (data.SETTINGS?.aiModels || {})[provider] || {};
  const [models, setModels] = useState(() => ({ ...p.recommended, ...selected }));
  const dirty = AI_TASKS.some(([t]) => (models[t] || "") !== ((selected[t] || p.recommended[t]) || ""));

  const saveKey = () => { if (!key.trim()) return; setBusy("save"); API.ai.saveKey(provider, key.trim()).then(() => { setKey(""); onChanged(); }).catch((e) => setTest({ error: e.message })).finally(() => setBusy("")); };
  const clearKey = () => { setBusy("clear"); API.ai.clearKey(provider).then(onChanged).catch((e) => console.error(e)).finally(() => setBusy("")); };
  const runTest = () => { setBusy("test"); setTest(null); API.ai.testProvider(provider, models.draft).then(setTest).catch((e) => setTest({ live: false, error: e.message })).finally(() => { setBusy(""); onChanged(); }); };
  const discover = () => { setBusy("models"); API.ai.models(provider).then((r) => setDiscovered(r)).catch(() => setDiscovered({ models: [], error: "list failed" })).finally(() => setBusy("")); };
  const saveModels = () => { setBusy("savemodels"); const next = { ...(data.SETTINGS?.aiModels || {}), [provider]: models }; Actions.updateSettings({ aiModels: next }).catch((e) => console.error(e)).finally(() => setBusy("")); };

  return (
    <Card title={PROVIDER_LABELS[provider]} action={
      <div className="row" style={{ gap: 8 }}>
        {active && <Badge tone="dark">Active</Badge>}
        <Badge tone={p.configured ? "green" : "neutral"} dot={p.configured ? "#22C55E" : "#9CA3AF"}>{p.configured ? `key set · ${p.source}` : "no key"}</Badge>
        {!active && p.configured && <button className="btn btn--ghost btn--sm" onClick={() => onActive(provider)}>Make active</button>}
      </div>
    }>
      {/* key management — never displays the saved key */}
      <Field label="API key" hint={p.configured ? `Saved · ends …${p.last4 || ""} · source: ${p.source}. Enter a new key to replace.` : "Paste the provider API key. Stored encrypted on the server — never sent back to the browser."}>
        <div className="row" style={{ gap: 8 }}>
          <input className="input" type="password" placeholder={p.configured ? "•••••••• (saved)" : "sk-…"} value={key} onChange={(e) => setKey(e.target.value)} style={{ flex: 1 }} />
          <Button variant="dark" size="sm" icon="check" disabled={!key.trim() || busy === "save"} onClick={saveKey}>{busy === "save" ? "Saving…" : "Save"}</Button>
          {p.configured && p.source === "settings" && <Button variant="ghost" size="sm" disabled={busy === "clear"} onClick={clearKey}>Clear</Button>}
        </div>
      </Field>

      {/* per-task model selection */}
      <div className="field__label" style={{ marginBottom: 6 }}>Models by task</div>
      <div className="grid" style={{ gridTemplateColumns: "1fr 1fr", gap: 8, marginBottom: 10 }}>
        {AI_TASKS.map(([t, label]) => (
          <div key={t}>
            <div style={{ fontSize: 11, color: "var(--fg-4)", marginBottom: 2 }}>{label}</div>
            <input className="input" style={{ height: 36, fontSize: 12.5, fontFamily: "monospace" }} value={models[t] || ""} placeholder={p.recommended[t] || ""} onChange={(e) => setModels({ ...models, [t]: e.target.value })} list={`models-${provider}`} />
          </div>
        ))}
      </div>
      {discovered && <datalist id={`models-${provider}`}>{(discovered.models || []).map((m) => <option key={m} value={m} />)}</datalist>}
      <div className="row wrap" style={{ gap: 8, marginBottom: discovered ? 8 : 0 }}>
        <Button variant="subtle" size="sm" icon="check" disabled={!dirty || busy === "savemodels"} onClick={saveModels}>{busy === "savemodels" ? "Saving…" : "Save models"}</Button>
        <button className="btn btn--ghost btn--sm" disabled={busy === "models"} onClick={discover}><Icon name="layers" size={14} />{busy === "models" ? "Discovering…" : "Discover available models"}</button>
        <button className="btn btn--ghost btn--sm" onClick={() => setModels({ ...p.recommended })}><Icon name="refresh" size={14} />Recommended</button>
        <button className="btn btn--ghost btn--sm" disabled={!p.configured || busy === "test"} onClick={runTest}><Icon name="zap" size={14} />{busy === "test" ? "Testing…" : "Test connection"}</button>
      </div>
      {discovered && <div style={{ fontSize: 11.5, color: "var(--fg-4)", marginTop: 6 }}>{discovered.source === "live" ? `${(discovered.models || []).length} models available for this account` : "Couldn't list live models — showing recommended. " + (discovered.error || "")}</div>}
      {(test || p.lastTestedAt) && (
        <div className="row" style={{ gap: 8, marginTop: 10, padding: "10px 12px", borderRadius: 10, background: (test ? test.live : p.live) ? "var(--color-success-soft)" : "var(--color-danger-soft)", color: (test ? test.live : p.live) ? "#15803D" : "var(--color-danger)", fontSize: 12.5 }}>
          <Icon name={(test ? test.live : p.live) ? "checkcircle" : "alert"} size={15} />
          {test
            ? (test.live ? `Live · ${test.modelUsed || test.model} · ${test.latencyMs}ms` : `Failed: ${test.error || "no response"}`)
            : (p.live ? `Last test live · ${new Date(p.lastTestedAt).toLocaleString()}` : `Last test failed: ${p.error || "—"}`)}
        </div>
      )}
    </Card>
  );
}

function AiSettings() {
  const data = useStore();
  const [dir, setDir] = useState(null); // /ai/providers directory
  const [loading, setLoading] = useState(true);
  const refresh = () => { setLoading(true); API.ai.providers().then(setDir).catch((e) => console.error("ai providers failed", e)).finally(() => setLoading(false)); };
  React.useEffect(() => { refresh(); }, []);

  const live = dir ? dir.live : !!data.meta?.live;
  const active = dir?.active || data.meta?.ai?.provider || "anthropic";
  const providers = dir?.providers || [];
  const setActive = (provider) => { Actions.updateSettings({ aiActiveProvider: provider }).then(refresh).catch((e) => console.error(e)); };
  const applyMode = (mode) => {
    API.ai.recommend(active, mode).then((r) => {
      const next = { ...(data.SETTINGS?.aiModels || {}), [active]: r.models };
      return Actions.updateSettings({ aiModels: next });
    }).then(refresh).catch((e) => console.error(e));
  };

  const MEMORY_LABELS = { knowledgeBase: "Knowledge Base (global)", agentTraining: "Agent training (per-rep)", leadLevel: "Lead-level (notes/stage/follow-ups)", conversation: "Conversation history", learning: "Learning (won/lost)" };
  const memory = data.meta?.memory || {};

  // honest reason + last-checked, from the REAL probe (/ai/providers now returns these)
  const aiReason = AI_FALLBACK_REASON[dir?.lastErrorType] || (dir?.lastErrorType ? "The last health check failed" : "");
  const lastChecked = dir?.lastCheckedAt ? new Date(dir.lastCheckedAt).toLocaleTimeString() : null;
  const configuredButInvalid = !live && providers.some((p) => p.configured);
  return (
    <div className="col" style={{ gap: 16 }}>
      <FallbackBanner />
      <p className="muted" style={{ fontSize: 14, maxWidth: 520 }}>Add provider API keys, pick the best model per task, and test each connection. Keys are stored encrypted on the server and never sent to the browser. Precedence: saved key → <code style={{ fontFamily: "monospace" }}>.env</code> → fallback templates.</p>

      <Card>
        <div className="between">
          <div className="row" style={{ gap: 14 }}>
            <span className="opp" style={{ width: 44, height: 44, borderRadius: 12, background: live ? "var(--color-primary-tint-soft)" : "var(--color-orange-soft)", color: live ? "var(--color-secondary)" : "var(--color-orange)" }}><Icon name="sparkles" size={22} /></span>
            <div>
              <div style={{ fontWeight: 700 }}>{live ? `Live — ${PROVIDER_LABELS[active] || active}` : (configuredButInvalid ? "Fallback mode — provider key not valid" : "Fallback mode — grounded templates")}</div>
              <div style={{ fontSize: 12.5, color: "var(--fg-4)", maxWidth: 480 }}>{live ? "Verified by a real provider call — drafts and replies are model-generated." : (configuredButInvalid ? `${aiReason}. Replies use deterministic templates until a key passes the health check. Save/Test a key below.` : "No API key set — the Dynamic Workflow uses deterministic on-brand templates. Fully functional with no key.")}{lastChecked ? ` · Last checked ${lastChecked}` : ""}</div>
            </div>
          </div>
          <div className="row" style={{ gap: 10 }}>
            <Badge tone={live ? "green" : "orange"} dot={live ? "#22C55E" : "#EA580C"}>{live ? "Live" : "Fallback"}</Badge>
            <button className="btn btn--ghost btn--sm" onClick={refresh} disabled={loading}><Icon name="refresh" size={14} />{loading ? "…" : "Re-check"}</button>
          </div>
        </div>
        <div className="row wrap" style={{ gap: 8, marginTop: 14, alignItems: "center" }}>
          <span className="subtle" style={{ fontSize: 12, marginInlineEnd: 4 }}>Apply to {PROVIDER_LABELS[active] || active}:</span>
          <button className="btn btn--ghost btn--sm" onClick={() => applyMode("premium")}><Icon name="trophy" size={14} />Premium mode</button>
          <button className="btn btn--ghost btn--sm" onClick={() => applyMode("low")}><Icon name="zap" size={14} />Low-cost mode</button>
          <button className="btn btn--ghost btn--sm" onClick={() => applyMode("default")}><Icon name="refresh" size={14} />Recommended defaults</button>
        </div>
      </Card>

      {loading && !dir ? <Card><div className="skel" style={{ height: 80, borderRadius: 10 }} /></Card>
        : providers.map((p) => <ProviderCard key={p.provider} p={p} active={p.provider === active} onChanged={refresh} onActive={setActive} />)}

      <Card title="Memory systems">
        <div className="row wrap" style={{ gap: 8, marginTop: 4 }}>
          {Object.keys(MEMORY_LABELS).map((k) => (
            <Badge key={k} tone={memory[k] ? "green" : "neutral"} dot={memory[k] ? "#22C55E" : "#9CA3AF"}>{MEMORY_LABELS[k]}{memory[k] ? "" : " · off"}</Badge>
          ))}
        </div>
        <div style={{ fontSize: 12, color: "var(--fg-4)", marginTop: 10, lineHeight: 1.5 }}>Agents read the global Knowledge Base and the assigned rep's training on every run, and learn from won/lost outcomes. Only the <b>Content</b> step calls a live LLM; the other 7 agents run as deterministic logic (and fall back to templates with no key).</div>
      </Card>

      <div className="row" style={{ gap: 10, background: "var(--color-blue-soft)", border: "1px solid #DBEAFE", borderRadius: 12, padding: 14, color: "var(--color-blue)", alignItems: "flex-start" }}>
        <Icon name="shield" size={18} style={{ flexShrink: 0, marginTop: 1 }} />
        <span style={{ fontSize: 13, color: "var(--fg-2)", lineHeight: 1.5 }}>You can add keys here, or set <code style={{ fontFamily: "monospace" }}>ANTHROPIC_API_KEY</code> / <code style={{ fontFamily: "monospace" }}>OPENAI_API_KEY</code> / <code style={{ fontFamily: "monospace" }}>GEMINI_API_KEY</code> / <code style={{ fontFamily: "monospace" }}>DEEPSEEK_API_KEY</code> in the server <code style={{ fontFamily: "monospace" }}>.env</code>. A saved key here overrides the matching <code style={{ fontFamily: "monospace" }}>.env</code> key. With no key, everything keeps working in fallback mode.</span>
      </div>
    </div>
  );
}

/* ============================ TEAM ===================================== */
const ROLE_OPTS = ["Owner", "Admin", "Operator", "Viewer"];
const CURRENT_EMAIL = "yahia@maxabhub.com";
function nameFromEmail(email) {
  const local = (email.split("@")[0] || "").replace(/[._-]+/g, " ").trim();
  return local.split(" ").filter(Boolean).map((w) => w[0].toUpperCase() + w.slice(1)).join(" ") || email;
}
function InviteModal({ onClose, onInvite, busy }) {
  const [email, setEmail] = useState("");
  const [role, setRole] = useState("Operator");
  return (
    <Modal onClose={onClose} style={{ width: 440 }}>
      <MHead title="Invite a teammate" sub="Adds them to your Maxab Hub team" onClose={onClose} />
      <div style={{ padding: 22 }}>
        <Field label="Work email"><input className="input" autoFocus type="email" placeholder="name@maxabhub.com" value={email} onChange={(e) => setEmail(e.target.value)} /></Field>
        <Field label="Role" hint="Operators run campaigns. Admins also manage settings and billing.">
          <select className="select" value={role} onChange={(e) => setRole(e.target.value)}>{ROLE_OPTS.map((r) => <option key={r}>{r}</option>)}</select>
        </Field>
        <div className="row" style={{ gap: 10, justifyContent: "flex-end", marginTop: 8 }}>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button variant="primary" icon="send" disabled={!email.trim() || busy} onClick={() => onInvite({ email: email.trim(), role })}>{busy ? "Sending…" : "Send invite"}</Button>
        </div>
      </div>
    </Modal>
  );
}
function MemberModal({ member, onClose, onSave, onRemove, busy }) {
  const [role, setRole] = useState(member.role);
  const [defaultSession, setDefaultSession] = useState(member.defaultSession || "");
  const isYou = member.email === CURRENT_EMAIL;
  return (
    <Modal onClose={onClose} style={{ width: 440 }}>
      <MHead title={"Edit " + member.name} sub={member.email} onClose={onClose} />
      <div style={{ padding: 22 }}>
        <div className="row" style={{ gap: 12, marginBottom: 16 }}>
          <Avatar name={member.name} size="lg" />
          <div><div style={{ fontWeight: 700 }}>{member.name}</div><div style={{ fontSize: 12.5, color: "var(--fg-4)" }}>{member.email}</div></div>
        </div>
        <Field label="Role"><select className="select" value={role} onChange={(e) => setRole(e.target.value)}>{ROLE_OPTS.map((r) => <option key={r}>{r}</option>)}</select></Field>
        <Field label="Default WhatsApp line"><select className="select" value={defaultSession} onChange={(e) => setDefaultSession(e.target.value)}><option value="">No default</option>{(DATA.SESSIONS || []).map((s) => <option key={s.id} value={s.id}>{s.label}</option>)}</select></Field>
        <div className="row" style={{ gap: 10, justifyContent: "space-between", marginTop: 14 }}>
          <button className="btn btn--ghost btn--sm" disabled={busy || isYou} title={isYou ? "You can't remove yourself" : undefined} style={{ color: "var(--color-danger)", borderColor: "var(--color-danger-soft)", opacity: isYou ? 0.5 : 1 }} onClick={() => onRemove(member.id)}><Icon name="trash" size={15} />Remove from team</button>
          <div className="row" style={{ gap: 10 }}>
            <Button variant="ghost" onClick={onClose}>Cancel</Button>
            <Button variant="primary" icon="check" disabled={busy} onClick={() => onSave(member.id, { role, defaultSession })}>{busy ? "Saving…" : "Save"}</Button>
          </div>
        </div>
      </div>
    </Modal>
  );
}
function UsersSettings() {
  const data = useStore();
  const team = data.SETTINGS?.team || [];
  const [invite, setInvite] = useState(false);
  const [edit, setEdit] = useState(null);
  const [busy, setBusy] = useState(false);

  const persist = (nextTeam) => {
    setBusy(true);
    return Actions.updateSettings({ team: nextTeam })
      .catch((e) => { console.error("team save failed", e); })
      .finally(() => setBusy(false));
  };
  const invitePerson = ({ email, role }) => {
    if (team.some((m) => m.email.toLowerCase() === email.toLowerCase())) { setInvite(false); return; }
    const member = { id: "u_" + Math.random().toString(36).slice(2, 8), name: nameFromEmail(email), email, role };
    persist([...team, member]).then(() => setInvite(false));
  };
  const saveMember = (id, patch) => persist(team.map((m) => (m.id === id ? { ...m, ...patch } : m))).then(() => setEdit(null));
  const removeMember = (id) => persist(team.filter((m) => m.id !== id)).then(() => setEdit(null));

  return (
    <Card flush>
      <div className="between" style={{ padding: 20 }}>
        <b>Team members</b><Button variant="ghost" size="sm" icon="plus" onClick={() => setInvite(true)}>Invite</Button>
      </div>
      <table className="table">
        <thead><tr><th>Member</th><th>Email</th><th>Role</th><th></th></tr></thead>
        <tbody>{team.map((m) => {
          const you = m.email === CURRENT_EMAIL;
          const dark = m.role === "Owner" || m.role === "Admin";
          return (
            <tr key={m.id || m.email} style={{ cursor: "pointer" }} onClick={() => setEdit(m)}>
              <td><div className="row" style={{ gap: 10 }}><Avatar name={m.name} size="sm" /><b style={{ fontSize: 14 }}>{m.name}{you && <span className="subtle" style={{ fontWeight: 400 }}> (you)</span>}</b></div></td>
              <td style={{ color: "var(--fg-3)" }}>{m.email}</td>
              <td><Badge tone={dark ? "dark" : "neutral"}>{m.role}</Badge></td>
              <td style={{ textAlign: "end" }}><button className="iconbtn" style={{ width: 32, height: 32 }} onClick={(e) => { e.stopPropagation(); setEdit(m); }}><Icon name="moreV" size={16} /></button></td>
            </tr>
          );
        })}</tbody>
      </table>
      {invite && <InviteModal onClose={() => setInvite(false)} onInvite={invitePerson} busy={busy} />}
      {edit && <MemberModal member={edit} onClose={() => setEdit(null)} onSave={saveMember} onRemove={removeMember} busy={busy} />}
    </Card>
  );
}

/* ============================ BRAND ==================================== */
function LogoModal({ onClose }) {
  const data = useStore();
  const brand = data.SETTINGS?.brand || {};
  const [preview, setPreview] = useState(brand.logo || "");
  const [fileName, setFileName] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState(null);
  const fileRef = React.useRef(null);

  const onFile = (file) => {
    if (!file) return;
    if (!/^image\/(png|svg\+xml|jpeg|webp)$/.test(file.type)) { setErr("Please choose a PNG, SVG, JPG or WebP image."); return; }
    if (file.size > 512 * 1024) { setErr("Image is larger than 512KB — please use a smaller file."); return; }
    setErr(null); setFileName(file.name);
    const reader = new FileReader();
    reader.onload = () => setPreview(String(reader.result || ""));
    reader.onerror = () => setErr("Could not read that file.");
    reader.readAsDataURL(file);
  };
  const useLogo = () => {
    if (!preview) return;
    setBusy(true); setErr(null);
    Actions.updateSettings({ brand: { ...brand, logo: preview } }).then(onClose).catch((e) => setErr(e.message || "Save failed")).finally(() => setBusy(false));
  };

  return (
    <Modal onClose={onClose} style={{ width: 460 }}>
      <MHead title="Replace logo" sub="PNG, SVG, JPG or WebP · under 512KB" onClose={onClose} />
      <div style={{ padding: 22 }}>
        <input ref={fileRef} type="file" accept="image/png,image/svg+xml,image/jpeg,image/webp" style={{ display: "none" }} onChange={(e) => onFile(e.target.files && e.target.files[0])} />
        <button onClick={() => fileRef.current && fileRef.current.click()} style={{ width: "100%", border: "2px dashed " + (preview ? "var(--color-secondary)" : "var(--border-2)"), borderRadius: 16, padding: "28px 20px", background: preview ? "var(--color-primary-tint-soft)" : "var(--bg-2)", textAlign: "center", color: "var(--fg-3)" }}>
          {preview ? <><img src={preview} alt="logo preview" style={{ maxHeight: 60, maxWidth: 180, objectFit: "contain" }} /><div style={{ fontWeight: 700, color: "var(--fg-1)", marginTop: 10 }}>{fileName || "Current logo"}</div><div style={{ fontSize: 12, marginTop: 4 }}>Click to choose a different file</div></>
            : <><Icon name="image" size={30} /><div style={{ fontWeight: 700, color: "var(--fg-1)", marginTop: 10 }}>Click to choose a logo</div><div style={{ fontSize: 12, marginTop: 4 }}>PNG, SVG, JPG or WebP</div></>}
        </button>
        {err && <div className="row" style={{ gap: 8, marginTop: 12, color: "var(--color-danger)", fontSize: 12.5 }}><Icon name="alert" size={14} />{err}</div>}
        <div className="row" style={{ gap: 10, justifyContent: "flex-end", marginTop: 16 }}>
          <Button variant="ghost" onClick={onClose}>Cancel</Button>
          <Button variant="primary" icon="check" disabled={!preview || busy} onClick={useLogo}>{busy ? "Saving…" : "Use logo"}</Button>
        </div>
      </div>
    </Modal>
  );
}
const TONE_OPTS = ["Saudi professional", "Saudi friendly", "GCC neutral", "Premium Arabic", "English simple"];
function BrandSettings() {
  const data = useStore();
  const brand = data.SETTINGS?.brand || {};
  const [logoOpen, setLogoOpen] = useState(false);
  const [name, setName] = useState("");
  const [signature, setSignature] = useState("");
  const [site, setSite] = useState("");
  const [tone, setTone] = useState("Saudi professional");
  const [from, setFrom] = useState("09:00");
  const [to, setTo] = useState("20:00");
  const [saving, setSaving] = useState(false);
  const [saved, setSaved] = useState(false);

  React.useEffect(() => {
    setName(brand.name || "");
    setSignature(brand.signature || "Maxab Hub · ecommerce solutions");
    setSite(brand.site || "");
    setTone(brand.defaultTone || "Saudi professional");
    setFrom(brand.hours?.from || "09:00");
    setTo(brand.hours?.to || "20:00");
  }, [brand.name, brand.signature, brand.site, brand.defaultTone, brand.hours?.from, brand.hours?.to]);

  const save = () => {
    setSaving(true); setSaved(false);
    Actions.updateSettings({ brand: { ...brand, name: name.trim(), signature, site: site.trim(), defaultTone: tone, hours: { from, to } } })
      .then(() => { setSaved(true); setTimeout(() => setSaved(false), 1600); })
      .catch((e) => console.error("brand save failed", e))
      .finally(() => setSaving(false));
  };

  return (
    <div className="col" style={{ gap: 16 }}>
      <Card title="Brand">
        <div className="row" style={{ gap: 16, marginBottom: 16 }}>
          <div style={{ width: 120, height: 64, borderRadius: 12, background: "var(--bg-2)", display: "flex", alignItems: "center", justifyContent: "center", padding: 12 }}>
            <img src={brand.logo || "assets/logo-dark.png"} style={{ maxWidth: "100%", maxHeight: "100%" }} alt="logo" />
          </div>
          <Button variant="ghost" size="sm" icon="upload" onClick={() => setLogoOpen(true)}>Replace logo</Button>
        </div>
        <Field label="Company name"><input className="input" value={name} onChange={(e) => setName(e.target.value)} /></Field>
        <Field label="Default sender signature"><input className="input" value={signature} onChange={(e) => setSignature(e.target.value)} /></Field>
        <Field label="Website"><input className="input" value={site} onChange={(e) => setSite(e.target.value)} placeholder="https://maxabhub.com" /></Field>
      </Card>
      <Card title="Outreach defaults">
        <Field label="Default tone" hint="Agents can override per campaign.">
          <select className="select" value={tone} onChange={(e) => setTone(e.target.value)}>{TONE_OPTS.map((o) => <option key={o}>{o}</option>)}</select>
        </Field>
        <Field label="Working hours" hint="Agents only send inside these hours, per contact's timezone.">
          <div className="row" style={{ gap: 10 }}><input className="input" value={from} onChange={(e) => setFrom(e.target.value)} /><span className="muted">to</span><input className="input" value={to} onChange={(e) => setTo(e.target.value)} /></div>
        </Field>
      </Card>
      <div className="row" style={{ gap: 12, justifyContent: "flex-end", alignItems: "center" }}>
        {saved && <span className="row" style={{ gap: 6, color: "var(--color-success)", fontSize: 13, fontWeight: 600 }}><Icon name="checkcircle" size={16} />Saved</span>}
        <Button variant="primary" icon="check" disabled={saving || !name.trim()} onClick={save}>{saving ? "Saving…" : "Save brand"}</Button>
      </div>
      {logoOpen && <LogoModal onClose={() => setLogoOpen(false)} />}
    </div>
  );
}

/* ============================ LEAD STATUSES ============================ */
const STAGE_PALETTE = ["#9CA3AF", "#6B7280", "#2563EB", "#0891B2", "#0D9488", "#7E22CE", "#4F46E5", "#BE185D", "#DB2777", "#4A6400", "#22C55E", "#15803D", "#EA580C", "#F59E0B", "#B91C1C"];
function StageColorPicker({ color, onChange }) {
  const [open, setOpen] = useState(false);
  return (
    <div style={{ position: "relative", flexShrink: 0 }}>
      <button onClick={() => setOpen((o) => !o)} title="Choose color"
        style={{ display: "flex", alignItems: "center", gap: 8, height: 38, padding: "0 10px", borderRadius: "var(--radius-sm)", border: "1px solid var(--border-2)", background: "#fff", cursor: "pointer" }}>
        <span style={{ width: 20, height: 20, borderRadius: 999, background: color, boxShadow: "inset 0 0 0 1px rgba(0,0,0,.08)" }} />
        <Icon name="chevronDown" size={14} style={{ color: "var(--fg-4)" }} />
      </button>
      {open && <>
        <div style={{ position: "fixed", inset: 0, zIndex: 1 }} onClick={() => setOpen(false)} />
        <div style={{ position: "absolute", top: 44, insetInlineStart: 0, zIndex: 2, background: "#fff", border: "1px solid var(--border-1)", borderRadius: "var(--radius-md)", boxShadow: "var(--shadow-lg)", padding: 12, width: 208 }}>
          <div style={{ fontSize: 11, fontWeight: 700, color: "var(--fg-4)", textTransform: "uppercase", letterSpacing: ".04em", marginBottom: 8 }}>Palette</div>
          <div style={{ display: "grid", gridTemplateColumns: "repeat(5,1fr)", gap: 8 }}>
            {STAGE_PALETTE.map((c) => (
              <button key={c} onClick={() => { onChange(c); setOpen(false); }} title={c}
                style={{ width: 28, height: 28, borderRadius: 999, background: c, border: "2px solid " + (color === c ? "var(--fg-1)" : "transparent"), cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center", color: "#fff" }}>
                {color === c && <Icon name="check" size={14} />}
              </button>
            ))}
          </div>
        </div>
      </>}
    </div>
  );
}
const SYSTEM_STATUS = ["new", "won", "lost"];
function stagesFromSettings(statuses, t) {
  return (statuses || []).map((s) => {
    if (typeof s === "string") {
      const meta = (typeof STATUS_META !== "undefined" && STATUS_META[s]) || null;
      return { id: s, label: meta ? t(meta.key) : s, color: meta?.color || "#6B7280", locked: SYSTEM_STATUS.includes(s) };
    }
    return { id: s.id, label: s.label, color: s.color, locked: SYSTEM_STATUS.includes(s.id) };
  });
}
function StatusSettings() {
  const { t } = useLang();
  const data = useStore();
  const settingsStatuses = data.SETTINGS?.statuses;
  const [stages, setStages] = useState(() => stagesFromSettings(settingsStatuses, t));
  const [saving, setSaving] = useState(false);
  const [saved, setSaved] = useState(false);
  React.useEffect(() => { setStages(stagesFromSettings(settingsStatuses, t)); }, [settingsStatuses]);

  const update = (i, v) => setStages((s) => s.map((x, idx) => idx === i ? v : x));
  const remove = (i) => setStages((s) => s.filter((_, idx) => idx !== i));
  const add = () => setStages((s) => [...s.slice(0, s.length - 1), { id: "s" + Date.now(), label: "New status", color: STAGE_PALETTE[s.length % STAGE_PALETTE.length] }, s[s.length - 1]]);
  const save = () => {
    setSaving(true); setSaved(false);
    Actions.updateSettings({ statuses: stages.map(({ id, label, color }) => ({ id, label, color })) })
      .then(() => { setSaved(true); setTimeout(() => setSaved(false), 1600); })
      .catch((e) => console.error("statuses save failed", e))
      .finally(() => setSaving(false));
  };

  return (
    <div className="col" style={{ gap: 16 }}>
      <p className="muted" style={{ fontSize: 14, maxWidth: 520 }}>These are the stages shown on every contact and in the Contacts filters. Rename them, recolor them, or add your own — saved to your workspace.</p>
      <Card flush>
        <div className="between" style={{ padding: "16px 20px", borderBottom: "1px solid var(--border-1)" }}>
          <b>Pipeline stages</b><span className="subtle" style={{ fontSize: 12 }}>{stages.length} stages</span>
        </div>
        {stages.map((st, i) => (
          <div key={st.id} className="row" style={{ gap: 12, padding: "12px 20px", borderBottom: "1px solid var(--border-1)" }}>
            <Icon name="menu" size={16} style={{ color: "var(--fg-disabled)", cursor: "grab", flexShrink: 0 }} />
            <StageColorPicker color={st.color} onChange={(c) => update(i, { ...st, color: c })} />
            <input className="input" value={st.label} onChange={(e) => update(i, { ...st, label: e.target.value })} style={{ height: 38, flex: 1 }} />
            {st.locked
              ? <Badge tone="neutral">System</Badge>
              : <button className="iconbtn" style={{ width: 32, height: 32, color: "var(--fg-4)" }} onClick={() => remove(i)}><Icon name="trash" size={15} /></button>}
          </div>
        ))}
        <div style={{ padding: 16 }}><Button variant="ghost" icon="plus" onClick={add}>Add a stage</Button></div>
      </Card>
      <div className="row" style={{ gap: 12, justifyContent: "flex-end", alignItems: "center" }}>
        {saved && <span className="row" style={{ gap: 6, color: "var(--color-success)", fontSize: 13, fontWeight: 600 }}><Icon name="checkcircle" size={16} />Saved</span>}
        <Button variant="ghost" onClick={() => setStages(stagesFromSettings(settingsStatuses, t))} disabled={saving}>Reset</Button>
        <Button variant="primary" icon="check" onClick={save} disabled={saving}>{saving ? "Saving…" : "Save pipeline"}</Button>
      </div>
    </div>
  );
}

function SettingsScreen() {
  const [tab, setTab] = useState("whatsapp");
  return (
    <div className="content__inner fade-up">
      <div className="row wrap" style={{ gap: 4, marginBottom: 24, borderBottom: "1px solid var(--border-1)" }}>
        {SETTINGS_TABS.map((t) => (
          <button key={t.key} onClick={() => setTab(t.key)} className="row" style={{ gap: 8, padding: "12px 14px", fontSize: 14, fontWeight: 600,
            color: tab === t.key ? "var(--color-secondary)" : "var(--fg-3)", borderBottom: "2px solid " + (tab === t.key ? "var(--color-secondary)" : "transparent"), marginBottom: -1 }}>
            <Icon name={t.icon} size={16} />{t.label}
          </button>
        ))}
      </div>
      <div style={{ maxWidth: 720 }}>
        {tab === "whatsapp" && <WhatsAppSettings />}
        {tab === "automation" && <AutomationSettings />}
        {tab === "statuses" && <StatusSettings />}
        {tab === "ai" && <AiSettings />}
        {tab === "users" && <UsersSettings />}
        {tab === "brand" && <BrandSettings />}
      </div>
    </div>
  );
}

window.SettingsScreen = SettingsScreen;
