// fre.js — First-Run Experience banner for empty-state dashboards (W-mpehchnt000w46da).
//
// Renders a two-step onboarding banner at the top of the main content area when
// the operator has zero projects configured AND has not explicitly dismissed the
// banner. Self-contained and idempotent — safe to call renderFre() every tick.
//
// Trigger: projects.length === 0 AND localStorage.minions_fre_dismissed !== '1'.
// Auto-hide (no dismissal flag set) when projects.length >= 1 — the banner has
// served its purpose. If the user later removes all projects we re-show.

const FRE_DISMISS_KEY = 'minions_fre_dismissed';
const FRE_MOUNT_ID = 'fre-banner';

function _freIsDismissed() {
  try { return localStorage.getItem(FRE_DISMISS_KEY) === '1'; } catch { return false; }
}

function dismissFre() {
  try { localStorage.setItem(FRE_DISMISS_KEY, '1'); } catch { /* expected */ }
  const mount = document.getElementById(FRE_MOUNT_ID);
  if (mount) mount.innerHTML = '';
}

// Reset helper (exposed for tests / debugging only). Not wired to UI.
function _freReset() {
  try { localStorage.removeItem(FRE_DISMISS_KEY); } catch { /* expected */ }
}

// Open the Settings modal and scroll to the Default CLI control (id=set-defaultCli).
// The modal lives in a separate modal layer, not a sidebar page — openSettings()
// is async (loads /api/settings) so we await it before scrolling.
async function openSettingsToDefaultCli() {
  if (typeof openSettings !== 'function') return;
  try {
    await openSettings();
  } catch { /* settings fetch failure already toasts */ return; }
  // openSettings injects innerHTML synchronously after the fetch resolves, so
  // set-defaultCli is in the DOM by now. initRuntimeFleetUI() runs separately
  // and hydrates options — but the <select> element itself is already present.
  setTimeout(function() {
    const el = document.getElementById('set-defaultCli');
    if (!el) return;
    try { el.scrollIntoView({ behavior: 'smooth', block: 'center' }); } catch { /* old browser */ }
    try { el.focus({ preventScroll: true }); } catch { /* expected */ }
    const prevOutline = el.style.outline;
    el.style.outline = '2px solid var(--blue)';
    el.style.outlineOffset = '2px';
    setTimeout(function() { el.style.outline = prevOutline; el.style.outlineOffset = ''; }, 2000);
  }, 50);
}

