// dashboard-shared-saved-config-section-he.js — extracted verbatim from dashboard.js (pure move).

// ── Shared saved-config section helper ──────────────────────────────
// Used by the Gmail and Telegram tabs to render each surface (Sequence,
// Broadcast, Forward rule, etc.) as: section heading + saved configs
// list inline + "+ New" CTA. Replaces the Phase A cards-as-links
// pattern so the user sees what they've saved without click-throughs.
//
// `items` = array of saved configs (any shape).
// `renderRow(item)` returns a DOM node for one saved config (the row).
// `onNew()` is fired when the user clicks the "+ New" header button.
// Optional `onOpen(item)` fires when a row is clicked. If absent the
// rows aren't clickable (read-only listing).
function _renderConfigSection({
  title,
  icon,
  hint,
  items,
  newLabel,
  onNew,
  onOpen,
  renderRow,
  emptyHint,
  error,
  onRetry,
}) {
  const section = el("div", { style: "margin-bottom:22px;" });
  const list = Array.isArray(items) ? items : [];

  // Header row: icon + title + count badge + "+ New" button
  section.appendChild(
    el("div", { style: "display:flex;align-items:baseline;gap:10px;margin-bottom:4px;" }, [
      el("h3", { style: "margin:0;font-size:14px;color:var(--text-1);" }, `${icon} ${title}`),
      el(
        "span",
        {
          style:
            "font-size:10px;background:var(--border-soft);color:var(--text-2);padding:2px 7px;border-radius:6px;font-family:monospace;",
        },
        error ? "—" : String(list.length),
      ),
      onNew
        ? el(
            "button",
            {
              class: "btn btn-tiny btn-secondary",
              style: "margin-left:auto;",
              onclick: onNew,
            },
            newLabel || "+ New",
          )
        : null,
    ]),
  );
  if (hint)
    section.appendChild(
      el("p", { class: "muted", style: "margin:0 0 10px;font-size:11px;" }, hint),
    );

  // Body: error state takes precedence over empty/rows so a failed fetch reads
  // as "couldn't load — retry", never as "nothing configured" (silent failure).
  if (error) {
    section.appendChild(
      el(
        "div",
        {
          style:
            "padding:14px;background:#1f1414;border:1px solid #5a2a2a;border-radius:8px;display:flex;align-items:center;gap:10px;font-size:12px;color:var(--red);",
        },
        [
          el(
            "span",
            { style: "flex:1;" },
            `Couldn't load ${String(title).toLowerCase()}: ${typeof error === "string" ? error : error?.message || "load failed"}`,
          ),
          onRetry
            ? el("button", { class: "btn btn-tiny btn-secondary", onclick: onRetry }, "↻ Retry")
            : null,
        ],
      ),
    );
  } else if (list.length === 0) {
    section.appendChild(
      el(
        "div",
        {
          style:
            "padding:14px;background:var(--bg-card);border:1px dashed var(--border-soft);border-radius:8px;text-align:center;font-size:12px;color:var(--text-4);",
        },
        emptyHint || "Nothing saved yet.",
      ),
    );
  } else {
    const rows = el("div", { style: "display:flex;flex-direction:column;gap:6px;" });
    for (const item of list) {
      const row = renderRow(item);
      if (row && onOpen) {
        row.style.cursor = "pointer";
        const orig = row.onclick;
        row.onclick = (ev) => {
          if (orig) orig(ev);
          onOpen(item);
        };
      }
      if (row) rows.appendChild(row);
    }
    section.appendChild(rows);
  }

  return section;
}

