// dashboard-platform-health-modal.js — extracted verbatim from dashboard.js (classic script,
// shared global scope). Loaded before dashboard.js. Pure move, no logic change.

// ── Platform Health → event detail modal ─────────────────────────
//
// Click a row in "Recent inbound" or "Recent outbound" inside the platform
// lane drawer → opens a modal that shows the FULL message text, who-from
// → who-to with both sides' identifiers, and platform-aware deep links so
// the operator can jump straight to the exact tweet / DM thread / email
// thread they're looking at. Designed to be opinionated about one thing:
// "where do I see this on the platform itself?".

// Visual identity per platform — used to tint the modal hero so the
// operator instantly recognises which surface they're looking at.
const PLATFORM_IDENTITY = {
  x: {
    icon: "bird",
    name: "X",
    accent: "#1d9bf0",
    inboxLabel: "X Direct Messages",
    inboxUrl: "https://x.com/messages",
  },
  twitter: {
    icon: "bird",
    name: "Twitter",
    accent: "#1d9bf0",
    inboxLabel: "X Direct Messages",
    inboxUrl: "https://x.com/messages",
  },
  linkedin: {
    icon: "link",
    name: "LinkedIn",
    accent: "#0a66c2",
    inboxLabel: "LinkedIn Messaging",
    inboxUrl: "https://www.linkedin.com/messaging/",
  },
  telegram: {
    icon: "✈",
    name: "Telegram",
    accent: "#229ED9",
    inboxLabel: "Telegram",
    inboxUrl: "https://web.telegram.org/",
  },
  email: { icon: "mail", name: "Email", accent: "#34d399", inboxLabel: "Inbox", inboxUrl: null },
};

function platformIdentity(platform) {
  return (
    PLATFORM_IDENTITY[(platform || "").toLowerCase()] || {
      icon: "•",
      name: platform || "Platform",
      accent: "var(--accent)",
      inboxLabel: "Inbox",
      inboxUrl: null,
    }
  );
}

// Strip @ from handles and trailing slashes from URLs.
function _normHandle(h) {
  return String(h || "")
    .replace(/^@+/, "")
    .trim();
}
function _normUrl(u) {
  return String(u || "").replace(/\/+$/, "");
}

// Per-platform deep-link builder. Returns an array of { label, href, primary }
// — the modal renders these as buttons. We aim for the *most specific* link
// available; fall back to the platform inbox if all we have is "we sent
// something on LinkedIn".
function buildPlatformDeepLinks(ev) {
  const p = (ev.platform || "").toLowerCase();
  const links = [];
  const id = platformIdentity(p);

  // 1. If we captured a post URL during the send, that's the most specific
  //    pointer we have — always show it as the primary.
  if (ev.post_url) {
    links.push({
      label: `Open on ${id.name}`,
      href: ev.post_url,
      primary: true,
      hint: "Direct link captured at send-time",
    });
  }

  if (p === "linkedin") {
    // LinkedIn message threads use a URN format we sometimes capture in
    // platform_message_id. urn:li:fsd_thread:abc → /messaging/thread/abc/
    if (ev.platform_message_id) {
      const threadId = String(ev.platform_message_id).split(":").pop();
      if (threadId && threadId.length > 4) {
        links.push({
          label: "Open thread on LinkedIn",
          href: `https://www.linkedin.com/messaging/thread/${encodeURIComponent(threadId)}/`,
          primary: !ev.post_url,
        });
      }
    }
    if (ev.contact?.linkedin_url) {
      links.push({
        label: "Open recipient profile",
        href: ev.contact.linkedin_url,
        primary: false,
      });
    }
    if (links.length === 0)
      links.push({ label: "Open LinkedIn Messaging", href: id.inboxUrl, primary: true });
  } else if (p === "x" || p === "twitter") {
    const handle = _normHandle(ev.to_handle || ev.contact?.twitter_handle);
    if (handle) {
      links.push({
        label: `@${handle} on X`,
        href: `https://x.com/${encodeURIComponent(handle)}`,
        primary: !ev.post_url,
      });
      // Composer pre-fills a DM target — useful when you want to follow up.
      links.push({
        label: "Compose DM",
        href: `https://x.com/messages/compose?recipient_id=${encodeURIComponent(handle)}`,
        primary: false,
        hint: "Opens X with the recipient prefilled — needs the user_id, falls back to handle",
      });
    }
    if (links.length === 0)
      links.push({ label: "Open X Direct Messages", href: id.inboxUrl, primary: true });
  } else if (p === "telegram") {
    const u = _normHandle(ev.to_handle || ev.contact?.telegram_username);
    if (u) {
      links.push({
        label: `@${u} on Telegram (web)`,
        href: `https://t.me/${encodeURIComponent(u)}`,
        primary: !ev.post_url,
      });
      links.push({
        label: "Open in Telegram desktop app",
        href: `tg://resolve?domain=${encodeURIComponent(u)}`,
        primary: false,
        hint: "Requires the desktop client",
      });
    }
    if (links.length === 0)
      links.push({ label: "Open Telegram Web", href: id.inboxUrl, primary: true });
  } else if (p === "email") {
    const addr = (ev.to_handle || ev.contact?.email || "").trim();
    if (addr) {
      // Gmail web search by address — usually surfaces the thread instantly
      // when the operator is logged into the Gmail tab they sent from.
      links.push({
        label: `Search Gmail for ${addr}`,
        href: `https://mail.google.com/mail/u/0/#search/${encodeURIComponent(addr)}`,
        primary: !ev.post_url,
      });
      links.push({
        label: "Compose new email",
        href: `mailto:${encodeURIComponent(addr)}`,
        primary: false,
      });
    }
    if (links.length === 0)
      links.push({ label: "Open Gmail", href: "https://mail.google.com/mail/u/0/", primary: true });
  }

  return links;
}

