// dashboard-the-one-shared-detail-view.js — extracted verbatim from dashboard.js (pure move).

// ── The one shared detail view ─────────────────────────────────────
// Every automation card across every tab opens THIS. `item` is one of:
//   { type:"li_action", action }   (window.LI_ACTION_REGISTRY entry)
//   { type:"x_action",  action }   (window.PLATFORM_ACTIONS entry)
//   { type:"preset",    wf }       (automations-list workflow, kind!=custom)
//   { type:"custom",    wf }       (automations-list workflow, kind==custom)
// Layout is identical for all four: header (icon · title · type badge ·
// status) → description → "How it runs" → a consistent action bar.
function openAutomationDetail(item) {
  // Uses the shared openModal (focus-trap + Esc + focus-restore + aria). We
  // build the body + actions, then hand them off; `close` is resolved from the
  // openModal return via a holder so the action handlers can call it.
  const modal = el("div", {});
  const _h = {};
  const close = () => {
    if (_h.close) _h.close();
  };

  // Normalize the four input shapes into one view-model.
  let vm;
  if (item.type === "li_action") {
    const a = item.action;
    const liNodes = a.moduleMap && a.moduleMap.nodes;
    vm = {
      icon: "link",
      title: a.title,
      typeLabel: "LinkedIn action",
      typeColor: "#4ade80",
      status: null,
      description: a.hint,
      // Prefer the step map (how it runs); fall back to the input fields.
      steps:
        liNodes && liNodes.length
          ? liNodes.map((n) => ({ name: n.name || n.id, type: n.type }))
          : (a.fields || []).map((f) => ({ name: f.label, type: f.type })),
      stepsHeading: liNodes && liNodes.length ? "How it runs" : "Inputs you set each run",
    };
  } else if (item.type === "x_action") {
    const a = item.action;
    const runnable = !!a.runFromHere;
    vm = {
      icon: "bird",
      title: a.label,
      typeLabel: runnable ? "X action · runs from here" : "X action",
      typeColor: "#93c5fd",
      status: null,
      description: a.description,
      steps: runnable
        ? (a.runFromHere.fields || []).map((f) => ({ name: f.label, type: f.type }))
        : (a.moduleMap?.nodes || []).map((n) => ({ name: n.name, type: n.type })),
      stepsHeading: runnable ? "Inputs you set each run" : "How it runs",
    };
  } else {
    // preset | custom
    const w = item.wf;
    const isCustom = item.type === "custom";
    vm = {
      icon: isCustom ? "🧩" : "⚙️",
      title: w.name || w.id,
      typeLabel: isCustom ? "Your workflow" : "Preset",
      typeColor: isCustom ? "#d8b4fe" : "#c4b5fd",
      status: isCustom ? w.status || "draft" : null,
      description: w.description || "—",
      steps: (w.nodes || w.steps || []).map((n) => ({
        name: n.name || n.label || n.id,
        type: n.type,
      })),
      stepsHeading: "Steps",
    };
  }

  // Header
  modal.appendChild(
    el("div", { style: "display:flex;align-items:center;gap:10px;margin-bottom:6px;" }, [
      icon.for(vm.icon)
        ? icon(icon.for(vm.icon))
        : el("span", { style: "font-size:22px;line-height:1;" }, vm.icon),
      el("h2", { style: "margin:0;font-size:18px;color:var(--text-1);flex:1;" }, vm.title),
      el(
        "span",
        {
          style: `font-size:10px;background:var(--bg-1);color:${vm.typeColor};padding:3px 8px;border-radius:8px;text-transform:uppercase;letter-spacing:0.5px;`,
        },
        vm.typeLabel,
      ),
      vm.status ? _renderConfigStatusPill(vm.status) : null,
    ]),
  );
  modal.appendChild(
    el(
      "p",
      { class: "muted", style: "margin:6px 0 16px;font-size:13px;line-height:1.55;color:#bbb;" },
      vm.description,
    ),
  );

  // "How it runs" / steps
  if (vm.steps && vm.steps.length) {
    modal.appendChild(
      el(
        "h3",
        {
          style:
            "margin:14px 0 8px;font-size:11px;color:var(--text-3);text-transform:uppercase;letter-spacing:0.6px;",
        },
        vm.stepsHeading,
      ),
    );
    const list = el("ol", {
      style: "margin:0;padding-left:24px;font-size:13px;line-height:1.7;color:#ddd;",
    });
    for (const s of vm.steps) {
      const gloss = _stepGloss(s.type);
      list.appendChild(
        el("li", { style: "margin-bottom:4px;" }, [
          el("span", { style: "color:#e8e8ef;" }, s.name),
          gloss ? el("span", { style: "color:#8a8a98;" }, ` — ${gloss}`) : null,
        ]),
      );
    }
    modal.appendChild(list);
  }

  // ── Consistent action bar (type-specific buttons live HERE) ───────
  const bar = el("div", {
    style:
      "display:flex;gap:8px;justify-content:flex-end;margin-top:22px;border-top:1px solid var(--border-soft);padding-top:16px;flex-wrap:wrap;",
  });
  bar.appendChild(el("button", { class: "btn btn-secondary", onclick: close }, "Close"));

  if (item.type === "li_action") {
    bar.appendChild(
      el(
        "button",
        {
          class: "btn btn-secondary",
          onclick: () => {
            close();
            navigate("action-log/linkedin");
          },
        },
        "Action log",
      ),
    );
    bar.appendChild(
      el(
        "button",
        {
          class: "btn btn-primary",
          onclick: () => {
            close();
            _openLiAutoConfigModal(item.action);
          },
        },
        "Configure & run →",
      ),
    );
  } else if (item.type === "x_action") {
    // Run-from-here actions get the headless "Configure & run" path (hidden
    // x.com worker tab); the rest still open x.com for the in-page launcher.
    if (item.action.runFromHere) {
      bar.appendChild(
        el(
          "button",
          {
            class: "btn btn-secondary",
            onclick: () => {
              window.open(item.action.launchUrl || "https://x.com", "_blank", "noopener");
            },
          },
          "Open X.com",
        ),
      );
      bar.appendChild(
        el(
          "button",
          {
            class: "btn btn-primary",
            onclick: () => {
              close();
              _openXRunConfigModal(item.action);
            },
          },
          "Configure & run →",
        ),
      );
    } else {
      bar.appendChild(
        el(
          "button",
          {
            class: "btn btn-primary",
            onclick: () => {
              window.open(item.action.launchUrl || "https://x.com", "_blank", "noopener");
              close();
            },
          },
          "Open X.com →",
        ),
      );
    }
  } else if (item.type === "preset") {
    // Presets run on their schedule. On-demand running requires a clone
    // first (run-now is keyed by custom_id), so we don't offer Run here —
    // we route the user to Clone, which produces a runnable custom.
    bar.appendChild(
      el(
        "button",
        {
          class: "btn btn-secondary",
          onclick: () => {
            close();
            navigate("automations/view/" + item.wf.id);
          },
        },
        "Open in canvas",
      ),
    );
    bar.appendChild(
      el(
        "button",
        {
          class: "btn btn-primary",
          onclick: () => {
            close();
            cloneAutomation(item.wf);
          },
        },
        "Clone to my workflows",
      ),
    );
  } else {
    // custom
    const w = item.wf;
    if (_autoIsWired(w.source_preset_id || w.id)) {
      bar.appendChild(
        el(
          "button",
          {
            class: "btn btn-secondary",
            onclick: async () => {
              close();
              await runAutomationNow(w);
            },
          },
          "Run now",
        ),
      );
    }
    bar.appendChild(
      el(
        "button",
        {
          class: "btn btn-secondary",
          onclick: async () => {
            close();
            await toggleAutomationStatus(w);
          },
        },
        w.status === "active" ? "Pause" : "Activate",
      ),
    );
    bar.appendChild(
      el(
        "button",
        {
          class: "btn btn-primary",
          onclick: () => {
            close();
            navigate("automations/view/" + (w.id || "custom_" + w.custom_id));
          },
        },
        "Open in canvas",
      ),
    );
  }
  // Hand the assembled body to the shared modal (the action bar `bar` is part
  // of `modal` body here rather than the footer slot, since the buttons are
  // built inline above; openModal still provides backdrop/Esc/focus-trap).
  modal.appendChild(bar);
  // No `title` — the body already renders a rich header (icon · title · badge);
  // pass ariaLabel so the dialog is still named for screen readers.
  const h = openModal({ body: modal, maxWidth: "600px", ariaLabel: vm.title });
  _h.close = h.close;
}