// Universal status pill used by saved-config rows across both tabs.
// Maps common status strings to consistent color treatments.
function _renderConfigStatusPill(status) {
  const styles = {
    active: { bg: "#1a3a1a", color: "#4ade80", label: "running" },
    running: { bg: "#1a3a1a", color: "#4ade80", label: "running" },
    sending: { bg: "#1a3a1a", color: "#4ade80", label: "sending" },
    paused: { bg: "#3a2a1a", color: "#fbbf24", label: "paused" },
    scheduled: { bg: "#1a2a3a", color: "#93c5fd", label: "scheduled" },
    completed: { bg: "#222", color: "#888", label: "done" },
    draft: { bg: "#222", color: "#999", label: "draft" },
    failed: { bg: "#3a1a1a", color: "#f87171", label: "failed" },
    inactive: { bg: "#222", color: "#999", label: "inactive" },
  };
  const s = styles[status] || { bg: "#222", color: "#999", label: status || "—" };
  return el(
    "span",
    {
      style: `background:${s.bg};color:${s.color};font-size:10px;padding:3px 8px;border-radius:6px;text-transform:uppercase;letter-spacing:0.4px;flex-shrink:0;`,
    },
    s.label,
  );
}

// Compact row used by every saved-config list. `title` is bolded,
// `subline` is muted secondary text, `statusPill` floats right.
function _renderConfigRow({ title, subline, status }) {
  return el(
    "div",
    {
      style:
        "background:var(--bg-card);border:1px solid var(--border-soft);border-radius:8px;padding:10px 12px;display:flex;align-items:center;gap:10px;transition:border-color 120ms,background 120ms;",
      onmouseenter: (e) => {
        e.currentTarget.style.borderColor = "var(--border-hover)";
        e.currentTarget.style.background = "#1f1f28";
      },
      onmouseleave: (e) => {
        e.currentTarget.style.borderColor = "var(--border-soft)";
        e.currentTarget.style.background = "var(--bg-card)";
      },
    },
    [
      el("div", { style: "flex:1;min-width:0;" }, [
        el(
          "div",
          {
            style:
              "font-size:13px;color:var(--text-1);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;",
          },
          title,
        ),
        subline
          ? el("div", { class: "muted", style: "font-size:11px;margin-top:2px;" }, subline)
          : null,
      ]),
      status ? _renderConfigStatusPill(status) : null,
    ],
  );
}