// The creative bit — render a chat-style bubble that mimics the platform's
// own UI tone (color-tinted accent + platform icon avatar). Outbound bubbles
// flush right, inbound flush left, just like a real messaging app.
function _renderEventBubble(ev) {
  const isOutbound = ev.kind === "outreach_sent" || ev.kind === "sent";
  const id = platformIdentity(ev.platform);
  const text = ev.full_text || ev.what || "(no content captured)";
  const align = isOutbound ? "flex-end" : "flex-start";
  const bubbleBg = isOutbound ? id.accent : "var(--bg-2)";
  const bubbleFg = isOutbound ? "white" : "var(--text-1)";
  const radius = isOutbound ? "12px 12px 2px 12px" : "12px 12px 12px 2px";

  return el(
    "div",
    { style: `display:flex;flex-direction:column;align-items:${align};gap:4px;margin:14px 0;` },
    [
      el("div", { class: "muted small", style: `display:flex;align-items:center;gap:6px;` }, [
        icon.for(id.icon) ? icon(icon.for(id.icon)) : el("span", {}, id.icon),
        el(
          "span",
          {},
          isOutbound
            ? `from ${ev.from_account || "your account"} → ${ev.who || "recipient"}`
            : `from ${ev.who || "sender"} → you`,
        ),
      ]),
      el(
        "div",
        {
          style: `max-width:88%;padding:10px 14px;background:${bubbleBg};color:${bubbleFg};border-radius:${radius};font-size:13px;line-height:1.5;white-space:pre-wrap;word-break:break-word;box-shadow:0 1px 2px rgba(0,0,0,0.2);`,
        },
        text,
      ),
      el("div", { class: "muted small mono" }, fmtDate(ev.ts)),
    ],
  );
}