async function renderAutomationsHub({ platform } = {}) {
  const activePlatform = platform || "linkedin";
  const wrapper = el("div", { class: "automations-hub", style: "padding:16px;" });
  setContentNode(wrapper);

  // Page title + brief description
  wrapper.appendChild(
    el("div", { class: "page-header", style: "margin-bottom:10px;" }, [
      el("h1", { style: "margin:0;font-size:18px;" }, "Automations"),
      el(
        "p",
        { class: "muted", style: "margin:4px 0 0;font-size:12px;" },
        "Every automation you can run, by platform — on-demand actions and the always-on server engines. Click any card for details. Multi-step chains you build live in Workflows.",
      ),
    ]),
  );

  // Tab strip — platform scope. Catalog fetched up-front so each tab can
  // show a count badge of the server automations it contains.
  const catalog = await _fetchAutomationsCatalog();
  const buckets = _bucketAutomations(catalog.workflows || []);
  const tabs = _AUTO_TABS.map((t) => {
    const n = (buckets[t.bucket] || []).length;
    return {
      id: t.id,
      icon: t.icon,
      label: t.label,
      route: "automations/" + t.id,
      badge: n ? String(n) : null,
    };
  });
  wrapper.appendChild(_renderHubTabStrip(tabs, activePlatform));

  // Uniform capability banner — same component, same slot, every tab. This is
  // the consistency layer over the differing body structures below.
  const capBanner = _renderAutomationCapabilityBanner(activePlatform);
  if (capBanner) wrapper.appendChild(capBanner);

  // Content area for active tab
  const content = el("div", { class: "hub-content" });
  wrapper.appendChild(content);

  // Catalog failed to load — surface ONE honest error+retry banner so a failed
  // automations-list fetch never silently reads as "you have no server engines".
  // Non-fatal: the client-side LinkedIn/X actions below still render.
  if (catalog.__error) {
    content.appendChild(
      el(
        "div",
        {
          style:
            "margin-bottom:14px;padding:12px 14px;background:#1f1414;border:1px solid #5a2a2a;border-radius:8px;font-size:12px;color:var(--red);display:flex;align-items:center;gap:10px;",
        },
        [
          el("span", { style: "flex:1;" }, `Couldn't load server automations: ${catalog.__error}`),
          el(
            "button",
            {
              class: "btn btn-tiny btn-secondary",
              onclick: () => renderAutomationsHub({ platform: activePlatform }),
            },
            "↻ Retry",
          ),
        ],
      ),
    );
  }

  // Append this tab's server-side preset/custom section (the previously
  // missing automations). Shared across every tab so they read alike. When the
  // catalog loaded fine but this platform has no server presets, show a quiet
  // one-line note rather than an unexplained gap. Suppressed entirely if the
  // catalog failed (the error banner above already explains the absence).
  const appendPresets = (heading) => {
    const items = buckets[activePlatform] || [];
    const sec = _renderAutoPresetSection(items, { heading });
    if (sec) {
      content.appendChild(sec);
      return;
    }
    if (catalog.__error) return;
    content.appendChild(
      el(
        "div",
        {
          style:
            "margin-top:18px;padding:12px 14px;border:1px dashed var(--border-soft);border-radius:8px;font-size:12px;color:var(--text-4);",
        },
        "No always-on server engines for this platform yet — the on-demand actions above are ready to use.",
      ),
    );
  };

  if (activePlatform === "linkedin") {
    await _buildLiAutomationsBody(content);
    appendPresets("Server-side LinkedIn engines");
  } else if (activePlatform === "x") {
    content.appendChild(_renderAutomationsXTab());
    appendPresets("Server-side X engines");
  } else if (activePlatform === "gmail") {
    // Show a quick loading state while saved-config endpoints fetch.
    content.appendChild(
      el(
        "div",
        { class: "muted", id: "_auto-gmail-loading", style: "padding:14px;" },
        "Loading Gmail surfaces…",
      ),
    );
    const gmailBody = await _renderAutomationsGmailTab();
    content.innerHTML = "";
    content.appendChild(gmailBody);
    appendPresets("Server-side email engines");
  } else if (activePlatform === "telegram") {
    content.appendChild(
      el(
        "div",
        { class: "muted", id: "_auto-tg-loading", style: "padding:14px;" },
        "Loading Telegram surfaces…",
      ),
    );
    const tgBody = await _renderAutomationsTelegramTab();
    content.innerHTML = "";
    content.appendChild(tgBody);
    appendPresets("Server-side Telegram engines");
  } else if (activePlatform === "multi") {
    // New tab — multi-platform presets that coordinate 2+ outbound channels.
    const sec = _renderAutoPresetSection(buckets.multi, {});
    content.appendChild(
      sec ||
        el("div", { class: "empty-state", style: "padding:24px;" }, [
          el("div", { class: "empty-state-icon" }, icon("shuffle")),
          el("div", { class: "empty-state-title" }, "No multi-platform automations loaded"),
          el(
            "div",
            { class: "empty-state-hint" },
            "If you just added the Goals/Boost features, restart the Nexus bot so it loads the presets.",
          ),
        ]),
    );
  } else if (activePlatform === "system") {
    // New tab — CRM / enrichment / scoring / signal-source engines.
    const sec = _renderAutoPresetSection(buckets.system, {});
    content.appendChild(
      sec ||
        el("div", { class: "empty-state", style: "padding:24px;" }, [
          el("div", { class: "empty-state-icon" }, icon("settings")),
          el("div", { class: "empty-state-title" }, "No system automations loaded"),
          el(
            "div",
            { class: "empty-state-hint" },
            "Restart the Nexus bot and look for [WORKFLOW] Loaded N preset workflow(s) in the logs.",
          ),
        ]),
    );
  } else {
    content.appendChild(el("div", { class: "muted" }, `Unknown platform: ${activePlatform}`));
  }
}