// Render the FRE banner into #fre-banner. Idempotent — bails out early when:
//   • mount point missing (layout didn't load yet)
//   • banner explicitly dismissed
//   • projects.length >= 1 (auto-hide)
// Otherwise renders the two-step card.
//
// Accepts the current /api/status payload (or just a projects array, for tests).
// When passed the full payload, autoMode.defaultCli drives the runtime label.
function renderFre(statusOrProjects) {
  const mount = document.getElementById(FRE_MOUNT_ID);
  if (!mount) return;
  const isArr = Array.isArray(statusOrProjects);
  const projects = isArr
    ? statusOrProjects
    : (statusOrProjects && Array.isArray(statusOrProjects.projects) ? statusOrProjects.projects : []);
  const status = isArr ? (window._lastStatus || {}) : (statusOrProjects || {});
  const projectCount = projects.length;
  // Bail-out paths assign an empty string literal on its own line so the
  // SEC-03 dynamic-innerHTML counter (test/unit.test.js
  // DYNAMIC_INNERHTML_BASELINE) treats them as exempt.
  if (projectCount >= 1) {
    mount.innerHTML = '';
    return;
  }
  if (_freIsDismissed()) {
    mount.innerHTML = '';
    return;
  }

  // Resolve the currently-configured runtime CLI for the explainer copy.
  // /api/status surfaces this as autoMode.defaultCli (resolveAgentCli(null, engine)).
  // Fall back to autoMode.ccCli (also defaultCli-derived when ccCli unset) then 'copilot'
  // (matches ENGINE_DEFAULTS.defaultCli — W-mpmwxkk40007c995).
  const auto = (status && status.autoMode) || {};
  const runtimeCli = String(auto.defaultCli || auto.ccCli || 'copilot');

  const cardStyle = [
    'margin:12px 24px',
    'padding:16px 20px',
    'background:var(--surface2)',
    'border:1px solid var(--blue)',
    'border-radius:var(--radius-lg)',
    'color:var(--text)',
    'font-size:var(--text-lg)',
    'box-shadow:var(--shadow-md)',
  ].join(';');

  const stepBox = [
    'display:flex',
    'gap:12px',
    'align-items:flex-start',
    'padding:10px 12px',
    'background:var(--surface)',
    'border:1px solid var(--border)',
    'border-radius:var(--radius-sm)',
  ].join(';');

  const stepNum = [
    'display:inline-flex',
    'align-items:center',
    'justify-content:center',
    'width:22px',
    'height:22px',
    'border-radius:var(--radius-full)',
    'background:var(--blue)',
    'color:#fff',
    'font-weight:700',
    'font-size:var(--text-base)',
    'flex-shrink:0',
  ].join(';');

  // W-mq57qetc0009ed48: blue-primary CTA inline blob removed; "+ Add Project"
  // now uses the shared .btn-primary-solid primitive. Only the layout-only
  // margin-top:8px stays inline.
  const btnPrimaryMarginTop = 'margin-top:8px';

  const btnGhost = [
    'padding:6px 14px',
    'background:transparent',
    'color:var(--blue)',
    'border:1px solid var(--blue)',
    'border-radius:var(--radius-sm)',
    'cursor:pointer',
    'font-size:var(--text-md)',
    'font-weight:600',
    'margin-top:8px',
  ].join(';');

  const dismissBtn = [
    'background:none',
    'border:none',
    'color:var(--muted)',
    'cursor:pointer',
    'font-size:var(--text-base)',
    'padding:2px 8px',
  ].join(';');

  // Use textContent-safe interpolation for the runtime label (config-derived, but defensive).
  const safeRuntime = String(runtimeCli).replace(/[<>&"']/g, function(c) {
    return ({ '<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;', "'": '&#39;' })[c];
  });

  // eslint-disable-next-line no-unsanitized/property -- reason: structural HTML is a string literal; runtime label is escaped into safeRuntime before interpolation (field: runtimeCli)
  mount.innerHTML =
    '<div id="fre-card" style="' + cardStyle + '">' +
      '<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:10px">' +
        '<div style="font-size:var(--text-xl);font-weight:700;color:var(--blue)">&#x1F44B; Welcome to Minions</div>' +
        '<button onclick="dismissFre()" style="' + dismissBtn + '" title="Hide this banner — clear localStorage.minions_fre_dismissed to re-show">Dismiss</button>' +
      '</div>' +
      '<div style="color:var(--muted);font-size:var(--text-md);margin-bottom:12px">Two quick steps to get your fleet ready.</div>' +
      '<div style="display:flex;flex-direction:column;gap:10px">' +

        '<div style="' + stepBox + '">' +
          '<span style="' + stepNum + '">1</span>' +
          '<div style="flex:1">' +
            '<div style="font-weight:600;margin-bottom:2px">Pick your runtime CLI</div>' +
            '<div style="color:var(--muted);font-size:var(--text-md);line-height:1.5">' +
              'Minions spawns agents through this CLI. Switch via Settings &rarr; Engine &rarr; Default CLI (<code>claude</code> or <code>copilot</code>). ' +
              'Currently: <code style="background:var(--bg);padding:1px 6px;border-radius:3px;color:var(--text)">' + safeRuntime + '</code>' +
            '</div>' +
            '<button onclick="openSettingsToDefaultCli()" style="' + btnGhost + '">Open Settings &rarr; Default CLI</button>' +
          '</div>' +
        '</div>' +

        '<div style="' + stepBox + '">' +
          '<span style="' + stepNum + '">2</span>' +
          '<div style="flex:1">' +
            '<div style="font-weight:600;margin-bottom:2px">Add your first project</div>' +
            '<div style="color:var(--muted);font-size:var(--text-md);line-height:1.5">' +
              'Projects map a local git worktree to a remote repo. Without a project, agents have nowhere to run.' +
            '</div>' +
            '<button onclick="addProject()" class="btn-primary-solid" style="' + btnPrimaryMarginTop + '">+ Add Project</button>' +
          '</div>' +
        '</div>' +

      '</div>' +
    '</div>';
}

window.MinionsFre = { renderFre, dismissFre, openSettingsToDefaultCli, _freReset, FRE_DISMISS_KEY };