// The full modal.
function openEventDetailModal(ev) {
  const id = platformIdentity(ev.platform);
  const isOutbound = ev.kind === "outreach_sent" || ev.kind === "sent";
  const links = buildPlatformDeepLinks(ev);

  // Modal lives outside the existing right-side drawer so we don't clobber
  // open contact/company drawers — operators often open the event detail
  // *while* a contact drawer is up.
  const overlay = el("div", {
    class: "event-detail-overlay",
    style:
      "position:fixed;inset:0;background:rgba(0,0,0,0.6);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);z-index:500;display:flex;align-items:center;justify-content:center;padding:24px;",
    onclick: (e) => {
      if (e.target === e.currentTarget) overlay.remove();
    },
  });

  const card = el("div", {
    style: `width:560px;max-width:100%;max-height:88vh;display:flex;flex-direction:column;background:var(--bg-1);border:1px solid ${id.accent}33;border-top:3px solid ${id.accent};border-radius:var(--radius-lg);box-shadow:0 24px 64px rgba(0,0,0,0.5);overflow:hidden;animation:cmdkIn 0.18s cubic-bezier(0.16, 1, 0.3, 1);`,
  });

  // Header — platform-tinted hero strip.
  card.appendChild(
    el(
      "div",
      {
        style: `padding:16px 20px;background:linear-gradient(135deg, ${id.accent}22, ${id.accent}08);border-bottom:1px solid var(--border);display:flex;align-items:center;gap:12px;`,
      },
      [
        el(
          "div",
          {
            style: `font-size:24px;width:42px;height:42px;border-radius:50%;background:${id.accent}22;display:flex;align-items:center;justify-content:center;`,
          },
          id.icon,
        ),
        el("div", { style: "flex:1;min-width:0;" }, [
          el(
            "div",
            {
              style:
                "font-size:11px;text-transform:uppercase;letter-spacing:0.08em;color:var(--text-3);font-weight:600;",
            },
            isOutbound ? `${id.name} · sent` : `${id.name} · received`,
          ),
          el(
            "div",
            {
              style:
                "font-size:15px;font-weight:600;color:var(--text-1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;",
            },
            isOutbound
              ? `You sent a message to ${ev.who || "(unknown)"}`
              : `${ev.who || "(unknown)"} ${ev.kind === "inbound" ? "messaged you" : "replied"}`,
          ),
          ev.who_company ? el("div", { class: "muted small" }, ev.who_company) : null,
        ]),
        el(
          "button",
          { type: "button", class: "icon-btn", title: "Close", onclick: () => overlay.remove() },
          "×",
        ),
      ],
    ),
  );

  // Body — scrollable message area.
  const body = el("div", { style: "flex:1;overflow-y:auto;padding:8px 20px 20px;" });

  body.appendChild(_renderEventBubble(ev));

  // Inbound enrichment: intent + sentiment chips when present.
  if (!isOutbound && (ev.intent || ev.sentiment)) {
    body.appendChild(
      el("div", { style: "display:flex;gap:6px;flex-wrap:wrap;margin:0 0 14px;" }, [
        ev.intent ? el("span", { class: "badge badge-purple" }, `intent: ${ev.intent}`) : null,
        ev.sentiment
          ? el("span", { class: "badge badge-blue" }, `sentiment: ${ev.sentiment}`)
          : null,
        ev.is_handled ? el("span", { class: "badge badge-green" }, "handled") : null,
      ]),
    );
  }

  // "Where to see this" — the creative payload of the modal. A glass card
  // with a stack of platform-aware deep links plus the always-on "Open in
  // CRM" jump. Each link explains what it actually opens (real URL deep
  // links beat a generic "View on platform" button — no surprises).
  const seeWrap = el(
    "div",
    {
      style: `border:1px solid ${id.accent}33;background:${id.accent}0a;border-radius:var(--radius-md);padding:14px;margin-bottom:14px;`,
    },
    [
      el("div", { style: "display:flex;align-items:center;gap:8px;margin-bottom:10px;" }, [
        el("span", { style: `width:6px;height:6px;border-radius:50%;background:${id.accent};` }),
        el(
          "div",
          {
            style:
              "font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-2);",
          },
          "Where to see this",
        ),
      ]),
    ],
  );
  for (const link of links) {
    const a = el(
      "a",
      {
        href: link.href,
        target: link.href?.startsWith("tg://") ? "_self" : "_blank",
        rel: "noopener noreferrer",
        style: `display:flex;align-items:center;gap:10px;padding:10px 12px;background:${link.primary ? id.accent : "var(--bg-2)"};color:${link.primary ? "white" : "var(--text-1)"};border-radius:var(--radius-sm);font-size:12px;font-weight:500;text-decoration:none;margin-bottom:6px;transition:transform 100ms ease-out;`,
        onmouseenter: (e) => {
          e.currentTarget.style.transform = "translateX(2px)";
        },
        onmouseleave: (e) => {
          e.currentTarget.style.transform = "";
        },
        onclick: () => {
          setTimeout(() => overlay.remove(), 50);
        },
        title: link.hint || "",
      },
      [
        el(
          "span",
          { style: "flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" },
          link.label,
        ),
        el("span", { style: "font-size:11px;opacity:0.7;" }, "↗"),
      ],
    );
    seeWrap.appendChild(a);
  }
  body.appendChild(seeWrap);

  // "Where it lives in the CRM" — the matching half. Always visible so the
  // operator can jump from an event to the contact / campaign / deal in one
  // hop without thinking.
  const crmWrap = el(
    "div",
    {
      style:
        "border:1px solid var(--border);background:var(--bg-2);border-radius:var(--radius-md);padding:14px;margin-bottom:14px;",
    },
    [
      el("div", { style: "display:flex;align-items:center;gap:8px;margin-bottom:10px;" }, [
        el("span", { style: "width:6px;height:6px;border-radius:50%;background:var(--accent);" }),
        el(
          "div",
          {
            style:
              "font-weight:600;font-size:12px;text-transform:uppercase;letter-spacing:0.06em;color:var(--text-2);",
          },
          "In your CRM",
        ),
      ]),
    ],
  );
  const crmActions = [];
  if (ev.contact?.id || ev.drillTo?.type === "contact") {
    const cid = ev.contact?.id || ev.drillTo?.id;
    crmActions.push({
      label: `Open contact: ${ev.who || `#${cid}`}`,
      onclick: () => {
        overlay.remove();
        showContactDrawer(cid);
      },
    });
  }
  if (ev.campaign_id) {
    crmActions.push({
      label: `Open campaign #${ev.campaign_id}`,
      onclick: () => {
        overlay.remove();
        navigate(`campaigns/outreach/${ev.campaign_id}`);
      },
    });
  }
  if (crmActions.length === 0) {
    crmWrap.appendChild(el("div", { class: "muted small" }, "No CRM entity linked to this event."));
  } else {
    for (const action of crmActions) {
      crmWrap.appendChild(
        el(
          "button",
          {
            type: "button",
            style:
              "display:flex;align-items:center;gap:10px;width:100%;padding:10px 12px;background:var(--bg-1);color:var(--text-1);border:1px solid var(--border);border-radius:var(--radius-sm);font-size:12px;font-weight:500;cursor:pointer;margin-bottom:6px;font-family:inherit;text-align:left;",
            onclick: action.onclick,
          },
          [
            el("span", { style: "flex:1;" }, action.label),
            el("span", { style: "font-size:11px;color:var(--text-3);" }, "→"),
          ],
        ),
      );
    }
  }
  body.appendChild(crmWrap);

  // Footer toolbar — copy + send-time metadata.
  const footer = el(
    "div",
    {
      style:
        "padding:10px 20px;border-top:1px solid var(--border);background:var(--bg-0);display:flex;gap:8px;align-items:center;font-size:11px;",
    },
    [
      el(
        "button",
        {
          type: "button",
          class: "btn btn-tiny btn-secondary",
          onclick: async () => {
            try {
              await navigator.clipboard.writeText(ev.full_text || ev.what || "");
              toast("Copied to clipboard", "ok", 1500);
            } catch {
              toast("Copy failed", "err");
            }
          },
        },
        "Copy text",
      ),
      isOutbound && ev.from_account
        ? el("span", { class: "muted small mono" }, `via ${ev.from_account}`)
        : null,
      el("span", { style: "flex:1;" }),
      el("span", { class: "muted small mono" }, ev.source || ""),
    ],
  );

  card.appendChild(body);
  card.appendChild(footer);
  overlay.appendChild(card);
  document.body.appendChild(overlay);

  // Esc closes — local handler so it doesn't conflict with global Esc.
  const escHandler = (e) => {
    if (e.key === "Escape") {
      overlay.remove();
      document.removeEventListener("keydown", escHandler);
    }
  };
  document.addEventListener("keydown", escHandler);
  overlay.addEventListener("click", (e) => {
    if (e.target === overlay) document.removeEventListener("keydown", escHandler);
  });
}

