// screens-opportunities.jsx — the Opportunity PIPELINE (production).
//
// An opportunity is now a REAL persisted record (DATA.OPPORTUNITIES), not a derived
// card. It is the central sales spine: linked to a contact + conversation + agent,
// with a lifecycle (new → in_review → contacted → meeting_scheduled → proposal_sent →
// won/lost), an activity timeline, and linked meetings / proposals / custom requests /
// follow-ups. Every action persists through real Actions (Actions.createOpportunity,
// setOpportunityStatus, assignOpportunity, addOpportunityMeeting/Proposal/FollowUp/Request,
// deleteOpportunity) and refreshes the related screens. Nothing here is derived or fake.
const { useState: useOppState } = React;
const oppT = (lang, ar, en) => (lang === "ar" ? ar : en);

// Backend-aligned lifecycle (matches server/sales/opportunity.js OPP_STATUSES).
const OPP_STATUSES = {
  new:               { en: "New", ar: "جديدة", tone: "blue", c: "#2563EB" },
  in_review:         { en: "In Review", ar: "قيد المراجعة", tone: "purple", c: "#7E22CE" },
  contacted:         { en: "Contacted", ar: "تم التواصل", tone: "blue", c: "#0891B2" },
  meeting_scheduled: { en: "Meeting Scheduled", ar: "تم تحديد اجتماع", tone: "lime", c: "#4A6400" },
  proposal_sent:     { en: "Proposal Sent", ar: "تم إرسال العرض", tone: "orange", c: "#EA580C" },
  won:               { en: "Won", ar: "تم الفوز", tone: "green", c: "#22C55E" },
  lost:              { en: "Lost", ar: "خاسرة", tone: "red", c: "#B91C1C" },
};
const OPP_ORDER = ["new", "in_review", "contacted", "meeting_scheduled", "proposal_sent", "won", "lost"];
const OPEN_STAGES = ["new", "in_review", "contacted", "meeting_scheduled", "proposal_sent"];
const SERVICE_LABEL = { web_design: "Web design", shopify_design: "Shopify store", salla_design: "Salla store", automation: "Automation", whatsapp_agent: "WhatsApp agent", seo: "SEO", maxab_hub: "maxab.ai", ai_services: "AI services", app_sub: "App subscription" };
// Customer-interest tags for follow-ups (mirrors server INTERESTS).
const INTEREST_OPTS = [
  ["hot", "Hot lead", "عميل ساخن"], ["warm", "Warm lead", "عميل دافئ"], ["cold", "Cold lead", "عميل بارد"],
  ["asked_price", "Asked for price", "طلب السعر"], ["asked_meeting", "Asked for a meeting", "طلب اجتماعاً"],
  ["waiting_decision", "Waiting for decision", "ينتظر القرار"], ["needs_request", "Needs custom request", "يحتاج طلباً مخصصاً"], ["asked_proposal", "Asked for a proposal", "طلب عرضاً"],
];

// Next-Best-Action labels (the action keys returned by the NBA engine).
const NBA_LABELS = {
  follow_up: ["Follow up now", "تابع الآن"], follow_up_proposal: ["Follow up on the proposal", "تابع العرض المُرسل"],
  close_won: ["Close — send the payment link", "أغلق — أرسل رابط الدفع"], send_proposal: ["Send a proposal", "أرسل عرضاً"],
  confirm_meeting: ["Confirm the meeting", "أكّد الاجتماع"], schedule_meeting: ["Schedule a meeting", "حدّد اجتماعاً"],
  reengage: ["Re-engage the lead", "أعد إشراك العميل"], start_outreach: ["Start outreach", "ابدأ التواصل"],
};
function NBA_LABEL(action, lang) { const m = NBA_LABELS[action] || [action, action]; return lang === "ar" ? m[1] : m[0]; }
// Phase 3 — Maxab AI product type labels (mirror server PRODUCT_TYPES).
const PRODUCT_LABELS = {
  ai_sub: ["AI Sales Agent Subscription", "اشتراك وكيل المبيعات"], source_code: ["AI Sales Agent Source Code", "الكود المصدري"],
  private_deploy: ["Private Deployment", "نشر خاص"], white_label: ["White Label", "نسخة بعلامتك"], support_pkg: ["Support Package", "باقة دعم"],
  shopify_design: ["Shopify Design", "تصميم شوبيفاي"], web_design: ["Website Design", "تصميم موقع"], salla_design: ["Salla Design", "تصميم سلة"],
  automation: ["Automation Service", "خدمة أتمتة"], maxab_hub: ["maxab.ai SaaS", "maxab.ai"],
};
function productLabel(pt, lang) {
  const m = PRODUCT_LABELS[pt];
  if (m) return lang === "ar" ? m[1] : m[0];
  // fall back to a founder-managed product's name (Control Center → Products)
  const p = ((typeof DATA !== "undefined" && DATA.MAXAB_PRODUCTS) || []).find((x) => x && x.productType === pt);
  if (p) return (lang === "ar" && p.nameAr) ? p.nameAr : (p.name || pt);
  return pt || "—";
}
// ROI Score for an opportunity — shown only when a committed (confirmed) ROI exists.
// Pending/low-confidence ROI has no score; non-ROI opportunities show nothing.
function roiScoreOf(o) {
  if (!o) return null;
  if (typeof o.roiScore === "number") return o.roiScore;
  if (o.roi && !o.roi.pendingConfirmation && typeof o.roi.roiScore === "number") return o.roi.roiScore;
  return null;
}
// Selectable product types = the built-in labels ∪ every ACTIVE managed product.
function productOpts() {
  const managed = ((typeof DATA !== "undefined" && DATA.MAXAB_PRODUCTS) || []).filter((p) => p && (p.status ? p.status === "active" : p.active !== false)).map((p) => p.productType);
  return Array.from(new Set([...Object.keys(PRODUCT_LABELS), ...managed]));
}
// Currency-aware money formatter — delegates to the shared MaxabCurrency formatter.
// `cur` is the record's currency (e.g. opportunity.currency); omitted → global default.
function fmtMoney(n, lang, cur) { return window.fmtCurrency(n, cur, lang); }
// Currency-SAFE total across records: single currency → one labelled total; mixed +
// rates configured → converted total; mixed + no rates → per-currency breakdown chips
// (never a fabricated mixed number). For an all-SAR install this is just "SAR 12,345".
function sumMoney(records, amountFn, lang) {
  const r = window.MaxabCurrency.sumSafe(records, amountFn, (o) => o.currency);
  if (r.total != null) return window.fmtCurrency(r.total, r.currency, lang);
  return Object.keys(r.byCurrency).sort().map((c) => window.fmtCurrency(r.byCurrency[c], c, lang)).join(" · ");
}
const CURRENCIES = (window.MaxabCurrency && window.MaxabCurrency.SUPPORTED) || ["SAR", "USD", "EUR", "CAD", "AED"];
const defaultCur = () => (window.MaxabCurrency && window.MaxabCurrency.defaultCurrency && window.MaxabCurrency.defaultCurrency()) || "SAR";
function CurrencySelect({ value, onChange, style }) {
  return <select className="select" value={value} onChange={(e) => onChange(e.target.value)} style={{ maxWidth: 110, ...(style || {}) }}>{CURRENCIES.map((c) => <option key={c} value={c}>{c}</option>)}</select>;
}
function svcLabel(s) { return SERVICE_LABEL[s] || (s ? String(s).replace(/_/g, " ") : "maxab.ai"); }
function statusLabel(s, lang) { const m = OPP_STATUSES[s] || OPP_STATUSES.new; return lang === "ar" ? m.ar : m.en; }
function agentById(id) { return ((window.DATA && DATA.AGENTS) || []).find((a) => a.id === id) || null; }
function contactById(id) { return ((window.DATA && DATA.CONTACTS) || []).find((c) => c.id === id) || null; }

// Live linked sub-records for an opportunity (computed from the store, always fresh).
function linkedFor(oppId) {
  const f = (coll) => ((window.DATA && DATA[coll]) || []).filter((r) => r.opportunityId === oppId);
  return { meetings: f("MEETINGS"), proposals: f("PROPOSALS"), requests: f("CUSTOM_REQUESTS"), followUps: f("FOLLOW_UPS") };
}
function liveOpps() { return ((window.DATA && DATA.OPPORTUNITIES) || []).filter((o) => !o.deletedAt); }
function opportunitiesForContact(contactId) { return liveOpps().filter((o) => o.contactId === contactId); }
window.opportunitiesForContact = opportunitiesForContact;
window.OPP_STATUSES = OPP_STATUSES;

function OppStatusBadge({ status }) {
  const { lang } = useLang();
  const m = OPP_STATUSES[status] || OPP_STATUSES.new;
  return <Badge tone={m.tone} dot={m.c}>{lang === "ar" ? m.ar : m.en}</Badge>;
}
window.OppStatusBadge = OppStatusBadge;

// Toast helper shared by the screen + drawer.
function useToast() {
  const [toast, setToast] = useOppState("");
  const flash = (m) => { setToast(m); setTimeout(() => setToast(""), 2400); };
  const node = toast ? <div className="fade-up" style={{ position: "fixed", bottom: 24, insetInlineStart: "50%", transform: "translateX(-50%)", background: "var(--color-secondary)", color: "#fff", padding: "12px 20px", borderRadius: "var(--radius-md)", boxShadow: "var(--shadow-lg)", fontSize: 13.5, fontWeight: 600, zIndex: 80, display: "flex", alignItems: "center", gap: 8 }}><Icon name="checkcircle" size={16} />{toast}</div> : null;
  return [flash, node];
}

function OpportunitiesScreen() {
  const { lang } = useLang();
  const { go } = useApp();
  const data = useStore();
  const T = (ar, en) => oppT(lang, ar, en);
  const [detailId, setDetailId] = useOppState(null);
  const [newOpen, setNewOpen] = useOppState(false);
  const [flash, toastNode] = useToast();

  const opps = liveOpps();
  const detail = detailId ? opps.find((o) => o.id === detailId) : null;
  const byStage = (s) => opps.filter((o) => o.status === s);
  const pipelineValue = opps.filter((o) => OPEN_STAGES.includes(o.status)).reduce((s, o) => s + (o.estimatedValue || 0), 0);
  const wonValue = byStage("won").reduce((s, o) => s + (o.saleValue || o.estimatedValue || 0), 0);

  return (
    <div className="content__inner content__inner--wide fade-up" style={{ maxWidth: 1480 }}>
      <div className="between wrap" style={{ marginBottom: 16, gap: 12 }}>
        <div className="col" style={{ gap: 2 }}>
          <div className="row" style={{ gap: 10 }}>
            <h4 style={{ whiteSpace: "nowrap", margin: 0 }}>{T("البيع", "Sell")}</h4>
            <span className="subtle" style={{ fontSize: 13 }}>{opps.length} {T("فرصة", "opportunities")}</span>
          </div>
          <span className="subtle" style={{ fontSize: 11.5 }}>{T("استورد ← حلّل ← قسّم ← حملة ← أطلق ← تابع ← اجتماع ← عرض ← فاتورة ← أغلق", "Import → Analyze → Segment → Campaign → Launch → Follow up → Meeting → Proposal → Invoice → Won")}</span>
        </div>
        <div className="row" style={{ gap: 10, flexWrap: "wrap" }}>
          <span className="row" style={{ gap: 6, fontSize: 12.5, color: "var(--fg-3)" }}><b style={{ color: "var(--fg-1)" }}>{sumMoney(opps.filter((o) => OPEN_STAGES.includes(o.status)), (o) => o.estimatedValue || 0, lang)}</b> {T("في الفرص", "in pipeline")}</span>
          <span className="row" style={{ gap: 6, fontSize: 12.5, color: "var(--fg-3)" }}><b style={{ color: "var(--color-success)" }}>{sumMoney(byStage("won"), (o) => o.saleValue || o.estimatedValue || 0, lang)}</b> {T("مغلقة", "won")}</span>
          <Button variant="primary" size="sm" icon="plus" onClick={() => setNewOpen(true)}>{T("فرصة جديدة", "New opportunity")}</Button>
        </div>
      </div>

      {opps.length > 0 && <NextActionsWorklist onOpen={(id) => setDetailId(id)} lang={lang} />}

      {opps.length === 0 ? (
        <Card><EmptyState icon="sparkles" title={T("لا توجد فرص بعد", "No opportunities yet")} body={T("الفرص هي مسار البيع. أنشئ فرصة من عميل، أو من لوحة المحادثة عند ظهور نية شراء.", "Opportunities are your sales pipeline. Create one from a contact, or flag one from the conversation panel when buying intent appears.")} action={<Button variant="primary" icon="plus" onClick={() => setNewOpen(true)}>{T("فرصة جديدة", "New opportunity")}</Button>} /></Card>
      ) : (
        <div className="oppboard" style={{ display: "flex", gap: 14, overflowX: "auto", paddingBottom: 8, alignItems: "flex-start" }}>
          {OPP_ORDER.map((stage) => {
            const col = byStage(stage);
            const m = OPP_STATUSES[stage];
            const colVal = col.reduce((s, o) => s + (stage === "won" ? (o.saleValue || o.estimatedValue || 0) : (o.estimatedValue || 0)), 0);
            return (
              <div key={stage} style={{ flex: "0 0 280px", minWidth: 280, background: "var(--bg-2)", borderRadius: 14, padding: 10 }}>
                <div className="between" style={{ padding: "4px 6px 10px" }}>
                  <span className="row" style={{ gap: 7, fontSize: 12.5, fontWeight: 700 }}><span className="sdot" style={{ background: m.c }} />{statusLabel(stage, lang)}</span>
                  <span className="subtle" style={{ fontSize: 12 }}>{col.length}{colVal ? " · " + sumMoney(col, (o) => stage === "won" ? (o.saleValue || o.estimatedValue || 0) : (o.estimatedValue || 0), lang) : ""}</span>
                </div>
                <div className="col" style={{ gap: 8 }}>
                  {col.length === 0 ? (
                    <div className="subtle" style={{ fontSize: 12, textAlign: "center", padding: "14px 0" }}>—</div>
                  ) : col.map((o) => <OppMiniCard key={o.id} opp={o} onClick={() => setDetailId(o.id)} lang={lang} />)}
                </div>
              </div>
            );
          })}
        </div>
      )}

      {detail && <OpportunityDrawer opp={detail} onClose={() => setDetailId(null)} onToast={flash} go={go} />}
      {newOpen && <NewOpportunityModal onClose={() => setNewOpen(false)} onCreated={(o) => { setNewOpen(false); setDetailId(o.id); flash(T("تم إنشاء الفرصة", "Opportunity created")); }} onToast={flash} />}
      {toastNode}
    </div>
  );
}
window.OpportunitiesScreen = OpportunitiesScreen;