// Gmail tab — surfaces email Campaigns / Sequences / Warmup as inline
// saved-config sections. Sequences + Warmup have list endpoints so
// their saved configs render directly; Campaigns is CTA-only because
// the campaigns table is platform-mixed and lives behind #campaigns.
async function _renderAutomationsGmailTab() {
  // Parallel fetch — defensive: if an endpoint errors, the section
  // shows its empty state and "+ New" CTA so the user can still create.
  // Error sentinel (not null) so a failed section renders "couldn't load — retry"
  // instead of an empty list that reads as "nothing configured".
  const [seqR, wuR] = await Promise.all([
    api("email-sequences-list").catch((e) => ({ __error: e?.message || "load failed" })),
    api("email-warmup-list").catch((e) => ({ __error: e?.message || "load failed" })),
  ]);

  const wrap = el("div", {});
  // Run-model explainer is in the shared hub capability banner.

  // ── Email Campaigns (CTA-only, no list endpoint here) ───────────
  wrap.appendChild(
    el("div", { style: "margin-bottom:22px;" }, [
      el("div", { style: "display:flex;align-items:baseline;gap:10px;margin-bottom:6px;" }, [
        el("h3", { style: "margin:0;font-size:14px;color:var(--text-1);" }, "Email Campaigns"),
        el(
          "button",
          {
            class: "btn btn-tiny btn-secondary",
            style: "margin-left:auto;",
            onclick: () => navigate("new-email-campaign"),
          },
          "+ New campaign",
        ),
      ]),
      el(
        "p",
        { class: "muted", style: "margin:0 0 10px;font-size:11px;" },
        "One-shot bulk sends with template variables and unsubscribe handling. Full list lives in Campaigns.",
      ),
      el(
        "div",
        {
          style:
            "padding:14px;background:var(--bg-card);border:1px dashed var(--border-soft);border-radius:8px;display:flex;align-items:center;gap:10px;font-size:12px;",
        },
        [
          el(
            "span",
            { class: "muted", style: "flex:1;" },
            "Manage all campaigns (DM + Email + Outreach) in one place →",
          ),
          el(
            "button",
            { class: "btn btn-tiny btn-secondary", onclick: () => navigate("campaigns") },
            "Open Campaigns",
          ),
        ],
      ),
    ]),
  );

  // ── Email Sequences ─────────────────────────────────────────────
  wrap.appendChild(
    _renderConfigSection({
      title: "Email Sequences",
      icon: "🔁",
      hint: "Multi-step drip with conditional branches (if replied / if opened / if not replied).",
      items: seqR?.sequences || [],
      error: seqR?.__error,
      onRetry: () => navigate("automations/gmail"),
      newLabel: "+ New sequence",
      onNew: () => navigate("email/sequences"),
      onOpen: () => navigate("email/sequences"),
      emptyHint: "No sequences yet — click + New to build a multi-step drip.",
      renderRow: (s) =>
        _renderConfigRow({
          title: s.name || `Sequence #${s.id}`,
          subline: `${s.step_count || s.steps?.length || 0} steps${s.enrolled_count != null ? ` · ${s.enrolled_count} enrolled` : ""}${s.completed_count != null ? ` · ${s.completed_count} completed` : ""}`,
          status: s.status,
        }),
    }),
  );

  // ── Email Warmup ────────────────────────────────────────────────
  wrap.appendChild(
    _renderConfigSection({
      title: "Email Warmup",
      icon: "🔥",
      hint: "Gradual ramp on new sender domains. Small daily volume increasing toward your inbox's reputation.",
      items: wuR?.configs || wuR?.warmups || [],
      error: wuR?.__error,
      onRetry: () => navigate("automations/gmail"),
      newLabel: "+ Start warmup",
      onNew: () => navigate("email/warmup"),
      onOpen: () => navigate("email/warmup"),
      emptyHint: "No warmup configs yet — start one to ramp a new sender.",
      renderRow: (w) =>
        _renderConfigRow({
          title: w.smtp_identity || w.email || `Warmup #${w.id}`,
          subline: `Day ${w.day_number || w.current_day || 0}${w.daily_volume != null ? ` · ${w.daily_volume}/day` : ""}${w.target_volume != null ? ` → ${w.target_volume} target` : ""}`,
          status: w.status || (w.enabled || w.is_active ? "active" : "paused"),
        }),
    }),
  );

  return wrap;
}

