// dashboard-platform-hub-phase-4.js — extracted verbatim from dashboard.js (pure move).

// ─── Platform Hub (Phase 4) ──────────────────────────────────────
// Unified per-platform page mirroring the Telegram /growth surface:
//   Overview  — connected accounts + health + connect prompt
//   Operations — link grid to all platform features (campaigns, broadcast, …)
//   Monitor   — today's stats + recent activity
// One function handles X / LinkedIn / Telegram / Email.

const PLATFORM_META = {
  x: {
    name: "X / Twitter",
    emoji: "🐦",
    accountKey: "twitter",
    connectHint:
      "Visit x.com in Chrome while logged in. The Nexus extension auto-syncs your session.",
  },
  linkedin: {
    name: "LinkedIn",
    emoji: "💼",
    accountKey: "linkedin",
    connectHint:
      "Visit linkedin.com while logged in. The extension picks up your session automatically.",
  },
  telegram: {
    name: "Telegram",
    emoji: "💬",
    accountKey: "telegram",
    connectHint:
      "Add a Telegram userbot via MTProto — API ID/Hash + phone + code, right in the dashboard.",
  },
  email: {
    name: "Email",
    emoji: "✉️",
    accountKey: "smtp",
    connectHint: "Run /emailsetup in the Telegram bot to add an SMTP account.",
  },
};

const PLATFORM_OPERATIONS = {
  x: [
    { icon: "📣", title: "Campaigns", desc: "Comment / like / RT campaigns", route: "campaigns" },
    {
      icon: "🐦",
      title: "Post & Engage",
      desc: "Account dashboard + routine controls",
      route: "x",
    },
  ],
  linkedin: [
    { icon: "📣", title: "Campaigns", desc: "DM and connection campaigns", route: "campaigns" },
  ],
  telegram: [
    {
      icon: "📨",
      title: "DM Campaigns",
      desc: "Targeted DMs from your accounts",
      route: "campaigns",
    },
    { icon: "📢", title: "Broadcast", desc: "Send to all groups", route: "telegram/broadcast" },
    {
      icon: "📥",
      title: "Mass Invite",
      desc: "Bulk invite users to groups",
      route: "telegram/invite",
    },
    {
      icon: "➡",
      title: "Forward Rules",
      desc: "Auto-forward by keyword",
      route: "telegram/forward",
    },
    {
      icon: "💬",
      title: "Active Member",
      desc: "AI engagement in groups",
      route: "telegram/activemember",
    },
    {
      icon: "🤖",
      title: "Auto Reply",
      desc: "AI auto-respond to DMs",
      route: "telegram/autoreply",
    },
    { icon: "👁", title: "Listener", desc: "Passive group monitoring", route: "telegram/passive" },
    {
      icon: "🧲",
      title: "Smart Scrape",
      desc: "Scrape members from groups",
      route: "telegram/scrape",
    },
    {
      icon: "📸",
      title: "Stories",
      desc: "Auto-rotate Telegram stories",
      route: "telegram/stories",
    },
  ],
  email: [
    { icon: "✉️", title: "Campaigns", desc: "Mass email outreach", route: "campaigns" },
    { icon: "🔄", title: "Sequences", desc: "Multi-step drip campaigns", route: "email/sequences" },
    { icon: "🔥", title: "Warmup", desc: "Inbox warming", route: "email/warmup" },
  ],
};

let platformHubTab = "overview";