// X (Twitter) tab — catalog-driven. Renders the 15 X actions defined in
// platform-actions.js, grouped by category. Each card opens a detail
// modal showing the workflow DAG (from action.moduleMap) + a CTA that
// opens x.com so the user can run it from the in-page launcher. When
// the background-tab adapter lands (Phase B), the modal's CTA flips to
// "Run from here" and fires an swAction the way LinkedIn cards do.
function _renderAutomationsXTab() {
  const catalog =
    typeof window !== "undefined" && Array.isArray(window.PLATFORM_ACTIONS)
      ? window.PLATFORM_ACTIONS
      : [];
  const actions = catalog.filter((a) => a.platform === "twitter");

  if (actions.length === 0) {
    return el(
      "div",
      { class: "muted", style: "padding:20px;text-align:center;" },
      "Platform action catalog not loaded — reload the extension.",
    );
  }

  // Group by category. Category order matches what makes sense to
  // explore: find-people → engage → grow → maintain.
  const CATEGORY_ORDER = ["intelligence", "engagement", "grow", "manage"];
  const CATEGORY_META = {
    intelligence: {
      icon: "search",
      label: "Intelligence",
      blurb: "Find the right people to target.",
    },
    engagement: { icon: "star", label: "Engagement", blurb: "Show up in feeds and conversations." },
    grow: { icon: "trend", label: "Grow", blurb: "Build your follower base." },
    manage: { icon: "settings", label: "Manage", blurb: "Long-haul maintenance + autopilot." },
  };
  const byCategory = {};
  for (const a of actions) {
    const cat = a.category || "other";
    (byCategory[cat] = byCategory[cat] || []).push(a);
  }

  const wrap = el("div", {});
  // (The "runs on x.com" explainer now lives in the shared capability banner
  // at the top of the hub — _renderAutomationCapabilityBanner — so every tab
  // states its run-model consistently.)

  const renderedCats = new Set();
  const renderCat = (catKey) => {
    const items = byCategory[catKey];
    if (!items || items.length === 0) return;
    renderedCats.add(catKey);
    const meta = CATEGORY_META[catKey] || { icon: "•", label: catKey, blurb: "" };

    wrap.appendChild(
      el("div", { style: "margin-bottom:8px;display:flex;align-items:baseline;gap:10px;" }, [
        el(
          "h3",
          { style: "margin:0;font-size:13px;color:var(--text-1);" },
          `${icon.for(meta.icon) ? iconHtml(icon.for(meta.icon)) : meta.icon} ${meta.label}`,
        ),
        el("span", { class: "muted", style: "font-size:11px;" }, meta.blurb),
      ]),
    );
    const grid = el("div", {
      style:
        "display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:12px;margin-bottom:22px;",
    });
    for (const a of items) grid.appendChild(_renderXActionCard(a));
    wrap.appendChild(grid);
  };

  // Known categories first in our preferred order, then any leftovers.
  for (const c of CATEGORY_ORDER) renderCat(c);
  for (const c of Object.keys(byCategory)) if (!renderedCats.has(c)) renderCat(c);

  return wrap;
}