// Telegram tab — 8 surfaces, 6 with inline saved-config lists, 2
// (Stories single-config, Smart Scrape one-off) as compact CTA cards
// because they don't fit the "multiple saved configs" shape.
async function _renderAutomationsTelegramTab() {
  // Parallel fetch — defensive: each endpoint can fail independently
  // without taking down the whole tab.
  // Error sentinel (not null) so a failed section renders "couldn't load — retry"
  // instead of an empty list that falsely reads as "nothing configured".
  const _err = (e) => ({ __error: e?.message || "load failed" });
  const [autoR, brR, invR, fwdR, amR, psR, storyR] = await Promise.all([
    api("tg-autoreply-list").catch(_err),
    api("tg-broadcast-history").catch(_err),
    api("tg-invite-list").catch(_err),
    api("tg-forward-list").catch(_err),
    api("tg-activemember-list").catch(_err),
    api("tg-passive-groups").catch(_err),
    api("tg-stories-get").catch(_err),
  ]);
  const _tgRetry = () => navigate("automations/telegram");

  const wrap = el("div", {});
  // Run-model explainer is in the shared hub capability banner. Note: Stories +
  // Smart Scrape are one-off surfaces (no saved-config list).

  // ── Broadcast (history, not "saved" — newest first) ─────────────
  wrap.appendChild(
    _renderConfigSection({
      title: "Broadcasts",
      icon: "📢",
      hint: "Send one message to many Telegram groups. Recent sends are shown.",
      items: (brR?.broadcasts || []).slice(0, 6),
      error: brR?.__error,
      onRetry: _tgRetry,
      newLabel: "+ New broadcast",
      onNew: () => navigate("telegram/broadcast"),
      onOpen: () => navigate("telegram/broadcast"),
      emptyHint: "No broadcasts sent yet.",
      renderRow: (b) =>
        _renderConfigRow({
          title:
            (b.message_text || "(empty message)").slice(0, 60) +
            ((b.message_text || "").length > 60 ? "…" : ""),
          subline: `${b.sent_count || 0} sent${b.failed_count ? ` · ${b.failed_count} failed` : ""}${b.created_at ? ` · ${fmtDate(b.created_at)}` : ""}`,
          status: b.status,
        }),
    }),
  );

  // ── Invite jobs ─────────────────────────────────────────────────
  wrap.appendChild(
    _renderConfigSection({
      title: "Invite jobs",
      icon: "👥",
      hint: "Auto-copy members from one group to another within daily limits.",
      items: invR?.jobs || [],
      error: invR?.__error,
      onRetry: _tgRetry,
      newLabel: "+ New job",
      onNew: () => navigate("telegram/invite"),
      onOpen: () => navigate("telegram/invite"),
      emptyHint: "No invite jobs yet.",
      renderRow: (j) =>
        _renderConfigRow({
          title: `${j.source_group_name || j.source_chat_id || "?"} → ${j.target_group_name || j.target_chat_id || "?"}`,
          subline: `${j.invited_count || 0} invited / ${j.daily_limit || "?"} daily cap${j.last_run_at ? ` · last: ${fmtDate(j.last_run_at)}` : ""}`,
          status: j.status,
        }),
    }),
  );

  // ── Forward rules ───────────────────────────────────────────────
  wrap.appendChild(
    _renderConfigSection({
      title: "Forward rules",
      icon: "↪",
      hint: "Auto-forward messages from one chat to another with optional filter conditions.",
      items: fwdR?.rules || [],
      error: fwdR?.__error,
      onRetry: _tgRetry,
      newLabel: "+ New rule",
      onNew: () => navigate("telegram/forward"),
      onOpen: () => navigate("telegram/forward"),
      emptyHint: "No forward rules yet.",
      renderRow: (r) =>
        _renderConfigRow({
          title: `${r.source_chat_name || r.source_chat_id || "?"} → ${r.target_chat_name || r.target_chat_id || "?"}`,
          subline: r.filter_type
            ? `filter: ${r.filter_type}${r.filter_value ? ` "${r.filter_value}"` : ""}`
            : "no filter",
          status: r.is_active ? "active" : "paused",
        }),
    }),
  );

  // ── Active member ───────────────────────────────────────────────
  wrap.appendChild(
    _renderConfigSection({
      title: "Active member",
      icon: "🤖",
      hint: "AI persona replies in groups using configurable behavior toggles (humor, technical, etc.).",
      items: amR?.configs || [],
      error: amR?.__error,
      onRetry: _tgRetry,
      newLabel: "+ New persona",
      onNew: () => navigate("telegram/activemember"),
      onOpen: () => navigate("telegram/activemember"),
      emptyHint: "No active-member configs yet.",
      renderRow: (c) =>
        _renderConfigRow({
          title: c.persona_name || c.group_name || `Config #${c.id}`,
          subline: `${c.message_count || 0} messages sent${c.last_active_at ? ` · last: ${fmtDate(c.last_active_at)}` : ""}`,
          status: c.is_active ? "active" : "paused",
        }),
    }),
  );

  // ── Auto-reply ──────────────────────────────────────────────────
  wrap.appendChild(
    _renderConfigSection({
      title: "Auto-reply rules",
      icon: "💬",
      hint: "AI-reply to Telegram DMs based on sender / keywords / context.",
      items: autoR?.configs || autoR?.rules || [],
      error: autoR?.__error,
      onRetry: _tgRetry,
      newLabel: "+ New rule",
      onNew: () => navigate("telegram/autoreply"),
      onOpen: () => navigate("telegram/autoreply"),
      emptyHint: "No auto-reply rules yet.",
      renderRow: (c) =>
        _renderConfigRow({
          title: c.account_name || c.account_id || `Account #${c.id}`,
          subline: (c.prompt || "").slice(0, 80) || "no prompt",
          status: c.is_active ? "active" : "paused",
        }),
    }),
  );

  // ── Passive listener ────────────────────────────────────────────
  wrap.appendChild(
    _renderConfigSection({
      title: "Passive listeners",
      icon: "👂",
      hint: "Silently scrape contacts + messages from groups you're a member of into shared_contacts.",
      items: psR?.groups || [],
      error: psR?.__error,
      onRetry: _tgRetry,
      newLabel: "+ Watch a group",
      onNew: () => navigate("telegram/passive"),
      onOpen: () => navigate("telegram/passive"),
      emptyHint: "No groups being watched yet.",
      renderRow: (g) =>
        _renderConfigRow({
          title: g.group_name || g.chat_id || "?",
          subline: `${g.contact_count || g.member_count || 0} contacts scraped${g.last_seen_at ? ` · last: ${fmtDate(g.last_seen_at)}` : ""}`,
          status: "active",
        }),
    }),
  );

  // ── Stories (single config — not a list, special-cased) ────────
  // Guard the error sentinel: a failed fetch ({__error}) must read as
  // "couldn't load — retry", not as "no schedule yet" (silent failure).
  const storyErr = storyR?.__error;
  const storyConfig = storyErr ? null : storyR?.config || storyR || null;
  const hasStory = storyConfig && (storyConfig.is_active != null || storyConfig.account_id != null);
  wrap.appendChild(
    el("div", { style: "margin-bottom:22px;" }, [
      el("div", { style: "display:flex;align-items:baseline;gap:10px;margin-bottom:6px;" }, [
        el("h3", { style: "margin:0;font-size:14px;color:var(--text-1);" }, "Stories"),
        hasStory ? _renderConfigStatusPill(storyConfig.is_active ? "active" : "paused") : null,
        el(
          "button",
          {
            class: "btn btn-tiny btn-secondary",
            style: "margin-left:auto;",
            onclick: () => (storyErr ? _tgRetry() : navigate("telegram/stories")),
          },
          storyErr ? "↻ Retry" : hasStory ? "Edit" : "+ Schedule",
        ),
      ]),
      el(
        "p",
        { class: "muted", style: "margin:0 0 10px;font-size:11px;" },
        "Auto-post photo / video stories to your Telegram channel on a daily schedule. One configuration per account.",
      ),
      storyErr
        ? el(
            "div",
            {
              style:
                "padding:14px;background:#1f1414;border:1px solid #5a2a2a;border-radius:8px;font-size:12px;color:var(--red);",
            },
            `Couldn't load stories: ${storyErr}`,
          )
        : null,
      !hasStory && !storyErr
        ? el(
            "div",
            {
              style:
                "padding:14px;background:var(--bg-card);border:1px dashed var(--border-soft);border-radius:8px;text-align:center;font-size:12px;color:var(--text-4);",
            },
            "No stories schedule yet — click + Schedule to set one up.",
          )
        : null,
    ]),
  );

  // ── Smart Scrape (one-off command, no saved configs) ────────────
  wrap.appendChild(
    el("div", { style: "margin-bottom:22px;" }, [
      el("div", { style: "display:flex;align-items:baseline;gap:10px;margin-bottom:6px;" }, [
        el("h3", { style: "margin:0;font-size:14px;color:var(--text-1);" }, "Smart Scrape"),
        el(
          "button",
          {
            class: "btn btn-tiny btn-secondary",
            style: "margin-left:auto;",
            onclick: () => navigate("telegram/scrape"),
          },
          "Open scrape",
        ),
      ]),
      el(
        "p",
        { class: "muted", style: "margin:0;font-size:11px;" },
        "One-off targeted scrape of a group's members + AI enrichment → CRM with ICP score. Use Passive Listener for continuous monitoring instead.",
      ),
    ]),
  );

  return wrap;
}