async function renderPlatformHub(platform, params = {}) {
  const meta = PLATFORM_META[platform];
  if (!meta) {
    setContent(
      `<div class="empty-state"><div class="empty-state-icon">❓</div><div class="empty-state-title">Unknown platform: ${escapeHtml(platform)}</div></div>`,
    );
    return;
  }
  const section =
    params.section && ["overview", "operations", "monitor"].includes(params.section)
      ? params.section
      : platformHubTab;
  platformHubTab = section;

  showLoading(`Loading ${meta.name}…`);

  // Pull accounts list. accounts-all returns { twitter: [...], linkedin: [...], telegram: [...], smtp: [...] }
  const accountsData = await api("accounts-all").catch(() => ({}));
  const accounts = accountsData?.[meta.accountKey] || [];

  function tabHref(s) {
    return `${platform}/${s}`;
  }

  const header = el("div", { class: "page-header" }, [
    el("div", {}, [
      el("div", { class: "page-title" }, `${meta.emoji} ${meta.name}`),
      el(
        "div",
        { class: "page-subtitle" },
        accounts.length === 0
          ? "No accounts connected yet"
          : `${accounts.length} account${accounts.length === 1 ? "" : "s"} connected`,
      ),
    ]),
    el(
      "button",
      {
        class: "btn btn-secondary btn-tiny",
        type: "button",
        onclick: () => navigate(`accounts/${platform === "email" ? "email" : platform}`),
      },
      "+ Manage accounts",
    ),
  ]);

  const tabs = el("div", { class: "tabs" }, [
    tabBtn("overview", "Overview", () => navigate(tabHref("overview"))),
    tabBtn("operations", "Operations", () => navigate(tabHref("operations"))),
    tabBtn("monitor", "Monitor", () => navigate(tabHref("monitor"))),
  ]);

  setContentNode(el("div", {}, [header, tabs, el("div", { id: "platform-hub-body" })]));
  setTimeout(() => {
    $$(".tab").forEach((t) => t.classList.toggle("active", t.getAttribute("data-tab") === section));
  }, 0);

  const slot = $("#platform-hub-body");
  if (!slot) return;

  // Channel-readiness banner (non-blocking — features still render below).
  // Telegram has a special add-on case (needs the add-on linked + a userbot);
  // other platforms show a "no active session" notice on Operations/Monitor so
  // their action cards don't silently no-op (Overview already has an empty-state).
  try {
    const cap = await getCapabilities();
    let banner = null;
    if (platform === "telegram") banner = _tgGateBanner(cap);
    else if (section !== "overview") banner = _channelGateBanner(platform, meta, cap);
    if (banner) slot.appendChild(banner);
  } catch {
    /* non-fatal */
  }

  if (section === "overview") {
    slot.appendChild(renderPlatformOverview(platform, meta, accounts));
  } else if (section === "operations") {
    slot.appendChild(renderPlatformOperations(platform, meta));
  } else {
    slot.appendChild(await renderPlatformMonitor(platform, meta, accounts));
  }
}

// Cached capabilities fetch (30s) — used to gate Telegram-only features.
let _capCache = null,
  _capCacheTs = 0;
async function getCapabilities(force = false) {
  if (!force && _capCache && Date.now() - _capCacheTs < 30000) return _capCache;
  try {
    const c = await api("capabilities");
    if (c && !c.error) {
      _capCache = c;
      _capCacheTs = Date.now();
    }
    return c;
  } catch {
    return null;
  }
}

// Returns a "Requires the Telegram add-on" banner element, or null when Telegram
// is fully available (linked + a userbot connected).
function _tgGateBanner(cap) {
  if (!cap || cap.error) return null;
  if (cap.telegramLinked && cap.hasPremiumAccount) return null; // fully available

  let title, body;
  if (!cap.telegramEnabled) {
    title = "Telegram add-on unavailable";
    body =
      "No Telegram bot is configured on the server. Telegram-channel automations (broadcast, mass-invite, scrape, group activation) need it — everything else works without it.";
  } else if (!cap.telegramLinked) {
    title = "Requires the Telegram add-on";
    body =
      "These features run through Telegram. Connect the add-on to use them: send /pair to your Nexus bot, then enter the code in the extension popup (or on the Connections page).";
  } else {
    title = "Add a Telegram userbot";
    body =
      "Telegram is connected for alerts, but group automations (broadcast, mass-invite, scrape, group activation) need a Telegram userbot account. Add one to unlock them.";
  }

  const card = el(
    "div",
    { class: "card", style: "margin-bottom:14px;border:1px solid #d29922;background:#1c170a;" },
    [
      el("div", { style: "display:flex;align-items:center;gap:8px;margin-bottom:4px;" }, [
        el("span", { style: "font-size:15px;" }, "✈️"),
        el("div", { style: "font-size:14px;font-weight:600;color:#d29922;flex:1;" }, title),
      ]),
      el("div", { class: "muted", style: "font-size:12px;line-height:1.5;" }, body),
      cap.telegramEnabled && !cap.telegramLinked
        ? el(
            "button",
            {
              class: "btn btn-secondary",
              type: "button",
              style: "margin-top:10px;",
              onclick: () => navigate("connections"),
            },
            "Connect Telegram →",
          )
        : null,
    ].filter(Boolean),
  );
  return card;
}