// Pretty labels + icons for enrichment task types. The enrichment_queue
// task_type CHECK was dropped in v53, so new task types can show up — fall
// back to the raw string for any not in this map.
const ENRICHMENT_TASK_LABELS = {
  find_contact_email: { icon: "mail", label: "Find email" },
  enrich_contact_linkedin: { icon: "link", label: "Enrich LinkedIn" },
  discover_employees: { icon: "users", label: "Discover employees" },
  find_tg_group: { icon: "message", label: "Find Telegram group" },
  scrape_admins: { icon: "lock", label: "Scrape admins" },
  find_twitter: { icon: "bird", label: "Find Twitter" },
  find_linkedin: { icon: "link", label: "Find LinkedIn" },
  ai_summary: { icon: "bot", label: "AI summary" },
  enrich_company: { icon: "building", label: "Enrich company" },
};

function enrichmentTaskBadge(task_type) {
  const meta = ENRICHMENT_TASK_LABELS[task_type] || { icon: "settings", label: task_type };
  return el(
    "span",
    { class: "badge badge-purple", style: "font-size:10px;" },
    `${icon.for(meta.icon) ? iconHtml(icon.for(meta.icon)) : meta.icon} ${meta.label}`,
  );
}

// Drawer that answers "which contacts/companies got enriched?". Lists the
// most recent enrichment_queue rows for the chosen status, with a clickable
// entity link, the task type, and the timestamp. Tabs let the operator
// switch between Completed / Pending / Failed without leaving the drawer.
async function openEnrichmentDrawer(initialStatus = "completed") {
  let activeStatus = initialStatus;
  // Cache responses per status so flipping tabs is instant after the first load.
  const cache = {};

  async function loadStatus(status) {
    if (cache[status]) return cache[status];
    const data = await api("crm-enrichment-recent", {
      queryString: `?status=${encodeURIComponent(status)}&limit=80`,
    }).catch(() => ({}));
    cache[status] = data || { tasks: [], stats: {}, total: 0 };
    return cache[status];
  }

  function renderBody() {
    const drawerBody = $("#drawer-body");
    if (!drawerBody) return;
    drawerBody.innerHTML = "";
    drawerBody.appendChild(el("div", { class: "muted small" }, "Loading…"));

    loadStatus(activeStatus).then((data) => {
      const stats = data.stats || {};
      const tasks = data.tasks || [];
      const body = el("div", {});

      // Header stats — same numbers the queue bar shows, no extra fetch.
      body.appendChild(
        el("div", { class: "row", style: "gap:14px;flex-wrap:wrap;margin-bottom:14px;" }, [
          el("div", {}, [
            el("div", { class: "muted small" }, "Pending"),
            el("div", { style: "font-size:18px;font-weight:600;" }, String(stats.pending || 0)),
          ]),
          el("div", {}, [
            el("div", { class: "muted small" }, "Running"),
            el(
              "div",
              { style: "font-size:18px;font-weight:600;color:var(--blue);" },
              String(stats.running || 0),
            ),
          ]),
          el("div", {}, [
            el("div", { class: "muted small" }, "Done 24h"),
            el(
              "div",
              { style: "font-size:18px;font-weight:600;color:var(--green);" },
              String(stats.completed_24h || 0),
            ),
          ]),
          el("div", {}, [
            el("div", { class: "muted small" }, "Failed 24h"),
            el(
              "div",
              { style: "font-size:18px;font-weight:600;color:var(--red);" },
              String(stats.failed_24h || 0),
            ),
          ]),
        ]),
      );

      // Tabs: completed (default) | pending | running | failed.
      const STATUSES = [
        { id: "completed", label: "Completed" },
        { id: "pending", label: "Pending" },
        { id: "running", label: "Running" },
        { id: "failed", label: "Failed" },
      ];
      body.appendChild(
        el(
          "div",
          { class: "tabs", style: "margin-bottom:12px;" },
          STATUSES.map((s) =>
            el(
              "button",
              {
                class: `tab${activeStatus === s.id ? " active" : ""}`,
                type: "button",
                onclick: () => {
                  activeStatus = s.id;
                  renderBody();
                },
              },
              s.label,
            ),
          ),
        ),
      );

      // Task list.
      if (tasks.length === 0) {
        body.appendChild(
          el("div", { class: "empty-state" }, [
            el("div", { class: "empty-state-icon" }, icon("bolt")),
            el("div", { class: "empty-state-title" }, `No ${activeStatus} enrichment tasks`),
            el(
              "div",
              { class: "empty-state-hint" },
              activeStatus === "completed"
                ? "Tasks completed in the last 24 hours will appear here."
                : `Nothing currently ${activeStatus}.`,
            ),
          ]),
        );
      } else {
        body.appendChild(
          el(
            "div",
            { class: "muted small", style: "margin-bottom:8px;" },
            `${tasks.length} of ${data.total || tasks.length} task${tasks.length === 1 ? "" : "s"}`,
          ),
        );
        for (const t of tasks) {
          // Resolve the entity name + open handler. Companies take precedence
          // when both ids are set (rare — usually one or the other).
          let entityNode;
          if (t.company_id && t.company_name) {
            entityNode = el(
              "a",
              {
                class: "company-link",
                onclick: (e) => {
                  e.stopPropagation();
                  closeDrawer();
                  setTimeout(() => openCompanyDrawerById(t.company_id), 200);
                },
                title: "Open company",
              },
              `${t.company_name}`,
            );
          } else if (t.contact_id && t.contact_name) {
            entityNode = el(
              "a",
              {
                class: "company-link",
                onclick: (e) => {
                  e.stopPropagation();
                  closeDrawer();
                  setTimeout(() => showContactDrawer(t.contact_id), 200);
                },
                title: "Open contact",
              },
              `${t.contact_name}${t.contact_company ? ` · ${t.contact_company}` : ""}`,
            );
          } else if (t.company_id) {
            entityNode = el(
              "span",
              { class: "muted small" },
              `🏢 (deleted company #${t.company_id})`,
            );
          } else if (t.contact_id) {
            entityNode = el(
              "span",
              { class: "muted small" },
              `👤 (deleted contact #${t.contact_id})`,
            );
          } else {
            entityNode = el("span", { class: "muted small" }, "(no entity)");
          }

          const meta = el("div", { class: "row", style: "gap:8px;align-items:center;" }, [
            enrichmentTaskBadge(t.task_type),
            t.attempts > 1 ? el("span", { class: "muted small" }, `attempt ${t.attempts}`) : null,
          ]);

          const row = el(
            "div",
            {
              class: "field-row",
              style: "align-items:flex-start;flex-direction:column;gap:4px;padding:10px 0;",
            },
            [
              el(
                "div",
                {
                  class: "row",
                  style: "justify-content:space-between;width:100%;align-items:center;gap:8px;",
                },
                [
                  entityNode,
                  el("span", { class: "muted small mono" }, fmtDate(t.updated_at || t.created_at)),
                ],
              ),
              meta,
              t.last_error
                ? el(
                    "div",
                    {
                      class: "muted small",
                      style:
                        "color:var(--red);font-family:var(--font-mono);font-size:10px;line-height:1.4;",
                    },
                    t.last_error.slice(0, 200),
                  )
                : null,
            ],
          );
          body.appendChild(row);
        }
      }

      drawerBody.innerHTML = "";
      drawerBody.appendChild(body);
    });
  }

  openDrawer("Enrichment activity", el("div", { class: "muted small" }, "Loading…"));
  renderBody();
}