// Single X action card. Hover-highlighted, click → detail modal.
function _renderXActionCard(action) {
  const stepCount = action.moduleMap?.nodes?.length || 0;
  const open = () => openAutomationDetail({ type: "x_action", action });
  return el(
    "div",
    {
      class: "card x-action-card",
      role: "button",
      tabindex: "0",
      "aria-label": `${action.label} — view details`,
      style:
        "background:var(--bg-card);border:1px solid var(--border-soft);border-radius:10px;padding:14px;display:flex;flex-direction:column;gap:8px;cursor:pointer;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)";
      },
      onclick: open,
      onkeydown: (e) => {
        if (e.key === "Enter" || e.key === " ") {
          e.preventDefault();
          open();
        }
      },
    },
    [
      el("div", { style: "display:flex;align-items:center;gap:8px;" }, [
        el("h4", { style: "margin:0;font-size:14px;color:var(--text-1);flex:1;" }, action.label),
        stepCount > 0
          ? el(
              "span",
              {
                style:
                  "font-size:10px;color:var(--text-3);background:var(--bg-1);padding:2px 7px;border-radius:6px;font-family:monospace;",
              },
              `${stepCount} steps`,
            )
          : null,
      ]),
      el(
        "div",
        { class: "muted", style: "font-size:12px;line-height:1.5;color:#999;flex:1;" },
        action.description,
      ),
      el("div", { style: "display:flex;gap:6px;margin-top:auto;align-items:center;" }, [
        el(
          "span",
          {
            style:
              "font-size:10px;background:var(--border-soft);color:var(--text-2);padding:2px 7px;border-radius:6px;text-transform:uppercase;letter-spacing:0.4px;",
          },
          action.category || "—",
        ),
        el(
          "span",
          { style: "font-size:10px;color:var(--text-4);margin-left:auto;" },
          "view workflow →",
        ),
      ]),
    ],
  );
}