// Generic "no active session" banner for X / LinkedIn / Email on the
// Operations/Monitor tabs — so their action cards don't silently no-op when
// there's no live session. Returns null when the channel is ready.
function _channelGateBanner(platform, meta, cap) {
  if (!cap || cap.error || !cap.channels) return null;
  if (cap.channels[platform]) return null; // ready — active session exists
  const card = el(
    "div",
    { class: "card", style: "margin-bottom:14px;border:1px solid #d29922;background:#1c170a;" },
    [
      el("div", { style: "display:flex;align-items:center;gap:8px;margin-bottom:4px;" }, [
        el("span", { style: "font-size:15px;" }, meta.emoji),
        el(
          "div",
          { style: "font-size:14px;font-weight:600;color:#d29922;flex:1;" },
          `No active ${meta.name} session`,
        ),
      ]),
      el(
        "div",
        { class: "muted", style: "font-size:12px;line-height:1.5;" },
        `Connect (or re-sync) a ${meta.name} account to run these — ${meta.connectHint}`,
      ),
      el(
        "button",
        {
          class: "btn btn-secondary",
          type: "button",
          style: "margin-top:10px;",
          onclick: () => navigate(`accounts/${platform}`),
        },
        "+ Manage accounts",
      ),
    ],
  );
  return card;
}

function renderPlatformOverview(platform, meta, accounts) {
  if (accounts.length === 0) {
    return el("div", { class: "empty-state", style: "padding: 32px;" }, [
      el("div", { class: "empty-state-icon" }, meta.emoji),
      el("div", { class: "empty-state-title" }, `Connect a ${meta.name} account`),
      el("div", { class: "empty-state-hint" }, meta.connectHint),
      el("div", { style: "display: flex; gap: 8px; justify-content: center; margin-top: 16px;" }, [
        el(
          "button",
          {
            class: "btn btn-primary",
            type: "button",
            onclick: () => navigate(`accounts/${platform}`),
          },
          "+ Connect account",
        ),
      ]),
    ]);
  }

  function dotColor(status) {
    if (status === "active") return "green";
    if (status === "rate_limited") return "yellow";
    if (status === "logged_out" || status === "expired") return "gray";
    return "red";
  }

  return el("div", {}, [
    // Account cards
    el("div", { class: "card" }, [
      el("div", { class: "card-title" }, "Connected accounts"),
      ...accounts.map((a) => {
        const label = a.account_identifier
          ? `@${a.account_identifier}`
          : a.label || a.identifier || a.email || a.phone || "Account";
        const health = a.health_score != null ? `${a.health_score}%` : a.status || "—";
        return el(
          "div",
          {
            class: "channel-row",
            style:
              "padding: 10px 12px; border-bottom: 1px solid var(--border); cursor: pointer; display: flex; align-items: center; gap: 12px;",
            onclick: () => navigate(`${platform}/${a.id}`),
          },
          [
            el("span", { class: `account-dot ${dotColor(a.status)}` }),
            el("div", { style: "flex: 1; min-width: 0;" }, [
              el("div", { class: "primary-cell truncate" }, label),
              el(
                "div",
                { class: "muted small" },
                [
                  a.status || "unknown",
                  a.warmup_day != null ? ` · warmup d${a.warmup_day}` : null,
                  a.daily_actions != null ? ` · ${a.daily_actions} actions today` : null,
                ]
                  .filter(Boolean)
                  .join(""),
              ),
            ]),
            el("div", { class: "muted mono small" }, health),
          ],
        );
      }),
    ]),

    // Quick capacity card — total accounts vs cap
    el("div", { class: "card" }, [
      el("div", { class: "card-title" }, "Capacity"),
      el("div", { class: "stats-grid" }, [
        statCard(
          "Active",
          accounts.filter((a) => a.status === "active").length,
          "of " + accounts.length + " total",
        ),
        statCard("Rate-limited", accounts.filter((a) => a.status === "rate_limited").length, ""),
        statCard("Slots used", `${accounts.length} / 5`, "5 slots per platform"),
      ]),
    ]),

    // Connect prompt for additional accounts
    accounts.length < 5
      ? el("div", { class: "card" }, [
          el("div", { class: "card-title" }, "Add another account"),
          el(
            "div",
            { class: "muted", style: "font-size: 13px; margin-bottom: 12px;" },
            meta.connectHint,
          ),
          el(
            "button",
            {
              class: "btn btn-primary",
              type: "button",
              onclick: () => navigate(`accounts/${platform}`),
            },
            "+ Connect another account",
          ),
        ])
      : null,
  ]);
}