// Opens the company drawer when we only have an id (e.g. clicking a company
// name from the contacts table, or selecting a company in the palette
// without the row preloaded). Reuses /api/crm/companies/:id/contacts which
// now returns the full company row in `data.company`.
async function openCompanyDrawerById(companyId) {
  if (!companyId) return;
  const data = await api("crm-company-contacts", { companyId }).catch(() => ({}));
  if (data?.error || !data?.company) {
    toast(`Couldn't open company: ${data?.error || "not found"}`, "err");
    return;
  }
  showCompanyDrawer(data.company);
}

function fieldRow(label, value) {
  if (value == null || value === "") return null;
  return el("div", { class: "field-row" }, [
    el("div", { class: "field-label" }, label),
    el("div", { class: "field-value" }, typeof value === "string" ? value : value),
  ]);
}

async function showCompanyDrawer(company) {
  const body = el("div", {}, [
    // AI lead analysis at the very top — most operators want this first
    // when sizing up a company. Rendered before the structured fields so
    // cached verdicts are immediately visible. Only available when we have
    // a real DB row to update.
    company.id
      ? buildLeadAnalysisSection(
          "company",
          company.id,
          company.ai_lead_analysis_json,
          company.ai_lead_analysis_at,
        )
      : null,
    el("h4", {}, "Company"),
    fieldRow("Name", company.name),
    fieldRow("Sector", company.sector),
    fieldRow("Sub-sector", company.sub_sector),
    fieldRow("Stage", company.stage),
    fieldRow("Country", company.country),
    fieldRow("Total raised", company.total_raised ? fmtAmount(company.total_raised) : null),
    fieldRow("Token", company.token_symbol),
    // Data-confidence badge — single 0-100% score that aggregates every
    // signal (channel completeness, AI lead-analysis verdict, crypto-
    // relevance). Operator sees at a glance whether the data they're
    // about to act on is trustworthy. Hover for a per-signal breakdown.
    renderDataConfidenceBadge(company),

    company.website ? el("h4", {}, "Links") : null,
    fieldRow(
      "Website",
      company.website
        ? el(
            "a",
            { href: company.website, target: "_blank", style: "color: var(--accent);" },
            company.website.replace(/^https?:\/\//, ""),
          )
        : null,
    ),
    // Twitter \u2014 must be a clickable link. Strip leading @ defensively
    // because legacy data sometimes stored "@handle" with the symbol;
    // the link href would have been https://x.com/@handle (404).
    fieldRow(
      "Twitter",
      company.twitter_handle
        ? el(
            "a",
            {
              href: `https://x.com/${String(company.twitter_handle).replace(/^@/, "")}`,
              target: "_blank",
              style: "color: var(--accent);",
            },
            `@${String(company.twitter_handle).replace(/^@/, "")}`,
          )
        : null,
    ),
    fieldRow(
      "LinkedIn",
      company.linkedin_url
        ? el(
            "a",
            { href: company.linkedin_url, target: "_blank", style: "color: var(--accent);" },
            "Open \u2192",
          )
        : null,
    ),
    // Discord + GitHub if present \u2014 added so all the channel data stored
    // by the multi-hop website scrape is actually visible to the operator.
    fieldRow(
      "Discord",
      company.discord_url
        ? el(
            "a",
            { href: company.discord_url, target: "_blank", style: "color: var(--accent);" },
            "Open \u2192",
          )
        : null,
    ),
    fieldRow(
      "GitHub",
      company.github_url
        ? el(
            "a",
            { href: company.github_url, target: "_blank", style: "color: var(--accent);" },
            company.github_url.replace(/^https?:\/\/(www\.)?github\.com\//, ""),
          )
        : null,
    ),
    fieldRow(
      "Telegram",
      company.telegram_group_url
        ? el(
            "a",
            { href: company.telegram_group_url, target: "_blank", style: "color: var(--accent);" },
            company.telegram_group_url.replace(/^https?:\/\/t\.me\//, "t.me/"),
          )
        : null,
    ),
    company.description ? el("h4", {}, "Description") : null,
    company.description
      ? el(
          "div",
          { class: "muted small", style: "line-height: 1.6;" },
          company.description.slice(0, 500),
        )
      : null,
    company.ai_summary ? el("h4", {}, "AI Summary") : null,
    company.ai_summary
      ? el(
          "div",
          { class: "muted small", style: "line-height: 1.6;" },
          company.ai_summary.slice(0, 500),
        )
      : null,
    company.tags ? el("h4", {}, "Tags") : null,
    company.tags
      ? el(
          "div",
          { class: "row", style: "flex-wrap: wrap; gap: 4px;" },
          company.tags
            .split(",")
            .map((t) => t.trim())
            .filter(Boolean)
            .slice(0, 15)
            .map((t) => el("span", { class: "badge badge-gray" }, t)),
        )
      : null,
  ]);

  // Inline CRM notes editor \u2014 saves on blur via crm-company-update.
  // Only available when we have a company.id (drilled from a real DB row).
  if (company.id) {
    body.appendChild(el("h4", { style: "margin-top:14px;" }, "Notes"));
    const notesArea = el(
      "textarea",
      {
        class: "wizard-textarea",
        rows: "4",
        placeholder:
          "CRM notes \u2014 saved on blur. Use this to track context, deal status, anything that won't fit in the structured fields.",
        style: "width:100%;",
        onblur: async (e) => {
          const newNotes = e.target.value;
          if ((newNotes || "") === (company.crm_notes || "")) return;
          const r = await api("crm-company-update", {
            companyId: company.id,
            body: { crm_notes: newNotes },
          });
          if (r?.ok) {
            toast("\ud83d\udcdd Notes saved", "ok", 2000);
            company.crm_notes = newNotes;
          } else toast(`Save failed: ${r?.error || "unknown"}`, "err");
        },
      },
      company.crm_notes || "",
    );
    body.appendChild(notesArea);

    // \u2b50 is_target toggle
    body.appendChild(
      el("div", { style: "display:flex;align-items:center;gap:8px;margin-top:8px;" }, [
        el(
          "label",
          { class: "wizard-label", style: "flex:1;margin:0;" },
          "\u2b50 Mark as priority outreach target",
        ),
        el(
          "button",
          {
            type: "button",
            class: `btn btn-tiny ${company.is_target ? "btn-primary" : "btn-secondary"}`,
            onclick: async (e) => {
              const newVal = company.is_target ? 0 : 1;
              const r = await api("crm-company-update", {
                companyId: company.id,
                body: { is_target: newVal },
              });
              if (r?.ok) {
                company.is_target = newVal;
                e.currentTarget.className = `btn btn-tiny ${newVal ? "btn-primary" : "btn-secondary"}`;
                e.currentTarget.textContent = newVal ? "ON \u2b50" : "OFF";
                toast(newVal ? "\u2b50 Marked as target" : "Removed from targets", "ok");
              } else toast(`Failed: ${r?.error || "unknown"}`, "err");
            },
          },
          company.is_target ? "ON \u2b50" : "OFF",
        ),
      ]),
    );
  }

  // Contacts at this company (drill-down)
  const contactsSection = el("div", { id: "company-contacts-section" }, [
    el("h4", {}, "People at this company"),
    el("div", { class: "muted small" }, "Loading\u2026"),
  ]);
  body.appendChild(contactsSection);
  // Deals attached to this company
  const dealsSection = el("div", { id: "company-deals-section" }, [
    el("h4", {}, "Deals"),
    el("div", { class: "muted small" }, "Loading\u2026"),
  ]);
  body.appendChild(dealsSection);
  openDrawer(company.name || "Company", body);
  // Track in palette "Recent"
  if (company.id) {
    pushPaletteRecent({
      kind: "company",
      id: company.id,
      label: company.name || `Company #${company.id}`,
      detail:
        [company.sector, company.country, company.icp_band].filter(Boolean).join(" \u00b7 ") ||
        "\u2014",
    });
  }

  // Load contacts + deals async after drawer opens (parallel)
  if (company.id) {
    const [contactsData, dealsData] = await Promise.all([
      api("crm-company-contacts", { companyId: company.id }).catch(() => ({})),
      api("crm-deals", { queryString: `?company_id=${encodeURIComponent(company.id)}` }).catch(
        () => ({}),
      ),
    ]);

    const section = $("#company-contacts-section");
    if (section) {
      const contacts = contactsData?.contacts || [];
      section.innerHTML = "";
      section.appendChild(el("h4", {}, `People (${contacts.length})`));
      if (contacts.length === 0) {
        section.appendChild(
          el("div", { class: "muted small" }, "No contacts found at this company."),
        );
      } else {
        for (const c of contacts.slice(0, 20)) {
          section.appendChild(
            el(
              "div",
              {
                class: "field-row",
                style: "cursor: pointer;",
                onclick: () => {
                  closeDrawer();
                  setTimeout(() => showContactDrawer(c.id), 200);
                },
              },
              [
                el("div", {}, [
                  el(
                    "span",
                    { class: "primary-cell", style: "font-size: 12px;" },
                    c.display_name || "\u2014",
                  ),
                  c.role
                    ? el("span", { class: "muted small", style: "margin-left: 8px;" }, c.role)
                    : null,
                ]),
                el("div", {}, [statusDot(c.conversation_stage || "unknown")]),
              ],
            ),
          );
        }
      }
    }

    const dealsBlock = $("#company-deals-section");
    if (dealsBlock) {
      const deals = dealsData?.deals || [];
      dealsBlock.innerHTML = "";
      dealsBlock.appendChild(el("h4", {}, `Deals (${deals.length})`));
      if (deals.length === 0) {
        dealsBlock.appendChild(
          el("div", { class: "muted small" }, "No deals attached to this company."),
        );
      } else {
        for (const d of deals.slice(0, 20)) {
          dealsBlock.appendChild(
            el(
              "div",
              {
                class: "field-row",
                style: "cursor: pointer;",
                onclick: () => {
                  closeDrawer();
                  setTimeout(() => navigate("deals"), 200);
                },
                title: "Open Deals view",
              },
              [
                el("div", {}, [
                  el(
                    "span",
                    { class: "primary-cell", style: "font-size: 12px;" },
                    d.title || `Deal #${d.id}`,
                  ),
                ]),
                el("div", { class: "row", style: "gap: 8px; align-items: center;" }, [
                  d.value_usd != null
                    ? el("span", { class: "mono small" }, fmtAmount(d.value_usd))
                    : null,
                  el("span", { class: "badge " + statusClass(d.stage) }, d.stage || "\u2014"),
                ]),
              ],
            ),
          );
        }
      }
    }
  }
}