// PHASE 7 — "What action should be taken now?" The ranked cross-pipeline Next-Best-Actions worklist
// (engine + route + API client already existed; this binds them to the UI). Each item opens the deal's
// existing drawer. Honest: renders NOTHING while loading or when there's no open work (the kanban speaks).
function NextActionsWorklist({ onOpen, lang }) {
  const data = useStore();                                    // re-fetch when the store changes (after an action runs)
  const [actions, setActions] = useOppState(null);
  React.useEffect(() => {
    let on = true;
    API.metrics.nextBestActions("limit=6").then((r) => { if (on) setActions((r && r.actions) || []); }).catch(() => { if (on) setActions([]); });
    return () => { on = false; };
  }, [data]);
  if (!Array.isArray(actions) || actions.length === 0) return null;
  const T = (ar, en) => (lang === "ar" ? ar : en);
  const URG = { high: "var(--color-danger)", normal: "var(--color-secondary)" };
  return (
    <Card style={{ marginBottom: 14, padding: 12 }}>
      <div className="between" style={{ marginBottom: 8 }}>
        <span className="row" style={{ gap: 7, fontWeight: 700, fontSize: 13 }}><Icon name="sparkles" size={14} style={{ color: "var(--color-secondary)" }} />{T("ماذا تفعل الآن — بالأولوية", "What to do now — by priority")}</span>
        <span className="subtle" style={{ fontSize: 12 }}>{actions.length}</span>
      </div>
      <div className="chipscroll" style={{ display: "flex", gap: 8, overflowX: "auto", paddingBottom: 4 }}>
        {actions.map((a) => (
          <button key={a.opportunityId} onClick={() => onOpen(a.opportunityId)} title={a.why || ""} style={{ flex: "0 0 auto", textAlign: "start", maxWidth: 320, minWidth: 220, background: "var(--bg-2)", border: "1px solid var(--border-1)", borderRadius: 10, padding: "9px 11px", cursor: "pointer", display: "block" }}>
            <div className="row" style={{ gap: 6, marginBottom: 4, flexWrap: "wrap" }}>
              <span className="sdot" style={{ background: URG[a.urgency] || URG.normal, flexShrink: 0 }} />
              <span style={{ fontWeight: 700, fontSize: 12.5 }}>{NBA_LABEL(a.action, lang)}</span>
              {a.estimatedValue ? <span className="subtle" style={{ fontSize: 11.5 }}>· {sumMoney([a], (x) => x.estimatedValue || 0, lang)}</span> : null}
            </div>
            <div className="subtle" style={{ fontSize: 11.5, lineHeight: 1.4, overflow: "hidden", textOverflow: "ellipsis", display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical" }}>{a.title || a.why}</div>
          </button>
        ))}
      </div>
    </Card>
  );
}

function OppMiniCard({ opp: o, onClick, lang }) {
  const agent = agentById(o.agentId);
  const c = contactById(o.contactId);
  const pm = PRIORITY_META[o.priority] || PRIORITY_META.medium;
  return (
    <button onClick={onClick} className="oppcard" style={{ textAlign: "start", width: "100%", background: "#fff", border: "1px solid var(--border-1)", borderRadius: 10, padding: 11, cursor: "pointer", display: "block" }}>
      <div className="between" style={{ marginBottom: 7 }}>
        <span style={{ fontWeight: 700, fontSize: 13, lineHeight: 1.3, flex: 1, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{(c && c.name) || o.title}</span>
        <span className="opp" style={{ width: 26, height: 26, borderRadius: 7, background: o.score >= 80 ? "var(--color-primary)" : "var(--bg-2)", color: "var(--color-secondary)", fontWeight: 800, fontSize: 11.5, flexShrink: 0 }}>{o.score}</span>
      </div>
      <div className="row wrap" style={{ gap: 5, marginBottom: 8 }}>
        <Badge tone="dark"><Icon name="sparkles" size={11} />{svcLabel(o.service)}</Badge>
        <span className="row" style={{ gap: 4, fontSize: 11.5, fontWeight: 600, color: pm.c }}><span className="sdot" style={{ background: pm.c }} />{pm.label}</span>
      </div>
      <div className="between">
        <b style={{ fontSize: 13.5 }}>{o.estimatedValue ? fmtMoney(o.estimatedValue, lang, o.currency) : "—"}</b>
        <span className="row" style={{ gap: 5 }}>
          {roiScoreOf(o) != null && <Badge tone="lime" title={oppT(lang, "درجة العائد", "ROI Score")}>{oppT(lang, "عائد", "ROI")} {roiScoreOf(o)}</Badge>}
          {agent && <Avatar name={agent.name} size="sm" color={agent.color} />}
        </span>
      </div>
    </button>
  );
}

function StatusWorkflow({ opp, lang, onPick }) {
  return (
    <div className="row" style={{ gap: 4, flexWrap: "wrap" }}>
      {OPP_ORDER.map((s) => {
        const active = s === opp.status;
        const m = OPP_STATUSES[s];
        return (
          <button key={s} onClick={() => onPick && onPick(s)} title={statusLabel(s, lang)} style={{ padding: "6px 10px", borderRadius: 999, fontSize: 11.5, fontWeight: 700, border: "1px solid " + (active ? m.c : "var(--border-2)"), background: active ? m.c : "#fff", color: active ? "#fff" : "var(--fg-3)", whiteSpace: "nowrap", cursor: "pointer" }}>{statusLabel(s, lang)}</button>
        );
      })}
    </div>
  );
}

const TLI = { created: "sparkles", status: "flag", assign: "bot", meeting: "calendar", proposal: "fileText", followup: "clock", request: "inbox", note: "message", updated: "edit", deleted: "trash" };
function OpportunityDrawer({ opp: o, onClose, onToast, go }) {
  const { lang } = useLang();
  const data = useStore();
  const T = (ar, en) => oppT(lang, ar, en);
  const [assignOpen, setAssignOpen] = useOppState(false);
  const [modal, setModal] = useOppState(null); // "meeting"|"proposal"|"followup"|"request"|"won"|"lost"
  const [busy, setBusy] = useOppState(false);
  const agents = data.AGENTS || [];
  const agent = agentById(o.agentId);
  const c = contactById(o.contactId);
  const pm = PRIORITY_META[o.priority] || PRIORITY_META.medium;
  const linked = linkedFor(o.id);
  const conv = (data.CONVERSATIONS || []).find((x) => x.contactId === o.contactId);
  // Hydrate the server view (intelligence + next-best-action + memory) for this opp.
  const [hyd, setHyd] = useOppState(null);
  React.useEffect(() => { let on = true; setHyd(null); API.opportunities.get(o.id).then((d) => { if (on) setHyd(d); }).catch(() => {}); return () => { on = false; }; }, [o.id, o.status, o.updatedAt]);
  const nba = hyd && hyd.nextBest;
  const intel = (hyd && hyd.intelligence) || null;
  const mem = (hyd && hyd.memory) || null;

  const assign = async (a) => { setAssignOpen(false); setBusy(true); try { await Actions.assignOpportunity(o.id, a.id); onToast(T("تم الإسناد إلى ", "Assigned to ") + a.name); } catch (e) { onToast(T("تعذّر الإسناد", "Assign failed")); } finally { setBusy(false); } };
  const advance = async (s) => {
    if (s === o.status) return;
    if (s === "won") { setModal("won"); return; }
    if (s === "lost") { setModal("lost"); return; }
    if (s === "meeting_scheduled") { setModal("meeting"); return; }
    if (s === "proposal_sent") { setModal("proposal"); return; }
    setBusy(true);
    try { await Actions.setOpportunityStatus(o.id, { status: s }); onToast(T("تم تحديث الحالة", "Status updated")); }
    catch (e) { onToast(errMsg(e, lang)); } finally { setBusy(false); }
  };

  return (
    <Drawer onClose={onClose}>
      <DrawerHead title={(c && c.name) || o.title} sub={`${(c && c.person) || ""}${c && c.person ? " · " : ""}${svcLabel(o.service)}`} onClose={onClose} right={<OppStatusBadge status={o.status} />} />
      <div style={{ overflowY: "auto", padding: 24, display: "flex", flexDirection: "column", gap: 16, flex: 1 }}>

        {/* Summary + score */}
        <div style={{ background: "var(--color-primary-tint-soft)", border: "1px solid var(--color-primary-tint)", borderRadius: 16, padding: 18 }}>
          <div className="between" style={{ marginBottom: 8 }}>
            <span className="row" style={{ gap: 8 }}><Icon name="sparkles" size={18} style={{ color: "var(--color-secondary)" }} /><b style={{ color: "var(--color-secondary)", fontSize: 13 }}>{T("الفرصة", "Opportunity")}</b></span>
            <span className="opp" style={{ width: 34, height: 34, borderRadius: 9, background: "#fff", color: "var(--color-secondary)", fontWeight: 800, fontSize: 13 }}>{o.score}</span>
          </div>
          <p style={{ fontSize: 14, lineHeight: 1.6 }}>{o.problem || T("لا يوجد ملخص بعد.", "No problem summary yet.")}</p>
          <NextActionHint opp={o} lang={lang} />
        </div>

        {/* AI intelligence + Next Best Action (Phase 2) */}
        <Card title={<span className="row" style={{ gap: 7 }}><Icon name="sparkles" size={15} style={{ color: "var(--color-secondary)" }} />{T("ذكاء الفرصة", "Opportunity intelligence")}</span>}>
          {(o.estimated || (intel && intel.estimated)) && <div className="subtle" style={{ fontSize: 11.5, marginBottom: 8 }}>{T("تقدير مبدئي — لا توجد إشارة بيع مؤكدة بعد (سيُحدَّث مع تفاعل العميل).", "Estimated — no confirmed buying signal yet (updates as the lead engages).")}</div>}
          <div className="grid" style={{ gridTemplateColumns: "1fr 1fr", gap: 10, marginBottom: nba ? 12 : 0 }}>
            <KVOpp k={T("احتمالية الإغلاق", "Close probability")} v={<b>{(o.closeProbability != null ? o.closeProbability : (intel && intel.closeProbability)) || 0}%{(o.estimated || (intel && intel.estimated)) ? <span className="subtle" style={{ fontWeight: 500, fontSize: 11 }}> · est.</span> : ""}</b>} />
            <KVOpp k={T("الإيراد المرجّح", "Weighted revenue")} v={<b>{fmtMoney(o.weightedRevenue != null ? o.weightedRevenue : (intel && intel.weightedRevenue) || 0, lang, o.currency)}</b>} />
            <KVOpp k={T("اهتمام العميل", "Customer interest")} v={<Badge tone="neutral">{(INTEREST_OPTS.find((x) => x[0] === o.interest) || [, o.interest])[lang === "ar" ? 2 : 1] || o.interest}</Badge>} />
            <KVOpp k={T("التقييم", "Score")} v={<b>{o.score}</b>} />
          </div>
          {nba && (
            <div style={{ background: nba.urgency === "high" ? "var(--color-orange-soft, #FFF7ED)" : "var(--bg-2)", borderRadius: 10, padding: "10px 12px" }}>
              <div className="between" style={{ marginBottom: 4 }}>
                <span className="row" style={{ gap: 6, fontWeight: 700, fontSize: 12.5 }}><Icon name="zap" size={14} style={{ color: "var(--color-secondary)" }} />{T("الإجراء التالي الأفضل", "Next best action")}</span>
                <Badge tone={nba.urgency === "high" ? "orange" : "neutral"}>{T("أولوية", "priority")} {nba.priorityScore}</Badge>
              </div>
              <div style={{ fontSize: 13, fontWeight: 600 }}>{NBA_LABEL(nba.action, lang)}</div>
              <div className="muted" style={{ fontSize: 12, marginTop: 2 }}>{nba.why}</div>
              {nba.suggestedFollowUp && <div className="subtle" style={{ fontSize: 11.5, marginTop: 6 }}>{T("متابعة مقترحة:", "Suggested follow-up:")} {nba.suggestedFollowUp.date} · {nba.suggestedFollowUp.objective}</div>}
            </div>
          )}
        </Card>

        {/* Status workflow */}
        <Card title={T("مسار الحالة", "Status workflow")}>
          <StatusWorkflow opp={o} lang={lang} onPick={advance} />
        </Card>

        {/* Details */}
        <Card title={T("التفاصيل", "Details")}>
          <KVOpp k={T("العميل", "Contact")} v={c ? <button className="linklike" onClick={() => { onClose(); if (window.__openContact) window.__openContact(c.id); }}>{c.name}</button> : "—"} />
          <KVOpp k={T("المحادثة", "Conversation")} v={conv ? <button className="linklike" onClick={() => { try { window.__pendingConversationId = conv.id; window.__pendingConvContactId = o.contactId; } catch (e) {} go && go("conversations"); onClose(); }}>{T("فتح المحادثة", "Open conversation")}</button> : <span className="subtle">{T("لا توجد", "None")}</span>} />
          <KVOpp k={T("الخدمة المقترحة", "Recommended service")} v={<Badge tone="dark">{svcLabel(o.service)}</Badge>} />
          <KVOpp k={T("القيمة التقديرية", "Estimated value")} v={o.estimatedValue ? fmtMoney(o.estimatedValue, lang, o.currency) + T("/شهر", "/mo") : "—"} />
          {o.status === "won" && <KVOpp k={T("قيمة البيع", "Sale value")} v={<b style={{ color: "var(--color-success)" }}>{fmtMoney(o.saleValue, lang, o.currency)}</b>} />}
          {o.status === "lost" && o.lossReason && <KVOpp k={T("سبب الخسارة", "Loss reason")} v={o.lossReason} />}
          <KVOpp k={T("الأولوية", "Priority")} v={<span className="row" style={{ gap: 6, fontWeight: 600 }}><span className="sdot" style={{ background: pm.c }} />{pm.label}</span>} />
          <KVOpp k={T("الوكيل المسند", "Assigned agent")} v={agent ? <span className="row" style={{ gap: 6 }}><Avatar name={agent.name} size="sm" color={agent.color} />{agent.name}</span> : <span className="subtle">{T("غير مسند", "Unassigned")}</span>} />
        </Card>

        {/* Linked records */}
        <LinkedList title={T("الاجتماعات", "Meetings")} icon="calendar" items={linked.meetings} empty={T("لا اجتماعات", "No meetings")} render={(m) => `${m.date || ""} ${m.time || ""} · ${m.channel === "google_meet" ? "Google Meet" : m.channel}`.trim()} badge={(m) => m.status} />
        <LinkedList title={T("العروض", "Proposals")} icon="fileText" items={linked.proposals} empty={T("لا عروض", "No proposals")} render={(p) => `${p.title}${p.amount ? " · " + fmtMoney(p.amount, lang, p.currency) : ""}${p.file ? " · 📎 " + p.file.name : ""}`} badge={(p) => p.status} />
        <LinkedList title={T("الطلبات المخصصة", "Custom requests")} icon="inbox" items={linked.requests} empty={T("لا طلبات", "No requests")} render={(r) => r.description || r.categoryLabel} badge={(r) => r.status} />
        <LinkedList title={T("المتابعات", "Follow-ups")} icon="clock" items={linked.followUps} empty={T("لا متابعات", "No follow-ups")} render={(f) => `${f.when || f.date || ""} · ${f.action || f.type}`} badge={(f) => f.interest || f.status} overdueKey />

        {/* Phase 3 — Product & revenue (fields shown depend on the product/revenue type) */}
        <Card title={<span className="row" style={{ gap: 7 }}><Icon name="dollar" size={15} />{T("المنتج والإيراد", "Product & revenue")}</span>}>
          <KVOpp k={T("نوع المنتج", "Product type")} v={<Badge tone="purple">{productLabel(o.productType, lang)}</Badge>} />
          <KVOpp k={T("نوع الإيراد", "Revenue type")} v={<Badge tone="neutral">{o.revenueType || "—"}</Badge>} />
          {o.revenueType === "subscription" && <>
            {o.subscriptionPlan && <KVOpp k={T("الخطة", "Plan")} v={o.subscriptionPlan === "yearly" ? T("سنوي", "Yearly") : T("شهري", "Monthly")} />}
            <KVOpp k="MRR" v={<b>{fmtMoney(o.expectedMRR, lang, o.currency)}{T("/شهر", "/mo")}</b>} />
            <KVOpp k="ARR" v={<b>{fmtMoney(o.expectedARR, lang, o.currency)}{T("/سنة", "/yr")}</b>} />
          </>}
          {o.revenueType === "license" && <>
            <KVOpp k={T("قيمة الترخيص", "License revenue")} v={<b>{fmtMoney(o.licenseRevenue, lang, o.currency)}</b>} />
            {o.setupRevenue > 0 && <KVOpp k={T("الإعداد", "Setup")} v={fmtMoney(o.setupRevenue, lang, o.currency)} />}
            {o.supportRevenue > 0 && <KVOpp k={T("دعم شهري", "Monthly support")} v={fmtMoney(o.supportRevenue, lang, o.currency) + T("/شهر", "/mo")} />}
          </>}
          {o.revenueType === "setup" && <>
            <KVOpp k={T("رسوم الإعداد", "Setup fee")} v={<b>{fmtMoney(o.setupRevenue, lang, o.currency)}</b>} />
            {o.supportRevenue > 0 && <KVOpp k={T("دعم شهري", "Monthly support")} v={fmtMoney(o.supportRevenue, lang, o.currency) + T("/شهر", "/mo")} />}
          </>}
          {o.revenueType === "support" && <KVOpp k={T("دعم شهري", "Monthly support")} v={<b>{fmtMoney(o.supportRevenue, lang, o.currency) + T("/شهر", "/mo")}</b>} />}
          {o.revenueType === "one_time" && <KVOpp k={T("إيراد لمرة واحدة", "One-time revenue")} v={<b>{fmtMoney(o.oneTimeRevenue, lang, o.currency)}</b>} />}
          {o.deploymentType && <KVOpp k={T("نوع النشر", "Deployment")} v={o.deploymentType === "client_server" ? T("سيرفر العميل", "Client server") : T("سيرفر Maxab", "Maxab-managed")} />}
          {o.technicalComplexity && <KVOpp k={T("التعقيد التقني", "Technical complexity")} v={<Badge tone={o.technicalComplexity === "high" ? "orange" : "neutral"}>{o.technicalComplexity}</Badge>} />}
          {Array.isArray(o.requiredIntegrations) && o.requiredIntegrations.length > 0 && <KVOpp k={T("التكاملات المطلوبة", "Integrations")} v={o.requiredIntegrations.join(", ")} />}
          {o.decisionMaker && <KVOpp k={T("متخذ القرار", "Decision maker")} v={o.decisionMaker} />}
          {o.renewalRisk && o.renewalRisk !== "none" && <KVOpp k={T("خطر التجديد", "Renewal risk")} v={<Badge tone="red">{o.renewalRisk}</Badge>} />}
        </Card>

        {/* ROI summary (AI Revenue Organization) — auto-calculated in conversation or via the
            RCC calculator; attached to the opportunity. A pending (unconfirmed) ROI shows only a
            note; the full card + ROI Score appear once committed. */}
        {o.roi && o.roi.pendingConfirmation ? (
          <Card title={<span className="row" style={{ gap: 7 }}><Icon name="dollar" size={15} style={{ color: "var(--color-orange)" }} />{T("العائد قيد التأكيد", "ROI pending confirmation")}</span>}>
            <div className="subtle" style={{ fontSize: 12.5, lineHeight: 1.5 }}>{T(`حُسب العائد مبدئيًا (ثقة ${Math.round((o.roi.confidence || 0) * 100)}%) — بانتظار تأكيد العميل للأرقام قبل اعتماده.`, `ROI computed tentatively (confidence ${Math.round((o.roi.confidence || 0) * 100)}%) — awaiting the prospect's confirmation before it's committed.`)}</div>
          </Card>
        ) : o.roi && o.roi.annualSavings != null && (
          <Card title={<span className="row" style={{ gap: 7 }}><Icon name="dollar" size={15} style={{ color: "var(--color-secondary)" }} />{T("ملخّص العائد على الاستثمار", "ROI summary")}</span>}>
            <KVOpp k={T("تكلفة الفريق السنوية", "Current annual team cost")} v={fmtMoney(o.roi.totalTeamCost, lang, o.roi.currency)} />
            <KVOpp k={T("تكلفة MAXAB السنوية", "MAXAB AI annual cost")} v={<span>{fmtMoney(o.roi.maxabAnnualCost, lang, o.roi.currency)}{o.roi.packageName ? <span className="subtle"> · {lang === "ar" ? (o.roi.packageName.ar || o.roi.packageName.en) : (o.roi.packageName.en || o.roi.packageName)}</span> : null}</span>} />
            <KVOpp k={T("التوفير السنوي", "Annual savings")} v={<b style={{ color: o.roi.annualSavings > 0 ? "var(--color-secondary)" : "var(--color-orange)" }}>{fmtMoney(o.roi.annualSavings, lang, o.roi.currency)}</b>} />
            {o.roi.roiPct != null && <KVOpp k={T("نسبة العائد", "ROI %")} v={o.roi.roiPct + "%"} />}
            {o.roi.paybackMonths != null && <KVOpp k={T("فترة الاسترداد", "Payback")} v={o.roi.paybackMonths + " " + T("شهر", "mo")} />}
            {(o.roiScore != null || o.roi.roiScore != null) && <KVOpp k={T("درجة العائد", "ROI Score")} v={<Badge tone="lime">{o.roiScore != null ? o.roiScore : o.roi.roiScore}/100</Badge>} />}
            {o.roi.confidence != null && <KVOpp k={T("ثقة الاستخراج", "Confidence")} v={Math.round(o.roi.confidence * 100) + "%"} />}
            <KVOpp k={T("المصدر", "Source")} v={<Badge tone="neutral">{o.roi.source === "conversation_auto" ? T("محادثة (تلقائي)", "conversation (auto)") : T("الحاسبة", "calculator")}</Badge>} />
          </Card>
        )}

        {/* Tranche E — payment actions (link / invoice / installments + live status) */}
        <PaymentActionsPanel opp={o} lang={lang} onToast={onToast} />

        {/* Agent memory (consolidated from real per-contact data) */}
        {mem && (
          <Card title={<span className="row" style={{ gap: 7 }}><Icon name="bot" size={15} />{T("ذاكرة العميل", "Agent memory")}</span>}>
            <KVOpp k={T("احتمالية الشراء", "Purchase likelihood")} v={<b>{mem.purchaseLikelihood}%</b>} />
            {mem.interestedServices && mem.interestedServices.length > 0 && <KVOpp k={T("خدمات مهتم بها", "Interested in")} v={mem.interestedServices.map(svcLabel).join(", ")} />}
            {mem.objections && mem.objections.length > 0 && <KVOpp k={T("اعتراضات", "Objections")} v={mem.objections.join(", ")} />}
            <KVOpp k={T("سجل", "History")} v={`${mem.previousProposals.length} ${T("عرض", "proposals")} · ${mem.previousMeetings.length} ${T("اجتماع", "meetings")} · ${mem.previousFollowUps.length} ${T("متابعة", "follow-ups")} · ${mem.conversationCount} ${T("رسالة", "msgs")}`} />
            {mem.nextBestAction && <KVOpp k={T("الخطوة التالية", "Next step")} v={mem.nextBestAction} />}
          </Card>
        )}

        {/* Ownership + handoff (multi-agent collaboration) */}
        <Card title={<span className="row" style={{ gap: 7 }}><Icon name="users" size={15} />{T("الملكية والتحويل", "Ownership & handoff")}</span>}>
          <KVOpp k={T("المالك الحالي", "Current owner")} v={agent ? <span className="row" style={{ gap: 6 }}><Avatar name={agent.name} size="sm" color={agent.color} />{agent.name}</span> : <span className="subtle">{T("غير مسند", "Unassigned")}</span>} />
          {o.previousAgentId && <KVOpp k={T("المالك السابق", "Previous owner")} v={(agentById(o.previousAgentId) || {}).name || o.previousAgentId} />}
          {Array.isArray(o.handoffLog) && o.handoffLog.length > 0 && (
            <div style={{ marginTop: 8 }}>
              <div className="subtle" style={{ fontSize: 11.5, marginBottom: 4 }}>{T("سجل التحويلات", "Handoff log")}</div>
              {o.handoffLog.slice(-4).map((h, i) => (
                <div key={i} className="row" style={{ gap: 6, fontSize: 12, padding: "3px 0" }}><Icon name="arrowRight" size={12} style={{ color: "var(--fg-4)" }} />{(agentById(h.from) || {}).name || h.from} → {(agentById(h.to) || {}).name || h.to}{h.reason ? " · " + h.reason : ""}</div>
              ))}
            </div>
          )}
        </Card>

        {/* Timeline */}
        {Array.isArray(o.timeline) && o.timeline.length > 0 && (
          <Card title={T("النشاط", "Activity timeline")}>
            <div className="col" style={{ gap: 10 }}>
              {o.timeline.slice().reverse().slice(0, 16).map((t, i) => (
                <div key={i} className="row" style={{ gap: 10, alignItems: "flex-start" }}>
                  <span className="opp" style={{ width: 26, height: 26, borderRadius: 7, background: "var(--bg-2)", color: "var(--fg-3)", flexShrink: 0 }}><Icon name={TLI[t.type] || "dot"} size={13} /></span>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontSize: 12.5, fontWeight: 600 }}>{t.detail || t.type}{t.from && t.to ? ` (${statusLabel(t.from, lang)} → ${statusLabel(t.to, lang)})` : ""}</div>
                    <div className="subtle" style={{ fontSize: 11 }}>{t.by} · {new Date(t.at).toLocaleString()}</div>
                  </div>
                </div>
              ))}
            </div>
          </Card>
        )}
      </div>

      {/* Action bar */}
      <div style={{ borderTop: "1px solid var(--border-1)", background: "#fff", padding: 16 }}>
        <div className="row wrap" style={{ gap: 8 }}>
          <Button variant="dark" size="sm" icon="message" disabled={busy} onClick={() => { try { window.__pendingConversationId = conv ? conv.id : null; window.__pendingConvContactId = o.contactId; } catch (e) {} go && go("conversations"); onClose(); }}>{T("بدء المحادثة", "Start conversation")}</Button>
          <div style={{ position: "relative" }}>
            <button className="btn btn--ghost btn--sm" disabled={busy} onClick={() => setAssignOpen((v) => !v)}><Icon name="bot" size={14} />{T("تعيين وكيل", "Assign agent")}</button>
            {assignOpen && <>
              <div style={{ position: "fixed", inset: 0, zIndex: 51 }} onClick={() => setAssignOpen(false)} />
              <div style={{ position: "absolute", bottom: 42, insetInlineStart: 0, zIndex: 52, width: 220, maxHeight: 280, overflowY: "auto", background: "#fff", border: "1px solid var(--border-1)", borderRadius: "var(--radius-md)", boxShadow: "var(--shadow-lg)", padding: 6 }}>
                {agents.map((a) => (
                  <button key={a.id} onClick={() => assign(a)} className="row" style={{ gap: 10, width: "100%", padding: "8px 10px", borderRadius: "var(--radius-xs)", textAlign: "start", background: a.id === o.agentId ? "var(--color-primary-tint-soft)" : "transparent", cursor: "pointer" }}>
                    <Avatar name={a.name} size="sm" color={a.color} /><span style={{ fontSize: 13 }}>{a.name}</span>{a.id === o.agentId && <Icon name="check" size={14} style={{ marginInlineStart: "auto", color: "var(--color-secondary)" }} />}
                  </button>
                ))}
              </div>
            </>}
          </div>
          <button className="btn btn--ghost btn--sm" disabled={busy} onClick={() => setModal("meeting")}><Icon name="calendar" size={14} />{T("اجتماع", "Meeting")}</button>
          <button className="btn btn--ghost btn--sm" disabled={busy} onClick={() => setModal("proposal")}><Icon name="fileText" size={14} />{T("عرض", "Proposal")}</button>
          <button className="btn btn--ghost btn--sm" disabled={busy} onClick={() => setModal("followup")}><Icon name="clock" size={14} />{T("متابعة", "Follow-up")}</button>
          <button className="btn btn--ghost btn--sm" disabled={busy} onClick={() => setModal("request")}><Icon name="inbox" size={14} />{T("طلب", "Request")}</button>
          {!["won", "lost"].includes(o.status) && <>
            <button className="btn btn--sm" style={{ background: "var(--color-success)", color: "#fff" }} disabled={busy} onClick={() => setModal("won")}><Icon name="checkcircle" size={14} />{T("فوز", "Won")}</button>
            <button className="btn btn--ghost btn--sm" style={{ color: "var(--color-danger)" }} disabled={busy} onClick={() => setModal("lost")}><Icon name="ban" size={14} />{T("خسارة", "Lost")}</button>
          </>}
        </div>
      </div>

      {modal === "meeting" && <ScheduleMeetingModal opp={o} onClose={() => setModal(null)} onDone={() => { setModal(null); onToast(T("تم جدولة الاجتماع", "Meeting scheduled")); }} onErr={(e) => onToast(errMsg(e, lang))} />}
      {modal === "proposal" && <SendProposalModal opp={o} onClose={() => setModal(null)} onDone={() => { setModal(null); onToast(T("تم إرسال العرض", "Proposal sent")); }} onErr={(e) => onToast(errMsg(e, lang))} />}
      {modal === "followup" && <AddFollowUpModal opp={o} onClose={() => setModal(null)} onDone={() => { setModal(null); onToast(T("تمت إضافة المتابعة", "Follow-up added")); }} onErr={(e) => onToast(errMsg(e, lang))} />}
      {modal === "request" && <LogRequestModal opp={o} onClose={() => setModal(null)} onDone={() => { setModal(null); onToast(T("تم تسجيل الطلب", "Request logged")); }} onErr={(e) => onToast(errMsg(e, lang))} />}
      {modal === "won" && <MarkWonModal opp={o} onClose={() => setModal(null)} onDone={() => { setModal(null); onToast(T("تم تسجيل الفوز 🎉", "Marked Won 🎉")); }} onErr={(e) => onToast(errMsg(e, lang))} />}
      {modal === "lost" && <MarkLostModal opp={o} onClose={() => setModal(null)} onDone={() => { setModal(null); onToast(T("تم تسجيل الخسارة", "Marked Lost")); }} onErr={(e) => onToast(errMsg(e, lang))} />}
    </Drawer>
  );
}

function errMsg(e, lang) {
  const m = String((e && e.message) || "").toLowerCase();
  if (m.includes("sale_value_required")) return lang === "ar" ? "أدخل قيمة البيع" : "Enter the sale value";
  if (m.includes("loss_reason_required")) return lang === "ar" ? "أدخل سبب الخسارة" : "Enter the loss reason";
  if (m.includes("invalid_status")) return lang === "ar" ? "حالة غير صالحة" : "Invalid status";
  if (m.includes("not_found")) return lang === "ar" ? "الفرصة غير موجودة" : "Opportunity not found";
  if (m.includes("agent_not_found")) return lang === "ar" ? "الوكيل غير موجود" : "Agent not found";
  return lang === "ar" ? "تعذّر الحفظ" : "Could not save";
}

function NextActionHint({ opp, lang }) {
  const map = {
    new: ["ابدأ محادثة أو تواصل", "Start a conversation / outreach"], in_review: ["أهّل العميل", "Qualify the fit"],
    contacted: ["حدّد اجتماعاً", "Schedule a meeting"], meeting_scheduled: ["أرسل عرضاً", "Send a proposal"],
    proposal_sent: ["أغلق — سجّل قيمة البيع", "Close — mark Won with sale value"], won: ["ابدأ التنفيذ", "Start delivery"], lost: ["أضف لإعادة الاستهداف", "Add to retargeting"],
  };
  const a = map[opp.status] || map.new;
  return <div className="row" style={{ gap: 7, marginTop: 10, fontSize: 12.5, color: "var(--color-secondary)", fontWeight: 700 }}><Icon name="arrowRight" size={14} />{lang === "ar" ? a[0] : a[1]}</div>;
}

function LinkedList({ title, icon, items, empty, render, badge, overdueKey }) {
  const today = new Date().toISOString().slice(0, 10);
  return (
    <Card title={<span className="row" style={{ gap: 7 }}><Icon name={icon} size={15} />{title}<span className="subtle" style={{ fontSize: 11.5 }}>{items.length}</span></span>}>
      {items.length === 0 ? <div className="subtle" style={{ fontSize: 12.5, padding: "4px 0" }}>{empty}</div> : (
        <div className="col" style={{ gap: 8 }}>
          {items.slice(0, 8).map((it) => {
            const over = overdueKey && it.date && it.date < today && it.status === "scheduled";
            return (
              <div key={it.id} className="between" style={{ gap: 10, padding: "8px 10px", background: over ? "var(--color-danger-soft, #FEF2F2)" : "var(--bg-2)", borderRadius: 9 }}>
                <span style={{ fontSize: 12.5, minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{render(it)}</span>
                {badge && badge(it) ? <Badge tone={over ? "red" : "neutral"}>{over ? "overdue" : badge(it)}</Badge> : null}
              </div>
            );
          })}
        </div>
      )}
    </Card>
  );
}

function KVOpp({ k, v }) {
  return (
    <div className="between" style={{ gap: 12, padding: "8px 0", borderBottom: "1px solid var(--border-1)", alignItems: "flex-start" }}>
      <span className="muted" style={{ fontSize: 12.5, flexShrink: 0 }}>{k}</span>
      <span style={{ fontSize: 13, fontWeight: 600, textAlign: "end", wordBreak: "break-word" }}>{v}</span>
    </div>
  );
}

// ---- Tranche E — payment actions on the opportunity (link / invoice / installment + status) --
// Every button calls the shared backend action layer (API.agentActions.run → /api/agent-actions).
// The layer enforces caps/approval/audit and degrades honestly when Stripe isn't configured — so
// this panel renders whatever the backend HONESTLY returns (a real link, an honest "team will
// send it", or a "needs manager approval" state) and never invents a payment link itself.
const PAY_CURRENCIES = ["SAR", "USD", "EUR", "CAD", "AED"];
const PAY_STATUS_TONE = { paid: "lime", partial: "orange", unpaid: "red", none: "neutral" };
function PaymentActionsPanel({ opp: o, lang, onToast }) {
  const T = (ar, en) => oppT(lang, ar, en);
  const [status, setStatus] = React.useState(null);
  const [invoices, setInvoices] = React.useState([]);
  const [form, setForm] = React.useState(null); // null | "createPaymentLink" | "createInvoice" | "createInstallmentPlan"
  const [amount, setAmount] = React.useState(String(o.estimatedValue || ""));
  const [cur, setCur] = React.useState(o.currency || "SAR");
  const [installments, setInstallments] = React.useState(3);
  const [subInterval, setSubInterval] = React.useState("year");
  const [busy, setBusy] = React.useState(false);
  const [result, setResult] = React.useState(null);

  const refresh = React.useCallback(() => {
    API.agentActions.run("checkPaymentStatus", { opportunityId: o.id }).then((r) => setStatus(r && r.data ? r.data : null)).catch(() => {});
    API.agentActions.invoices(o.id).then((r) => setInvoices((r && r.invoices) || [])).catch(() => {});
  }, [o.id]);
  React.useEffect(() => { refresh(); }, [refresh]);

  const plan = (status && status.plan) || o.paymentPlan || null;
  const msgOf = (r) => (r && r.message ? (lang === "ar" ? r.message.ar : r.message.en) : "");

  const submit = async (action) => {
    setBusy(true); setResult(null);
    try {
      const body = action === "createInstallmentPlan"
        ? { opportunityId: o.id, total: Number(amount) || 0, currency: cur, installments: Number(installments) || 3 }
        : action === "createSubscription"
        ? { opportunityId: o.id, amount: Number(amount) || 0, currency: cur, interval: subInterval }
        : { opportunityId: o.id, amount: Number(amount) || 0, currency: cur };
      const r = await API.agentActions.run(action, body);
      setResult(r);
      onToast(msgOf(r) || (r && r.success ? T("تم", "Done") : T("تعذّر", "Failed")));
      setForm(null);
      refresh();
    } catch (e) { onToast(T("تعذّر تنفيذ الإجراء", "Action failed")); }
    finally { setBusy(false); }
  };

  const ActBtn = ({ id, icon, label }) => (
    <Button variant={form === id ? "primary" : "dark"} size="sm" icon={icon} disabled={busy} onClick={() => { setForm(form === id ? null : id); setResult(null); }}>{label}</Button>
  );

  return (
    <Card title={<span className="row" style={{ gap: 7 }}><Icon name="dollar" size={15} style={{ color: "var(--color-secondary)" }} />{T("المدفوعات", "Payments")}</span>}>
      {/* status */}
      {status && status.status && status.status !== "none" ? (
        <>
          <KVOpp k={T("حالة الدفع", "Payment status")} v={<Badge tone={PAY_STATUS_TONE[status.status] || "neutral"}>{status.status === "paid" ? T("مدفوعة", "Paid") : status.status === "partial" ? T("مدفوعة جزئياً", "Partial") : T("غير مدفوعة", "Unpaid")}</Badge>} />
          <KVOpp k={T("المستحق / المدفوع", "Due / Paid")} v={<b>{fmtMoney(status.totalPaid || 0, lang, status.currency)} / {fmtMoney(status.totalDue || 0, lang, status.currency)}</b>} />
          {status.nextDue && <KVOpp k={T("الاستحقاق التالي", "Next due")} v={status.nextDue} />}
        </>
      ) : (
        <div className="subtle" style={{ fontSize: 12.5, marginBottom: 4 }}>{T("لا توجد فواتير أو خطة تقسيط بعد.", "No invoices or installment plan yet.")}</div>
      )}

      {/* actions */}
      <div className="row" style={{ gap: 8, flexWrap: "wrap", marginTop: 10 }}>
        <ActBtn id="createPaymentLink" icon="link" label={T("رابط دفع", "Payment link")} />
        <ActBtn id="createInvoice" icon="fileText" label={T("فاتورة", "Invoice")} />
        <ActBtn id="createInstallmentPlan" icon="layers" label={T("تقسيط", "Installments")} />
        <ActBtn id="createSubscription" icon="refresh" label={T("اشتراك", "Subscription")} />
      </div>

      {/* inline form */}
      {form && (
        <div style={{ background: "var(--bg-2)", borderRadius: 10, padding: 12, marginTop: 10, display: "flex", flexDirection: "column", gap: 8 }}>
          <div className="row" style={{ gap: 8, flexWrap: "wrap", alignItems: "center" }}>
            <input className="inp" type="number" min="0" value={amount} onChange={(e) => setAmount(e.target.value)} placeholder={form === "createInstallmentPlan" ? T("الإجمالي", "Total") : T("المبلغ", "Amount")} style={{ maxWidth: 140 }} />
            <select className="select" value={cur} onChange={(e) => setCur(e.target.value)} style={{ maxWidth: 100 }}>{PAY_CURRENCIES.map((c) => <option key={c} value={c}>{c}</option>)}</select>
            {form === "createInstallmentPlan" && (
              <select className="select" value={installments} onChange={(e) => setInstallments(e.target.value)} style={{ maxWidth: 130 }}>{[2, 3, 4, 6, 12].map((n) => <option key={n} value={n}>{n} {T("دفعات", "payments")}</option>)}</select>
            )}
            {form === "createSubscription" && (
              <select className="select" value={subInterval} onChange={(e) => setSubInterval(e.target.value)} style={{ maxWidth: 150 }}><option value="year">{T("سنوي", "Yearly")}</option><option value="month">{T("شهري", "Monthly")}</option></select>
            )}
          </div>
          {form === "createInstallmentPlan" && <div className="subtle" style={{ fontSize: 11 }}>{T("التقسيط يتطلب اعتماد المدير.", "Installment plans require manager approval.")}</div>}
          {form === "createSubscription" && <div className="subtle" style={{ fontSize: 11 }}>{T("اشتراك متكرر — بدون مفتاح Stripe حيّ، يرسل الفريق رابطاً متكرراً (لا يُختلق).", "Recurring subscription — with no live Stripe key, the team sends a recurring link (never fabricated).")}</div>}
          <div className="row" style={{ gap: 8 }}>
            <Button variant="primary" size="sm" disabled={busy} onClick={() => submit(form)}>{busy ? T("جارٍ…", "Working…") : T("تنفيذ", "Create")}</Button>
            <Button variant="ghost" size="sm" disabled={busy} onClick={() => setForm(null)}>{T("إلغاء", "Cancel")}</Button>
          </div>
        </div>
      )}

      {/* honest result feedback */}
      {result && (
        <div style={{ marginTop: 10, padding: "10px 12px", borderRadius: 10, fontSize: 12.5, lineHeight: 1.5, background: result.success ? "var(--color-primary-tint-soft)" : "var(--color-orange-soft, #FFF7ED)", border: "1px solid " + (result.success ? "var(--color-primary-tint)" : "var(--color-orange, #FB923C)") }}>
          {result.requiresApproval && <Badge tone="orange" style={{ marginInlineEnd: 6 }}>{T("بانتظار اعتماد المدير", "Needs manager approval")}</Badge>}
          <span>{msgOf(result)}</span>
          {result.data && result.data.link && <div style={{ marginTop: 6 }}><a className="linklike" href={result.data.link} target="_blank" rel="noreferrer">{T("فتح رابط الدفع", "Open payment link")}</a></div>}
        </div>
      )}

      {/* invoices */}
      {invoices.length > 0 && (
        <div style={{ marginTop: 12 }}>
          <div className="muted" style={{ fontSize: 11.5, marginBottom: 4 }}>{T("الفواتير", "Invoices")}</div>
          {invoices.map((iv) => (
            <div key={iv.id} className="between" style={{ gap: 10, padding: "6px 0", borderBottom: "1px solid var(--border-1)" }}>
              <span style={{ fontSize: 12.5 }}>{iv.number} · {fmtMoney(iv.total, lang, iv.currency)}{iv.paymentLink ? <> · <a className="linklike" href={iv.paymentLink} target="_blank" rel="noreferrer">{T("رابط", "link")}</a></> : ""}</span>
              <Badge tone={iv.status === "paid" ? "lime" : iv.status === "void" ? "neutral" : "orange"}>{iv.status}</Badge>
            </div>
          ))}
        </div>
      )}

      {/* installment plan */}
      {plan && Array.isArray(plan.installments) && (
        <div style={{ marginTop: 12 }}>
          <div className="muted" style={{ fontSize: 11.5, marginBottom: 4 }}>{T("خطة التقسيط", "Installment plan")} · {plan.paidCount || 0}/{plan.count || plan.installments.length}</div>
          {plan.installments.map((p) => (
            <div key={p.n} className="between" style={{ gap: 10, padding: "6px 0", borderBottom: "1px solid var(--border-1)" }}>
              <span style={{ fontSize: 12.5 }}>{T("دفعة", "Payment")} {p.n} · {fmtMoney(p.amount, lang, p.currency || plan.currency)} · {p.dueAt}</span>
              <Badge tone={p.status === "paid" ? "lime" : "neutral"}>{p.status === "paid" ? T("مدفوعة", "paid") : T("معلّقة", "pending")}</Badge>
            </div>
          ))}
        </div>
      )}
    </Card>
  );
}

// ---- New opportunity (pick a real contact → create a real record) -------
function NewOpportunityModal({ onClose, onCreated, onToast }) {
  const { lang } = useLang(); const data = useStore(); const T = (ar, en) => oppT(lang, ar, en);
  const [q, setQ] = useOppState(""); const [picked, setPicked] = useOppState(null); const [busy, setBusy] = useOppState(false);
  const [productType, setProductType] = useOppState("ai_sub");
  const [plan, setPlan] = useOppState("monthly");
  const [mrr, setMrr] = useOppState(""); const [licenseRev, setLicenseRev] = useOppState(""); const [setupRev, setSetupRev] = useOppState(""); const [supportRev, setSupportRev] = useOppState("");
  const [deploy, setDeploy] = useOppState("maxab_managed"); const [estVal, setEstVal] = useOppState("");
  const [cur, setCur] = useOppState(defaultCur());
  // Inherit the selected product's currency when it has one (Stage 5: default to the
  // product/service currency, else the global default).
  React.useEffect(() => {
    const p = (data.MAXAB_PRODUCTS || []).find((x) => x.productType === productType && x.currency);
    if (p && p.currency) setCur(window.MaxabCurrency.normalize(p.currency)); else setCur(defaultCur());
  }, [productType]);
  const existing = new Set(liveOpps().map((o) => o.contactId));
  const matches = (data.CONTACTS || []).filter((c) => !c.status || !["won", "lost"].includes(c.status)).filter((c) => { const s = (q || "").toLowerCase(); return !s || (c.name || "").toLowerCase().includes(s) || (c.person || "").toLowerCase().includes(s); }).slice(0, 30);
  const isSub = productType === "ai_sub" || productType === "maxab_hub";
  const isLicense = productType === "source_code" || productType === "white_label";
  const isDeploy = productType === "private_deploy";
  const create = async () => {
    if (!picked) return; setBusy(true);
    const body = { contactId: picked.id, productType, currency: cur };
    if (estVal) body.estimatedValue = Number(estVal) || undefined;
    if (isSub) { body.subscriptionPlan = plan; if (mrr) body.expectedMRR = Number(mrr) || 0; }
    if (isLicense) { if (licenseRev) body.licenseRevenue = Number(licenseRev) || 0; if (setupRev) body.setupRevenue = Number(setupRev) || 0; if (supportRev) body.supportRevenue = Number(supportRev) || 0; }
    if (isDeploy) { body.deploymentType = deploy; if (setupRev) body.setupRevenue = Number(setupRev) || 0; if (supportRev) body.supportRevenue = Number(supportRev) || 0; }
    try { const o = await Actions.createOpportunity(body); onCreated(o); }
    catch (e) { onToast(T("تعذّر الإنشاء", "Could not create")); setBusy(false); }
  };
  return (
    <Modal onClose={() => !busy && onClose()} style={{ width: 520 }}>
      <div className="between" style={{ padding: "18px 22px", borderBottom: "1px solid var(--border-1)" }}>
        <div style={{ fontWeight: 800, fontSize: 16 }}>{T("فرصة جديدة", "New opportunity")}</div>
        <button className="iconbtn" onClick={onClose}><Icon name="x" size={20} /></button>
      </div>
      <div style={{ padding: 22 }}>
        <Field label={T("اختر العميل", "Pick a contact")} hint={T("القيمة والخدمة تُشتق تلقائياً من ذكاء العميل.", "Value & service are derived automatically from the contact's intelligence.")}>
          <input className="input" autoFocus placeholder={T("ابحث بالاسم…", "Search by name…")} value={q} onChange={(e) => { setQ(e.target.value); setPicked(null); }} />
        </Field>
        <div className="col" style={{ gap: 6, maxHeight: 260, overflowY: "auto", marginTop: 4 }}>
          {matches.length === 0 ? <div className="subtle" style={{ fontSize: 13, textAlign: "center", padding: 16 }}>{T("لا عملاء مطابقون", "No matching contacts")}</div> :
            matches.map((c) => (
              <button key={c.id} onClick={() => setPicked(c)} className="between" style={{ width: "100%", padding: "9px 12px", borderRadius: 9, border: "1px solid " + (picked && picked.id === c.id ? "var(--color-secondary)" : "var(--border-1)"), background: picked && picked.id === c.id ? "var(--color-primary-tint-soft)" : "#fff", cursor: "pointer", textAlign: "start" }}>
                <span style={{ minWidth: 0 }}><b style={{ fontSize: 13 }}>{c.name}</b> <span className="subtle" style={{ fontSize: 12 }}>{c.person || ""}</span></span>
                {existing.has(c.id) && <Badge tone="neutral">{T("له فرصة", "has opp")}</Badge>}
              </button>
            ))}
        </div>
        {/* Phase 3 — product type + product-specific revenue inputs */}
        <Field label={T("نوع المنتج", "Product type")} hint={T("يحدد نوع الإيراد وحقول العرض.", "Drives the revenue type + the fields shown.")}>
          <select className="select" value={productType} onChange={(e) => setProductType(e.target.value)}>
            {productOpts().map((p) => <option key={p} value={p}>{productLabel(p, lang)}</option>)}
          </select>
        </Field>
        <Field label={T("القيمة التقديرية", "Estimated value")} hint={T("اتركه فارغاً لاشتقاقه من ذكاء العميل.", "Leave blank to derive from intelligence.")}>
          <div className="row" style={{ gap: 8 }}>
            <input className="input" type="number" min="0" value={estVal} onChange={(e) => setEstVal(e.target.value)} style={{ flex: 1 }} />
            <CurrencySelect value={cur} onChange={setCur} />
          </div>
        </Field>
        {isSub && <div className="row" style={{ gap: 12 }}>
          <Field label={T("الخطة", "Plan")}><select className="select" value={plan} onChange={(e) => setPlan(e.target.value)}><option value="monthly">{T("شهري", "Monthly")}</option><option value="yearly">{T("سنوي", "Yearly")}</option></select></Field>
          <Field label={T("MRR المتوقع", "Expected MRR")}><input className="input" type="number" min="0" placeholder={T("شهري", "monthly")} value={mrr} onChange={(e) => setMrr(e.target.value)} /></Field>
        </div>}
        {isLicense && <div className="row wrap" style={{ gap: 12 }}>
          <Field label={T("قيمة الترخيص", "License")}><input className="input" type="number" min="0" value={licenseRev} onChange={(e) => setLicenseRev(e.target.value)} /></Field>
          <Field label={T("الإعداد", "Setup")}><input className="input" type="number" min="0" value={setupRev} onChange={(e) => setSetupRev(e.target.value)} /></Field>
          <Field label={T("دعم شهري", "Support/mo")}><input className="input" type="number" min="0" value={supportRev} onChange={(e) => setSupportRev(e.target.value)} /></Field>
        </div>}
        {isDeploy && <div className="row" style={{ gap: 12 }}>
          <Field label={T("النشر", "Deployment")}><select className="select" value={deploy} onChange={(e) => setDeploy(e.target.value)}><option value="maxab_managed">{T("سيرفر Maxab", "Maxab-managed")}</option><option value="client_server">{T("سيرفر العميل", "Client server")}</option></select></Field>
          <Field label={T("دعم شهري", "Support/mo")}><input className="input" type="number" min="0" value={supportRev} onChange={(e) => setSupportRev(e.target.value)} /></Field>
        </div>}
        <div className="row" style={{ gap: 10, justifyContent: "flex-end", marginTop: 16 }}>
          <Button variant="ghost" disabled={busy} onClick={onClose}>{T("إلغاء", "Cancel")}</Button>
          <Button variant="primary" icon={busy ? null : "plus"} disabled={busy || !picked} onClick={create}>{busy ? <><span className="spin" style={{ width: 15, height: 15 }} />{T("جارٍ…", "Creating…")}</> : T("إنشاء الفرصة", "Create opportunity")}</Button>
        </div>
      </div>
    </Modal>
  );
}

// ---- Action modals (every one persists via real Actions) ----------------
const MEET_CHANNELS = [["google_meet", "Google Meet", "Google Meet"], ["phone", "Phone call", "مكالمة هاتفية"], ["in_person", "In person", "حضورياً"]];
function ScheduleMeetingModal({ opp, onClose, onDone, onErr }) {
  const { lang } = useLang(); const T = (ar, en) => oppT(lang, ar, en);
  const [date, setDate] = useOppState(""); const [time, setTime] = useOppState("11:00");
  const [channel, setChannel] = useOppState("google_meet"); const [note, setNote] = useOppState("");
  const [busy, setBusy] = useOppState(false); const [err, setErr] = useOppState("");
  const submit = async () => {
    if (!date) { setErr(T("اختر تاريخاً.", "Pick a date.")); return; }
    setBusy(true);
    try { await Actions.addOpportunityMeeting(opp.id, { date, time, channel, note }); onDone(); }
    catch (e) { setBusy(false); onErr && onErr(e); }
  };
  return (
    <Modal onClose={() => !busy && onClose()} style={{ width: 460 }}>
      <ModalHead title={T("تحديد اجتماع", "Schedule meeting")} onClose={onClose} />
      <div style={{ padding: 22 }}>
        <div className="row" style={{ gap: 12 }}>
          <Field label={T("التاريخ", "Date")}><input className="input" type="date" value={date} onChange={(e) => { setDate(e.target.value); setErr(""); }} /></Field>
          <Field label={T("الوقت", "Time")}><input className="input" type="time" value={time} onChange={(e) => setTime(e.target.value)} /></Field>
        </div>
        <Field label={T("القناة", "Channel")}><select className="select" value={channel} onChange={(e) => setChannel(e.target.value)}>{MEET_CHANNELS.map(([v, en, ar]) => <option key={v} value={v}>{lang === "ar" ? ar : en}</option>)}</select></Field>
        <Field label={T("ملاحظة", "Note")}><textarea className="textarea" rows={2} dir="auto" value={note} onChange={(e) => setNote(e.target.value)} /></Field>
        <ModalErr err={err} />
        <ModalFooter busy={busy} onClose={onClose} onSubmit={submit} icon="calendar" label={T("جدولة", "Schedule")} lang={lang} />
      </div>
    </Modal>
  );
}
function SendProposalModal({ opp, onClose, onDone, onErr }) {
  const { lang } = useLang(); const T = (ar, en) => oppT(lang, ar, en);
  const [title, setTitle] = useOppState(""); const [amount, setAmount] = useOppState(opp.estimatedValue || "");
  const [cur, setCur] = useOppState(window.MaxabCurrency.normalize(opp.currency));
  const [note, setNote] = useOppState(""); const [file, setFile] = useOppState(null);
  const [busy, setBusy] = useOppState(false); const [err, setErr] = useOppState("");
  const submit = async () => {
    if (!title.trim()) { setErr(T("أدخل عنوان العرض.", "Enter a proposal title.")); return; }
    setBusy(true);
    try { await Actions.addOpportunityProposal(opp.id, { title: title.trim(), amount: Number(amount) || 0, currency: cur, note, ...(file ? { fileName: file.name, fileSize: file.size, fileType: file.type } : {}) }); onDone(); }
    catch (e) { setBusy(false); onErr && onErr(e); }
  };
  return (
    <Modal onClose={() => !busy && onClose()} style={{ width: 480 }}>
      <ModalHead title={T("إرسال عرض", "Send proposal")} onClose={onClose} />
      <div style={{ padding: 22 }}>
        <Field label={T("عنوان العرض", "Proposal title")}><input className="input" autoFocus dir="auto" placeholder={T("مثال: تطوير متجر سلة", "e.g. Salla store revamp")} value={title} onChange={(e) => { setTitle(e.target.value); setErr(""); }} /></Field>
        <Field label={T("القيمة", "Amount")}><div className="row" style={{ gap: 8 }}><input className="input" type="number" min="0" value={amount} onChange={(e) => setAmount(e.target.value)} style={{ flex: 1 }} /><CurrencySelect value={cur} onChange={setCur} /></div></Field>
        <Field label={T("المرفق (PDF/مستند)", "Attachment (PDF/doc)")} hint={T("نخزّن اسم الملف وحجمه ونوعه فقط.", "We store the file name, size and type only.")}>
          <input className="input" type="file" onChange={(e) => setFile((e.target.files && e.target.files[0]) || null)} />
          {file && <div className="subtle" style={{ fontSize: 12, marginTop: 4 }}>📎 {file.name} · {Math.round((file.size || 0) / 1024)} KB</div>}
        </Field>
        <Field label={T("ملاحظة", "Note")}><textarea className="textarea" rows={2} dir="auto" value={note} onChange={(e) => setNote(e.target.value)} /></Field>
        <ModalErr err={err} />
        <ModalFooter busy={busy} onClose={onClose} onSubmit={submit} icon="send" label={T("إرسال العرض", "Send proposal")} lang={lang} />
      </div>
    </Modal>
  );
}
function AddFollowUpModal({ opp, onClose, onDone, onErr }) {
  const { lang } = useLang(); const T = (ar, en) => oppT(lang, ar, en);
  const [interest, setInterest] = useOppState("warm"); const [date, setDate] = useOppState(""); const [time, setTime] = useOppState("10:00");
  const [channel, setChannel] = useOppState("whatsapp"); const [priority, setPriority] = useOppState("medium"); const [note, setNote] = useOppState("");
  const [busy, setBusy] = useOppState(false); const [err, setErr] = useOppState("");
  const submit = async () => {
    if (!date) { setErr(T("اختر تاريخ التذكير.", "Pick a reminder date.")); return; }
    setBusy(true);
    try { await Actions.addOpportunityFollowUp(opp.id, { interest, date, time, channel, priority, note }); onDone(); }
    catch (e) { setBusy(false); onErr && onErr(e); }
  };
  return (
    <Modal onClose={() => !busy && onClose()} style={{ width: 480 }}>
      <ModalHead title={T("تذكير متابعة", "Follow-up reminder")} onClose={onClose} />
      <div style={{ padding: 22 }}>
        <Field label={T("اهتمام العميل", "Customer interest")} hint={T("يحدد الإجراء التالي وتوقيت المتابعة.", "Drives the suggested next action + timing.")}>
          <select className="select" value={interest} onChange={(e) => setInterest(e.target.value)}>{INTEREST_OPTS.map(([v, en, ar]) => <option key={v} value={v}>{lang === "ar" ? ar : en}</option>)}</select>
        </Field>
        <div className="row" style={{ gap: 12 }}>
          <Field label={T("التاريخ", "Date")}><input className="input" type="date" value={date} onChange={(e) => { setDate(e.target.value); setErr(""); }} /></Field>
          <Field label={T("الوقت", "Time")}><input className="input" type="time" value={time} onChange={(e) => setTime(e.target.value)} /></Field>
        </div>
        <div className="row" style={{ gap: 12 }}>
          <Field label={T("القناة", "Channel")}><select className="select" value={channel} onChange={(e) => setChannel(e.target.value)}><option value="whatsapp">WhatsApp</option><option value="call">{T("مكالمة", "Call")}</option><option value="email">{T("بريد", "Email")}</option></select></Field>
          <Field label={T("الأولوية", "Priority")}><select className="select" value={priority} onChange={(e) => setPriority(e.target.value)}><option value="high">{T("عالية", "High")}</option><option value="medium">{T("متوسطة", "Medium")}</option><option value="low">{T("منخفضة", "Low")}</option></select></Field>
        </div>
        <Field label={T("ملاحظة", "Note")}><textarea className="textarea" rows={2} dir="auto" value={note} onChange={(e) => setNote(e.target.value)} /></Field>
        <ModalErr err={err} />
        <ModalFooter busy={busy} onClose={onClose} onSubmit={submit} icon="clock" label={T("حفظ التذكير", "Save reminder")} lang={lang} />
      </div>
    </Modal>
  );
}
function LogRequestModal({ opp, onClose, onDone, onErr }) {
  const { lang } = useLang(); const T = (ar, en) => oppT(lang, ar, en);
  const [description, setDescription] = useOppState(""); const [category, setCategory] = useOppState("custom_feature");
  const [priority, setPriority] = useOppState("medium"); const [busy, setBusy] = useOppState(false); const [err, setErr] = useOppState("");
  const submit = async () => {
    if (!description.trim()) { setErr(T("صف الطلب.", "Describe the request.")); return; }
    setBusy(true);
    try { await Actions.addOpportunityRequest(opp.id, { description: description.trim(), category, categoryLabel: category, priority }); onDone(); }
    catch (e) { setBusy(false); onErr && onErr(e); }
  };
  return (
    <Modal onClose={() => !busy && onClose()} style={{ width: 480 }}>
      <ModalHead title={T("تسجيل طلب مخصص", "Log a custom request")} onClose={onClose} />
      <div style={{ padding: 22 }}>
        <Field label={T("وصف الطلب", "Request description")}><textarea className="textarea" rows={3} autoFocus dir="auto" placeholder={T("مثال: تكامل مع نظام المخزون", "e.g. Inventory-system integration")} value={description} onChange={(e) => { setDescription(e.target.value); setErr(""); }} /></Field>
        <div className="row" style={{ gap: 12 }}>
          <Field label={T("الفئة", "Category")}><input className="input" dir="auto" value={category} onChange={(e) => setCategory(e.target.value)} /></Field>
          <Field label={T("الأولوية", "Priority")}><select className="select" value={priority} onChange={(e) => setPriority(e.target.value)}><option value="high">{T("عالية", "High")}</option><option value="medium">{T("متوسطة", "Medium")}</option><option value="low">{T("منخفضة", "Low")}</option></select></Field>
        </div>
        <ModalErr err={err} />
        <ModalFooter busy={busy} onClose={onClose} onSubmit={submit} icon="inbox" label={T("تسجيل الطلب", "Log request")} lang={lang} />
      </div>
    </Modal>
  );
}
function MarkWonModal({ opp, onClose, onDone, onErr }) {
  const { lang } = useLang(); const T = (ar, en) => oppT(lang, ar, en);
  const [saleValue, setSaleValue] = useOppState(opp.estimatedValue || ""); const [closeNote, setCloseNote] = useOppState("");
  const [cur, setCur] = useOppState(window.MaxabCurrency.normalize(opp.currency));
  const [busy, setBusy] = useOppState(false); const [err, setErr] = useOppState("");
  const submit = async () => {
    if (!(Number(saleValue) > 0)) { setErr(T("أدخل قيمة البيع.", "Enter the sale value.")); return; }
    setBusy(true);
    try { await Actions.setOpportunityStatus(opp.id, { status: "won", saleValue: Number(saleValue), currency: cur, closeNote }); onDone(); }
    catch (e) { setBusy(false); onErr && onErr(e); }
  };
  return (
    <Modal onClose={() => !busy && onClose()} style={{ width: 440 }}>
      <ModalHead title={T("تسجيل فوز", "Mark as Won")} onClose={onClose} />
      <div style={{ padding: 22 }}>
        <p className="muted" style={{ fontSize: 13, marginBottom: 14 }}>{T("سيُحدّث العميل إلى \"فائز\" ويُضاف للهدف الشهري للوكيل.", "The contact becomes \"Won\" and this counts toward the agent's monthly target.")}</p>
        <Field label={T("قيمة البيع", "Sale value")}><div className="row" style={{ gap: 8 }}><input className="input" type="number" min="1" autoFocus value={saleValue} onChange={(e) => { setSaleValue(e.target.value); setErr(""); }} style={{ flex: 1 }} /><CurrencySelect value={cur} onChange={setCur} /></div></Field>
        <Field label={T("ملاحظة الإغلاق", "Closing note")}><textarea className="textarea" rows={2} dir="auto" value={closeNote} onChange={(e) => setCloseNote(e.target.value)} /></Field>
        <ModalErr err={err} />
        <ModalFooter busy={busy} onClose={onClose} onSubmit={submit} icon="checkcircle" label={T("تأكيد الفوز", "Confirm Won")} lang={lang} primaryColor="var(--color-success)" />
      </div>
    </Modal>
  );
}
function MarkLostModal({ opp, onClose, onDone, onErr }) {
  const { lang } = useLang(); const T = (ar, en) => oppT(lang, ar, en);
  const [lossReason, setLossReason] = useOppState(""); const [busy, setBusy] = useOppState(false); const [err, setErr] = useOppState("");
  const submit = async () => {
    if (!lossReason.trim()) { setErr(T("أدخل سبب الخسارة.", "Enter the loss reason.")); return; }
    setBusy(true);
    try { await Actions.setOpportunityStatus(opp.id, { status: "lost", lossReason: lossReason.trim() }); onDone(); }
    catch (e) { setBusy(false); onErr && onErr(e); }
  };
  return (
    <Modal onClose={() => !busy && onClose()} style={{ width: 440 }}>
      <ModalHead title={T("تسجيل خسارة", "Mark as Lost")} onClose={onClose} />
      <div style={{ padding: 22 }}>
        <Field label={T("سبب الخسارة", "Loss reason")}><textarea className="textarea" rows={3} autoFocus dir="auto" placeholder={T("مثال: اختار منافساً / الميزانية", "e.g. Chose a competitor / budget")} value={lossReason} onChange={(e) => { setLossReason(e.target.value); setErr(""); }} /></Field>
        <ModalErr err={err} />
        <ModalFooter busy={busy} onClose={onClose} onSubmit={submit} icon="ban" label={T("تأكيد الخسارة", "Confirm Lost")} lang={lang} primaryColor="var(--color-danger)" />
      </div>
    </Modal>
  );
}

function ModalHead({ title, onClose }) {
  return <div className="between" style={{ padding: "18px 22px", borderBottom: "1px solid var(--border-1)" }}><div style={{ fontWeight: 800, fontSize: 16 }}>{title}</div><button className="iconbtn" onClick={onClose}><Icon name="x" size={20} /></button></div>;
}
function ModalErr({ err }) {
  if (!err) return null;
  return <div className="row" style={{ gap: 8, padding: "10px 12px", background: "var(--color-danger-soft, #FEF2F2)", borderRadius: "var(--radius-sm)", marginBottom: 14 }}><Icon name="alert" size={16} style={{ color: "var(--color-danger)" }} /><span style={{ fontSize: 12.5, color: "var(--color-danger)" }}>{err}</span></div>;
}
function ModalFooter({ busy, onClose, onSubmit, icon, label, lang, primaryColor }) {
  const T = (ar, en) => oppT(lang, ar, en);
  return (
    <div className="row" style={{ gap: 10, justifyContent: "flex-end" }}>
      <Button variant="ghost" disabled={busy} onClick={onClose}>{T("إلغاء", "Cancel")}</Button>
      {primaryColor
        ? <button className="btn" style={{ background: primaryColor, color: "#fff" }} disabled={busy} onClick={onSubmit}>{busy ? <span className="spin" style={{ width: 15, height: 15 }} /> : <Icon name={icon} size={16} />}{label}</button>
        : <Button variant="primary" icon={busy ? null : icon} disabled={busy} onClick={onSubmit}>{busy ? <><span className="spin" style={{ width: 15, height: 15 }} />{T("جارٍ…", "Saving…")}</> : label}</Button>}
    </div>
  );
}
window.ScheduleMeetingModal = ScheduleMeetingModal;
window.SendProposalModal = SendProposalModal;
window.AddFollowUpModal = AddFollowUpModal;
window.LogRequestModal = LogRequestModal;
window.oppLinkedFor = linkedFor;

// ---- Meetings sub-tab screen (real meeting records) ---------------------
function MeetingsScreen() {
  const { lang } = useLang(); const data = useStore(); const { go } = useApp(); const T = (ar, en) => oppT(lang, ar, en);
  const meetings = (data.MEETINGS || []).slice().sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
  const today = new Date().toISOString().slice(0, 10);
  const upcoming = meetings.filter((m) => m.date && m.date >= today && !["cancelled", "completed", "no_show"].includes(m.status));
  return (
    <div className="content__inner content__inner--wide fade-up" style={{ maxWidth: 1100 }}>
      <div className="row" style={{ gap: 10, marginBottom: 16 }}>
        <h4>{T("الاجتماعات", "Meetings")}</h4>
        <span className="subtle" style={{ fontSize: 13 }}>{meetings.length} {T("اجتماع", "total")} · {upcoming.length} {T("قادمة", "upcoming")}</span>
      </div>
      {meetings.length === 0 ? (
        <Card><EmptyState icon="calendar" title={T("لا اجتماعات بعد", "No meetings yet")} body={T("الاجتماعات تُنشأ من لوحة المحادثة أو من درج الفرصة عبر \"تحديد اجتماع\".", "Meetings are created from the conversation panel or the opportunity drawer via \"Schedule meeting\".")} action={<Button variant="primary" icon="sparkles" onClick={() => go("opportunities")}>{T("عرض الفرص", "Go to opportunities")}</Button>} /></Card>
      ) : (
        <Card flush>
          {meetings.map((m) => {
            const c = contactById(m.contactId); const agent = agentById(m.agentId);
            const over = m.date && m.date < today && m.status === "scheduled";
            return (
              <div key={m.id} className="between" style={{ padding: "14px 18px", borderBottom: "1px solid var(--border-1)", gap: 12 }}>
                <div className="row" style={{ gap: 12, minWidth: 0 }}>
                  <span className="opp" style={{ width: 38, height: 38, borderRadius: 10, background: "var(--bg-2)", color: "var(--fg-3)", flexShrink: 0 }}><Icon name="calendar" size={17} /></span>
                  <div style={{ minWidth: 0 }}>
                    <div style={{ fontWeight: 700, fontSize: 14 }}>{(c && c.name) || "—"}</div>
                    <div className="subtle" style={{ fontSize: 12 }}>{m.date || "—"} {m.time || ""} · {m.channel === "google_meet" ? "Google Meet" : m.channel}{agent ? " · " + agent.name : ""}</div>
                  </div>
                </div>
                <Badge tone={over ? "red" : (m.status === "completed" ? "green" : "neutral")}>{over ? T("متأخر", "overdue") : m.status}</Badge>
              </div>
            );
          })}
        </Card>
      )}
    </div>
  );
}
window.MeetingsScreen = MeetingsScreen;

// ---- Support Tickets sub-tab (Customer Support AI Agent, Phase 3) -------
const TICKET_SEV = { critical: { tone: "red", c: "#B91C1C" }, high: { tone: "orange", c: "#EA580C" }, medium: { tone: "neutral", c: "#6B7280" }, low: { tone: "neutral", c: "#9CA3AF" } };
function SupportTicketsScreen() {
  const { lang } = useLang(); const data = useStore(); const T = (ar, en) => oppT(lang, ar, en);
  const [filter, setFilter] = useOppState("all");
  const [detail, setDetail] = useOppState(null);
  const [newOpen, setNewOpen] = useOppState(false);
  const [flash, toastNode] = useToast();
  React.useEffect(() => { Actions.loadSupportTickets(); }, []);
  const tickets = (data.SUPPORT_TICKETS || []);
  const rows = tickets.filter((t) => filter === "all" || (filter === "open" ? !["resolved", "closed"].includes(t.status) : t.severity === filter));
  const openCount = tickets.filter((t) => !["resolved", "closed"].includes(t.status)).length;
  const renewalRisk = tickets.filter((t) => ["high", "medium"].includes(t.renewalRisk) && !["resolved", "closed"].includes(t.status)).length;
  const chips = [["all", T("الكل", "All")], ["open", T("مفتوحة", "Open")], ["critical", T("حرجة", "Critical")], ["high", T("عالية", "High")]];
  const detailT = detail ? tickets.find((t) => t.id === detail) : null;
  return (
    <div className="content__inner content__inner--wide fade-up" style={{ maxWidth: 1100 }}>
      <div className="between wrap" style={{ marginBottom: 16, gap: 12 }}>
        <div className="row" style={{ gap: 10 }}><h4>{T("تذاكر الدعم", "Support tickets")}</h4><span className="subtle" style={{ fontSize: 13 }}>{openCount} {T("مفتوحة", "open")}{renewalRisk ? " · " + renewalRisk + " " + T("خطر تجديد", "renewal-risk") : ""}</span></div>
        <Button variant="primary" size="sm" icon="plus" onClick={() => setNewOpen(true)}>{T("تذكرة جديدة", "New ticket")}</Button>
      </div>
      {tickets.length === 0 ? (
        <Card><EmptyState icon="inbox" title={T("لا تذاكر دعم", "No support tickets")} body={T("تُنشأ التذاكر من لوحة المحادثة عندما يبلّغ عميل حالي عن مشكلة، أو يدوياً هنا.", "Tickets are created from the conversation panel when an existing customer reports an issue, or manually here.")} action={<Button variant="primary" icon="plus" onClick={() => setNewOpen(true)}>{T("تذكرة جديدة", "New ticket")}</Button>} /></Card>
      ) : (<>
        <div className="row wrap" style={{ gap: 8, marginBottom: 14 }}>
          {chips.map(([k, l]) => <button key={k} onClick={() => setFilter(k)} style={{ height: 32, padding: "0 14px", borderRadius: 999, fontSize: 13, fontWeight: 600, border: "1px solid " + (filter === k ? "var(--color-secondary)" : "var(--border-2)"), background: filter === k ? "var(--color-secondary)" : "#fff", color: filter === k ? "#fff" : "var(--fg-2)" }}>{l}</button>)}
        </div>
        <Card flush>
          {rows.map((t) => { const c = contactById(t.contactId); const sev = TICKET_SEV[t.severity] || TICKET_SEV.medium; return (
            <button key={t.id} onClick={() => setDetail(t.id)} className="between" style={{ width: "100%", textAlign: "start", padding: "14px 18px", borderBottom: "1px solid var(--border-1)", gap: 12, cursor: "pointer", background: "#fff" }}>
              <div className="row" style={{ gap: 12, minWidth: 0 }}>
                <span className="sdot" style={{ background: sev.c, width: 9, height: 9, flexShrink: 0 }} />
                <div style={{ minWidth: 0 }}>
                  <div style={{ fontWeight: 700, fontSize: 13.5 }}>{t.subject || t.categoryLabel || t.category}</div>
                  <div className="subtle" style={{ fontSize: 12 }}>{(c && c.name) || t.account || "—"} · {t.category}{t.renewalRisk && t.renewalRisk !== "none" ? " · " + T("خطر تجديد", "renewal risk") + " " + t.renewalRisk : ""}</div>
                </div>
              </div>
              <div className="row" style={{ gap: 8, flexShrink: 0 }}><Badge tone={sev.tone}>{t.severity}</Badge><Badge tone={["resolved", "closed"].includes(t.status) ? "green" : (t.status === "escalated" ? "orange" : "neutral")}>{t.status}</Badge></div>
            </button>
          ); })}
        </Card>
      </>)}
      {detailT && <SupportTicketDrawer ticket={detailT} onClose={() => setDetail(null)} onToast={flash} />}
      {newOpen && <NewTicketModal onClose={() => setNewOpen(false)} onCreated={() => { setNewOpen(false); flash(T("تم إنشاء التذكرة", "Ticket created")); }} onToast={flash} />}
      {toastNode}
    </div>
  );
}
window.SupportTicketsScreen = SupportTicketsScreen;

function SupportTicketDrawer({ ticket: t, onClose, onToast }) {
  const { lang } = useLang(); useStore(); const T = (ar, en) => oppT(lang, ar, en);
  const [busy, setBusy] = useOppState(false); const [note, setNote] = useOppState("");
  const c = contactById(t.contactId);
  const SEVS = ["low", "medium", "high", "critical"]; const STATS = ["new", "in_progress", "waiting_customer", "escalated", "resolved", "closed"];
  const set = async (patch) => { setBusy(true); try { await Actions.updateSupportTicket(t.id, patch); onToast(T("تم التحديث", "Updated")); } catch (e) { onToast(T("تعذّر", "Failed")); } finally { setBusy(false); } };
  const acts = t.nextActions || [];
  return (
    <Drawer onClose={onClose}>
      <DrawerHead title={t.subject || t.categoryLabel || t.category} sub={`${(c && c.name) || t.account || ""} · ${t.category}`} onClose={onClose} right={<Badge tone={(TICKET_SEV[t.severity] || {}).tone || "neutral"}>{t.severity}</Badge>} />
      <div style={{ overflowY: "auto", padding: 24, display: "flex", flexDirection: "column", gap: 16, flex: 1 }}>
        {t.description && <Card title={T("الوصف", "Description")}><p style={{ fontSize: 13.5, lineHeight: 1.55 }}>{t.description}</p></Card>}
        {acts.length > 0 && <Card title={T("الإجراء التالي", "Next actions")}><div className="col" style={{ gap: 6 }}>{acts.map((a, i) => <div key={i} className="row" style={{ gap: 7, fontSize: 12.5 }}><Icon name="arrowRight" size={13} style={{ color: "var(--color-secondary)" }} />{lang === "ar" ? a.ar : a.en}</div>)}</div></Card>}
        <Card title={T("التفاصيل", "Details")}>
          <KVOpp k={T("الفئة", "Category")} v={t.category} />
          <KVOpp k={T("نوع الاشتراك/الترخيص", "Subscription/license")} v={t.subscriptionType || "—"} />
          <KVOpp k={T("خطر التجديد", "Renewal risk")} v={<Badge tone={["high", "medium"].includes(t.renewalRisk) ? "red" : "neutral"}>{t.renewalRisk || "none"}</Badge>} />
          <KVOpp k={T("أثر على الإيراد", "Impact on revenue")} v={t.impactOnRevenue ? T("نعم", "Yes") : T("لا", "No")} />
          <KVOpp k={T("تصعيد مطلوب", "Escalation required")} v={t.escalationRequired ? T("نعم", "Yes") : T("لا", "No")} />
        </Card>
        <Card title={T("النشاط", "History")}><div className="col" style={{ gap: 8 }}>{(t.history || []).slice().reverse().slice(0, 10).map((h, i) => <div key={i} style={{ fontSize: 12 }}><b>{h.action}</b> · {h.detail} <span className="subtle">({new Date(h.at).toLocaleString()})</span></div>)}</div></Card>
      </div>
      <div style={{ borderTop: "1px solid var(--border-1)", background: "#fff", padding: 16 }}>
        <div className="row" style={{ gap: 10, marginBottom: 10 }}>
          <Field label={T("الحالة", "Status")}><select className="select" disabled={busy} value={t.status} onChange={(e) => set({ status: e.target.value })}>{STATS.map((s) => <option key={s} value={s}>{s}</option>)}</select></Field>
          <Field label={T("الخطورة", "Severity")}><select className="select" disabled={busy} value={t.severity} onChange={(e) => set({ severity: e.target.value })}>{SEVS.map((s) => <option key={s} value={s}>{s}</option>)}</select></Field>
        </div>
        <div className="row" style={{ gap: 8 }}>
          <input className="input" placeholder={T("أضف ملاحظة…", "Add a note…")} value={note} onChange={(e) => setNote(e.target.value)} style={{ flex: 1 }} />
          <Button variant="ghost" size="sm" disabled={busy || !note.trim()} onClick={() => { set({ note: note.trim() }); setNote(""); }}>{T("إضافة", "Add")}</Button>
          {!["resolved", "closed"].includes(t.status) && <Button variant="dark" size="sm" icon="checkcircle" disabled={busy} onClick={() => set({ status: "resolved" })}>{T("حل", "Resolve")}</Button>}
        </div>
      </div>
    </Drawer>
  );
}

const TICKET_CATS = ["login", "payment", "whatsapp_integration", "ai_agent", "conversation", "opportunity_pipeline", "proposal", "deployment", "source_code_setup", "training_data", "server", "billing", "general"];
function NewTicketModal({ onClose, onCreated, onToast }) {
  const { lang } = useLang(); const data = useStore(); const T = (ar, en) => oppT(lang, ar, en);
  const [q, setQ] = useOppState(""); const [picked, setPicked] = useOppState(null);
  const [category, setCategory] = useOppState("general"); const [severity, setSeverity] = useOppState("medium");
  const [subject, setSubject] = useOppState(""); const [description, setDescription] = useOppState(""); const [busy, setBusy] = useOppState(false);
  const matches = (data.CONTACTS || []).filter((c) => { const s = (q || "").toLowerCase(); return !s || (c.name || "").toLowerCase().includes(s); }).slice(0, 20);
  const submit = async () => {
    if (!picked || !subject.trim()) return; setBusy(true);
    try { await Actions.createSupportTicket({ contactId: picked.id, category, severity, subject: subject.trim(), description: description.trim(), by: "operator" }); onCreated(); }
    catch (e) { onToast(T("تعذّر", "Failed")); setBusy(false); }
  };
  return (
    <Modal onClose={() => !busy && onClose()} style={{ width: 520 }}>
      <ModalHead title={T("تذكرة دعم جديدة", "New support ticket")} onClose={onClose} />
      <div style={{ padding: 22 }}>
        <Field label={T("العميل", "Customer")}><input className="input" autoFocus placeholder={T("ابحث…", "Search…")} value={q} onChange={(e) => { setQ(e.target.value); setPicked(null); }} /></Field>
        <div className="col" style={{ gap: 6, maxHeight: 180, overflowY: "auto", marginBottom: 8 }}>
          {matches.map((c) => <button key={c.id} onClick={() => setPicked(c)} className="row" style={{ gap: 8, padding: "8px 10px", borderRadius: 8, border: "1px solid " + (picked && picked.id === c.id ? "var(--color-secondary)" : "var(--border-1)"), background: picked && picked.id === c.id ? "var(--color-primary-tint-soft)" : "#fff", cursor: "pointer", textAlign: "start" }}><b style={{ fontSize: 13 }}>{c.name}</b>{["won", "delivered"].includes(c.status) && <Badge tone="green">{T("عميل", "customer")}</Badge>}</button>)}
        </div>
        <div className="row" style={{ gap: 12 }}>
          <Field label={T("الفئة", "Category")}><select className="select" value={category} onChange={(e) => setCategory(e.target.value)}>{TICKET_CATS.map((c) => <option key={c} value={c}>{c}</option>)}</select></Field>
          <Field label={T("الخطورة", "Severity")}><select className="select" value={severity} onChange={(e) => setSeverity(e.target.value)}>{["low", "medium", "high", "critical"].map((s) => <option key={s} value={s}>{s}</option>)}</select></Field>
        </div>
        <Field label={T("الموضوع", "Subject")}><input className="input" dir="auto" value={subject} onChange={(e) => setSubject(e.target.value)} /></Field>
        <Field label={T("الوصف", "Description")}><textarea className="textarea" rows={3} dir="auto" value={description} onChange={(e) => setDescription(e.target.value)} /></Field>
        <ModalFooter busy={busy} onClose={onClose} onSubmit={submit} icon="inbox" label={T("إنشاء التذكرة", "Create ticket")} lang={lang} />
      </div>
    </Modal>
  );
}

// ---- Per-contact opportunity card for the lead drawer -------------------
function OppContactCard({ contact: c }) {
  const { lang } = useLang(); const { go } = useApp(); useStore(); const T = (ar, en) => oppT(lang, ar, en);
  const [busy, setBusy] = useOppState(false);
  const [flagErr, setFlagErr] = useOppState(false);
  const opps = opportunitiesForContact(c.id);
  // On success we navigate to the pipeline (component unmounts); on failure we surface
  // an inline error and re-enable the button (no silent dead state).
  const flagOpp = async () => { setBusy(true); setFlagErr(false); try { await Actions.createOpportunity({ contactId: c.id }); go("opportunities"); } catch (e) { setFlagErr(true); setBusy(false); } };
  return (
    <Card>
      <div className="between" style={{ marginBottom: 12 }}>
        <div className="row" style={{ gap: 8 }}><Icon name="sparkles" size={16} style={{ color: "var(--fg-3)" }} /><b style={{ fontSize: 14 }}>{T("الفرص", "Opportunities")}</b><span className="subtle" style={{ fontSize: 12 }}>{opps.length}</span></div>
        {opps.length > 0 && <Button variant="ghost" size="sm" iconEnd="chevronRight" onClick={() => go("opportunities")}>{T("عرض الكل", "View all")}</Button>}
      </div>
      {opps.length === 0 ? (
        <div className="col" style={{ gap: 10 }}>
          <p className="muted" style={{ fontSize: 12.5 }}>{T("لا توجد فرصة لهذا العميل بعد.", "No opportunity for this contact yet.")}</p>
          {flagErr && <span style={{ fontSize: 12, color: "var(--color-danger)" }}>{T("تعذّر إنشاء الفرصة — حاول مرة أخرى.", "Couldn't create the opportunity — try again.")}</span>}
          <Button variant="primary" size="sm" icon={busy ? null : "plus"} disabled={busy} onClick={flagOpp}>{busy ? <span className="spin" style={{ width: 14, height: 14 }} /> : T("إنشاء فرصة", "Flag as opportunity")}</Button>
        </div>
      ) : (
        <div className="col" style={{ gap: 10 }}>
          {opps.map((o) => (
            <div key={o.id} className="between" style={{ padding: "10px 12px", background: "var(--bg-2)", borderRadius: 10, gap: 10 }}>
              <div style={{ minWidth: 0 }}>
                <div className="row" style={{ gap: 7 }}><Badge tone="dark">{svcLabel(o.service)}</Badge><OppStatusBadge status={o.status} /></div>
                <div style={{ fontSize: 12.5, fontWeight: 700, marginTop: 5 }}>{o.estimatedValue ? fmtMoney(o.estimatedValue, lang, o.currency) + T("/شهر", "/mo") : "—"}{o.status === "won" && o.saleValue ? " · " + T("بيع ", "sold ") + fmtMoney(o.saleValue, lang, o.currency) : ""}</div>
              </div>
              <span className="opp" style={{ width: 30, height: 30, borderRadius: 8, background: "var(--color-primary-tint)", color: "var(--color-secondary)", fontWeight: 800, fontSize: 12, flexShrink: 0 }}>{o.score}</span>
            </div>
          ))}
        </div>
      )}
    </Card>
  );
}
window.OppContactCard = OppContactCard;