function renderPlatformOperations(platform, meta) {
  const ops = PLATFORM_OPERATIONS[platform] || [];
  if (ops.length === 0) {
    return el("div", { class: "empty-state", style: "padding: 32px;" }, [
      el("div", { class: "empty-state-icon" }, "🚧"),
      el("div", { class: "empty-state-title" }, "Operations coming soon"),
      el(
        "div",
        { class: "empty-state-hint" },
        "More tools land for this platform in upcoming phases.",
      ),
    ]);
  }

  return el("div", {}, [
    el(
      "div",
      { class: "muted", style: "font-size: 12px; margin-bottom: 12px;" },
      `Tools and verbs for ${meta.name}. Each card opens its dedicated page.`,
    ),
    el(
      "div",
      { class: "action-card-grid" },
      ops.map((op) =>
        el(
          "button",
          {
            class: "action-card",
            type: "button",
            onclick: () => navigate(op.route),
          },
          [
            el("div", { class: "action-card-icon" }, op.icon),
            el("div", { class: "action-card-body" }, [
              el("div", { class: "action-card-title" }, op.title),
              el("div", { class: "action-card-desc" }, op.desc),
            ]),
            el("div", { class: "action-card-cta" }, "→"),
          ],
        ),
      ),
    ),
  ]);
}

async function renderPlatformMonitor(platform, meta, accounts) {
  if (accounts.length === 0) {
    return el("div", { class: "empty-state", style: "padding: 32px;" }, [
      el("div", { class: "empty-state-icon" }, "📊"),
      el("div", { class: "empty-state-title" }, "Nothing to monitor yet"),
      el("div", { class: "empty-state-hint" }, "Connect an account in Overview to see stats here."),
    ]);
  }

  const wrap = el("div", {});

  // Aggregate health
  const active = accounts.filter((a) => a.status === "active").length;
  const limited = accounts.filter((a) => a.status === "rate_limited").length;
  const dead = accounts.filter((a) =>
    ["logged_out", "expired", "banned"].includes(a.status),
  ).length;
  const avgHealth = accounts.length
    ? Math.round(accounts.reduce((sum, a) => sum + (a.health_score || 0), 0) / accounts.length)
    : 0;
  const totalActions = accounts.reduce((sum, a) => sum + (a.daily_actions || 0), 0);

  wrap.appendChild(
    el("div", { class: "card" }, [
      el("div", { class: "card-title" }, "Today at a glance"),
      el("div", { class: "stats-grid" }, [
        statCard("Active", active, `of ${accounts.length} accounts`),
        statCard("Rate-limited", limited, "", limited > 0 ? "warning" : null),
        statCard("Offline", dead, "", dead > 0 ? "warning" : null),
        statCard("Avg health", `${avgHealth}%`, ""),
        statCard("Actions today", totalActions, "across all accounts"),
      ]),
    ]),
  );

  // ── Channel campaigns (filtered + lazy-loaded) ──
  // Fetch async so the rest of the page renders immediately. Slot is mounted
  // first; the request fills it in when it lands.
  const campaignsSlot = el("div", { class: "card" }, [
    el("div", { class: "card-title" }, "Active campaigns on this channel"),
    el("div", { class: "muted small" }, "Loading…"),
  ]);
  wrap.appendChild(campaignsSlot);

  // Map platform → campaign-API channel name. Campaigns API uses different
  // labels: dm = telegram DM, email = email, outreach = multi-channel.
  const campaignChannel = { telegram: "dm", email: "email", x: "outreach", linkedin: "outreach" }[
    platform
  ];
  if (campaignChannel) {
    api(`campaigns-${campaignChannel}`, { queryString: "?status=running&limit=5" })
      .catch(() => ({}))
      .then((data) => {
        const camps = data?.campaigns || [];
        campaignsSlot.replaceChildren(
          el("div", { class: "card-title" }, [
            "Active campaigns on this channel",
            el(
              "span",
              { class: "muted small", style: "margin-left: 8px;" },
              `(${camps.length} running)`,
            ),
          ]),
          camps.length === 0
            ? el("div", { class: "muted small", style: "padding: 8px 0;" }, [
                "No running campaigns. ",
                el(
                  "a",
                  {
                    href: "#campaigns",
                    style: "color: var(--accent);",
                    onclick: (e) => {
                      e.preventDefault();
                      navigate("campaigns");
                    },
                  },
                  "Create one →",
                ),
              ])
            : el(
                "div",
                {},
                camps.slice(0, 5).map((c) =>
                  el(
                    "div",
                    {
                      class: "channel-row",
                      style:
                        "padding: 8px 10px; border-bottom: 1px solid var(--border); cursor: pointer;",
                      onclick: () => navigate(`campaigns/${campaignChannel}/${c.id}`),
                    },
                    [
                      el("div", { style: "flex: 1; min-width: 0;" }, [
                        el(
                          "div",
                          { class: "primary-cell", style: "font-size: 12px;" },
                          c.name || `Campaign #${c.id}`,
                        ),
                        el(
                          "div",
                          { class: "muted small" },
                          `${c.total_sent || 0}/${c.daily_limit || c.target_count || "?"} sent · ${c.reply_count || 0} replies`,
                        ),
                      ]),
                      el(
                        "span",
                        {
                          class: "badge badge-green",
                          style: "font-size: 9px;",
                        },
                        c.status,
                      ),
                    ],
                  ),
                ),
              ),
        );
      });
  } else {
    campaignsSlot.replaceChildren(
      el("div", { class: "card-title" }, "Active campaigns on this channel"),
      el("div", { class: "muted small" }, "Channel doesn't have a campaigns surface yet."),
    );
  }

  // ── Buying signals on this platform ──
  // /api/signals returns recent matches; we filter client-side for the
  // platform we care about. Cap to last 7 days mentally — server may
  // return older but we just count what came back.
  if (platform === "x" || platform === "linkedin" || platform === "telegram") {
    const signalsSlot = el("div", { class: "card" }, [
      el("div", { class: "card-title" }, "Buying signals (recent)"),
      el("div", { class: "muted small" }, "Loading…"),
    ]);
    wrap.appendChild(signalsSlot);
    const sigPlatform = platform === "x" ? "twitter" : platform;
    api("signals-list", { queryString: `?platform=${sigPlatform}&limit=5` })
      .catch(() => ({}))
      .then((data) => {
        const sigs = data?.signals || [];
        signalsSlot.replaceChildren(
          el("div", { class: "card-title" }, [
            "Buying signals on this platform",
            el(
              "span",
              { class: "muted small", style: "margin-left: 8px;" },
              `(${sigs.length} recent)`,
            ),
          ]),
          sigs.length === 0
            ? el("div", { class: "muted small", style: "padding: 8px 0;" }, [
                "No matches in the recent window. ",
                el(
                  "a",
                  {
                    href: "#signals",
                    style: "color: var(--accent);",
                    onclick: (e) => {
                      e.preventDefault();
                      navigate("signals");
                    },
                  },
                  "Manage keywords →",
                ),
              ])
            : el(
                "div",
                {},
                sigs.slice(0, 5).map((s) =>
                  el(
                    "div",
                    {
                      class: "channel-row",
                      style:
                        "padding: 8px 10px; border-bottom: 1px solid var(--border); cursor: pointer;",
                      onclick: () => navigate(`signals/pursue/${s.id}`),
                    },
                    [
                      el("div", { style: "flex: 1; min-width: 0;" }, [
                        el(
                          "div",
                          { class: "primary-cell", style: "font-size: 12px;" },
                          `@${s.source_handle || "?"} mentioned "${s.matched_keyword}"`,
                        ),
                        el("div", { class: "muted small" }, fmtDate(s.detected_at)),
                      ]),
                      el(
                        "span",
                        {
                          class: `badge ${s.status === "engaged" ? "badge-green" : s.status === "dismissed" ? "badge-gray" : "badge-yellow"}`,
                          style: "font-size: 9px;",
                        },
                        s.status || "pending",
                      ),
                    ],
                  ),
                ),
              ),
        );
      });
  }

  // ── Per-account status ──
  wrap.appendChild(
    el("div", { class: "card" }, [
      el("div", { class: "card-title" }, "Per-account status"),
      ...accounts.map((a) => {
        const label = a.account_identifier
          ? `@${a.account_identifier}`
          : a.label || a.identifier || a.email || a.phone || "Account";
        const healthScore = a.health_score || 0;
        const health = healthScore >= 70 ? "healthy" : healthScore >= 40 ? "degraded" : "low";
        return el(
          "div",
          {
            class: "channel-row",
            style: "padding: 10px 12px; border-bottom: 1px solid var(--border); cursor: pointer;",
            onclick: () => navigate(`${platform}/${a.id}`),
          },
          [
            el("div", { class: "channel-name truncate", style: "flex: 1;" }, label),
            el("div", { class: "channel-bar", style: "width: 120px; margin: 0 12px;" }, [
              el("div", {
                class: `channel-bar-fill ${health}`,
                style: `width: ${healthScore}%`,
              }),
            ]),
            el(
              "div",
              { class: "muted mono small", style: "min-width: 60px; text-align: right;" },
              `${healthScore}%`,
            ),
            el(
              "div",
              { class: "muted small", style: "min-width: 80px; text-align: right;" },
              a.daily_actions != null ? `${a.daily_actions} actions` : "—",
            ),
          ],
        );
      }),
    ]),
  );

  // ── Drill-down quick links ──
  wrap.appendChild(
    el("div", { class: "card" }, [
      el("div", { class: "card-title" }, "Drill down"),
      el("div", { class: "row", style: "gap: 8px; flex-wrap: wrap;" }, [
        el(
          "button",
          {
            class: "btn btn-secondary btn-tiny",
            type: "button",
            onclick: () => navigate("health"),
          },
          "🛡 Health & Safety",
        ),
        el(
          "button",
          {
            class: "btn btn-secondary btn-tiny",
            type: "button",
            onclick: () => navigate("outreach-queue"),
          },
          "📤 Outreach Queue",
        ),
        el(
          "button",
          { class: "btn btn-secondary btn-tiny", type: "button", onclick: () => navigate("home") },
          "📈 Live dashboard",
        ),
        el(
          "button",
          {
            class: "btn btn-secondary btn-tiny",
            type: "button",
            onclick: () => navigate("report"),
          },
          "📊 Weekly report",
        ),
        el(
          "button",
          { class: "btn btn-secondary btn-tiny", type: "button", onclick: () => navigate("inbox") },
          "📬 Inbox",
        ),
        platform === "x"
          ? el(
              "button",
              { class: "btn btn-secondary btn-tiny", type: "button", onclick: () => navigate("x") },
              "🐦 X dashboard",
            )
          : null,
      ]),
    ]),
  );

  return wrap;
}
