(() => {
  const esc = value => String(value ?? '')
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/\"/g, '&quot;');

  const byId = id => document.getElementById(id);
  const clickId = id => {
    const el = byId(id);
    if (!el) return false;
    el.click();
    return true;
  };

  const writeClipboard = async text => {
    const value = String(text ?? '');
    if (!value) return false;
    try {
      await navigator.clipboard.writeText(value);
      return true;
    } catch {
      return false;
    }
  };

  const callApi = async (path, method = 'GET', body = null) => {
    if (typeof window.api !== 'function') return { ok: false, error: 'api_unavailable' };
    return await window.api(path, method, body);
  };

  const toast = msg => window.toast?.(msg);
  const appendLog = (text, tone = 'neutral') => window.appendLog?.(text, tone);

  const openPrimaryTab = tab => {
    const btn = document.querySelector(`.tab-btn[data-tab=\"${tab}\"]`);
    if (!btn) return false;
    btn.click();
    return true;
  };

  const openHistoryTab = htab => {
    openPrimaryTab('history');
    const btn = document.querySelector(`.htab-btn[data-htab=\"${htab}\"]`);
    if (!btn) return false;
    btn.click();
    return true;
  };

  const ensureAllDubFiltersVisible = () => {
    document.querySelectorAll('#dubs-categories .dub-cat.inactive').forEach(el => el.click());
  };

  const ensureDubFilterActive = kind => {
    const el = document.querySelector(`#dubs-categories .dub-cat[data-kind=\"${kind}\"]`);
    if (!el) return false;
    if (el.classList.contains('inactive')) el.click();
    return true;
  };

  const setCheckboxAndSave = checkedId => {
    const input = byId(checkedId);
    if (!input) return false;
    input.checked = !input.checked;
    clickId('settings-save-btn');
    return true;
  };

  const copyProjectOverview = async () => {
    const overview = {
      details: {
        name: byId('proj-name')?.value?.trim() || '',
        location: byId('proj-location')?.value?.trim() || '',
        summary: byId('proj-summary')?.value?.trim() || '',
        notes: byId('proj-notes')?.value?.trim() || ''
      },
      outline: (() => {
        try {
          return JSON.parse(localStorage.getItem('nv_projectOutline') || 'null');
        } catch {
          return null;
        }
      })()
    };
    const ok = await writeClipboard(JSON.stringify(overview, null, 2));
    if (ok) {
      toast('Project overview copied');
      appendLog('⧉ project overview copied', 'pass');
    } else {
      toast('Copy failed');
    }
    return ok;
  };

  const runClearTape = async () => {
    const data = await callApi('/playback/clear', 'POST');
    if (data.ok) {
      appendLog(`⏏ tape cleared (${data.cleared ?? 0} entries)`, 'neutral');
      toast(`Tape cleared — ${data.cleared ?? 0} entries removed`);
      await window.refreshDubTape?.();
      await window.refreshTape?.();
      return true;
    }
    toast('Clear tape failed');
    return false;
  };

  const commands = {
    'file.settings': { run: () => openPrimaryTab('settings') },
    'file.reload_ui': { run: () => window.location.reload() },
    'file.reboot_backend': { enabled: () => false, run: () => false },
    'file.resync_ai_lm': { enabled: () => false, run: () => false },
    'file.exit': { run: () => { window.close(); return true; } },
    'edit.copy': { run: () => document.execCommand?.('copy') },
    'edit.cut': { run: () => document.execCommand?.('cut') },
    'edit.paste': { run: () => document.execCommand?.('paste') },
    'edit.delete': { run: () => document.execCommand?.('delete') },
    'edit.find': {
      run: () => {
        const term = prompt('Find:')?.trim();
        if (!term) return false;
        const editor = byId('editor-textarea');
        if (editor && editor.offsetParent !== null) {
          const text = editor.value || '';
          const start = editor.selectionEnd || 0;
          const index = text.indexOf(term, start) >= 0 ? text.indexOf(term, start) : text.indexOf(term);
          if (index >= 0) {
            editor.focus();
            editor.setSelectionRange(index, index + term.length);
            return true;
          }
        }
        return window.find ? window.find(term) : false;
      }
    },
    'project.switch_project': { run: () => { const select = byId('project-select'); if (!select) return false; select.focus(); return true; } },
    'project.open_project_folder': {
      run: async () => {
        const data = await callApi('/projects/open-folder', 'POST');
        if (data?.ok) {
          toast('Project folder opened');
          appendLog(`📂 opened project folder → ${data.project || ''}`, 'pass');
          return true;
        }
        toast('Open project folder failed');
        appendLog(`✗ open project folder failed: ${data?.error || 'unknown'}`, 'fail');
        return false;
      }
    },
    'project.create_project': { run: () => clickId('project-create-btn') },
    'project.save_project': { run: () => clickId('proj-save-btn') },
    'project.reset_project_form': { run: () => clickId('proj-reset-btn') },
    'project.copy_project_overview': { run: () => copyProjectOverview() },
    'diagnostics.view_dubs_tape': { run: () => { openPrimaryTab('dubs'); ensureAllDubFiltersVisible(); return true; } },
    'diagnostics.view_diagnostics': { run: () => { openPrimaryTab('dubs'); ensureDubFilterActive('diagnostic'); return true; } },
    'diagnostics.view_errors': { run: () => { openPrimaryTab('dubs'); ensureDubFilterActive('error'); return true; } },
    'diagnostics.clear_tape': { run: () => runClearTape() },
    'diagnostics.archive_tape': { run: () => { openHistoryTab('tape'); return clickId('tape-archive-btn'); } },
    'transport.auto_accept_chat': { checked: () => Boolean(byId('set-auto-chat-manifests')?.checked), run: () => { openPrimaryTab('settings'); return setCheckboxAndSave('set-auto-chat-manifests'); } },
    'transport.auto_accept_diagnostic': { checked: () => Boolean(byId('set-auto-diagnostic-repair')?.checked), run: () => { openPrimaryTab('settings'); return setCheckboxAndSave('set-auto-diagnostic-repair'); } },
    'transport.auto_accept_enhancement': { checked: () => Boolean(byId('set-auto-enhancement-suggestions')?.checked), run: () => { openPrimaryTab('settings'); return setCheckboxAndSave('set-auto-enhancement-suggestions'); } },
    'transport.pause': { run: () => clickId('btn-pause') },
    'transport.next': { run: () => clickId('btn-next') },
    'transport.previous': { run: () => clickId('btn-prev') },
    'utilities.scrape_project': {
      enabled: () => false,
      run: () => {
        toast('Scrape Project is not wired yet');
        appendLog('scrape project not available yet', 'neutral');
        return false;
      }
    },
    'utilities.add_restore_point': { run: () => { openPrimaryTab('history'); openHistoryTab('system'); return clickId('restore-point-btn'); } },
    'utilities.view_restore_points': { run: () => { openPrimaryTab('history'); openHistoryTab('system'); return clickId('restore-list-btn'); } },
    'utilities.apply_diagnostic_repair': { enabled: () => false, run: () => false },
    'help.get_input_contract': { enabled: () => false, run: () => false },
    'help.get_agent_yaml': { enabled: () => false, run: () => false },
    'help.subscription': { enabled: () => false, run: () => false },
    'help.check_version': { enabled: () => false, run: () => false },
    'help.get_help': { enabled: () => false, run: () => false },
    'help.about': { run: () => { toast('Nodarama Verbatim'); appendLog('ℹ about → Nodarama Verbatim', 'neutral'); return true; } }
  };

  const sections = [
    { id: 'file', label: 'File', items: [
      { id: 'file.settings', label: 'Settings' },
      { id: 'file.reload_ui', label: 'Reload UI' },
      { id: 'file.reboot_backend', label: 'Reboot Backend' },
      { id: 'file.resync_ai_lm', label: 'Resync AI / LM' },
      { id: 'file.exit', label: 'Exit' }
    ]},
    { id: 'edit', label: 'Edit', items: [
      { id: 'edit.copy', label: 'Copy' },
      { id: 'edit.cut', label: 'Cut' },
      { id: 'edit.paste', label: 'Paste' },
      { id: 'edit.delete', label: 'Delete' },
      { id: 'edit.find', label: 'Find' }
    ]},
    { id: 'project', label: 'Project', items: [
      { id: 'project.switch_project', label: 'Switch Project' },
      { id: 'project.open_project_folder', label: 'Open Project Folder' },
      { id: 'project.create_project', label: 'Create Project' },
      { id: 'project.save_project', label: 'Save Project' },
      { id: 'project.reset_project_form', label: 'Reset Project Form' },
      { id: 'project.copy_project_overview', label: 'Copy Project Overview' }
    ]},
    { id: 'transport', label: 'Transport', items: [
      { id: 'transport.auto_accept_chat', label: 'Auto Accept Chat Proposal' },
      { id: 'transport.auto_accept_diagnostic', label: 'Auto Accept Diagnostic' },
      { id: 'transport.auto_accept_enhancement', label: 'Auto Accept Enhancement' },
      { id: 'transport.pause', label: 'Pause' },
      { id: 'transport.next', label: 'Next' },
      { id: 'transport.previous', label: 'Previous' }
    ]},
    { id: 'diagnostics', label: 'Diagnostics', items: [
      { id: 'diagnostics.view_dubs_tape', label: 'View Dub Tape' },
      { id: 'diagnostics.view_diagnostics', label: 'View Diagnostics' },
      { id: 'diagnostics.view_errors', label: 'View Errors' },
      { id: 'diagnostics.clear_tape', label: 'Clear Tape' },
      { id: 'diagnostics.archive_tape', label: 'Archive all viewed' }
    ]},
    { id: 'utilities', label: 'Utilities', items: [
      { id: 'utilities.scrape_project', label: 'Scrape Project' },
      { id: 'utilities.add_restore_point', label: 'Add Restore Point' },
      { id: 'utilities.view_restore_points', label: 'View Restore Points' },
      { id: 'utilities.apply_diagnostic_repair', label: 'Apply Diagnostic Repair' }
    ]},
    { id: 'help', label: 'About', items: [
      { id: 'help.get_input_contract', label: 'Get Input Contract' },
      { id: 'help.get_agent_yaml', label: 'Get Agent YAML' },
      { id: 'help.subscription', label: 'Subscription' },
      { id: 'help.check_version', label: 'Check Version' },
      { id: 'help.get_help', label: 'Get Help' },
      { id: 'help.about', label: 'About' }
    ]}
  ];

  let overlay = null;
  let panel = null;
  let activeSectionId = 'file';

  function isEnabled(item) {
    const cmd = commands[item.id];
    if (!cmd) return false;
    return typeof cmd.enabled === 'function' ? !!cmd.enabled() : true;
  }

  function isChecked(item) {
    const cmd = commands[item.id];
    return typeof cmd?.checked === 'function' ? !!cmd.checked() : false;
  }

  function getActiveSection() {
    return sections.find(section => section.id === activeSectionId) || sections[0];
  }

  function injectStyles() {
    if (byId('nv-sysmenu-style')) return;
    const style = document.createElement('style');
    style.id = 'nv-sysmenu-style';
    style.textContent = `
      .nv-sysmenu-overlay{position:fixed;inset:0;background:transparent;z-index:9999;pointer-events:none}
      .nv-sysmenu-panel{position:fixed;top:106px;left:12px;display:flex;align-items:flex-start;gap:0;pointer-events:auto}
      .nv-sysmenu-column{min-width:176px;background:rgba(35,35,51,.94);border:1px solid rgba(105,86,52,.55);box-shadow:0 0 0 1px rgba(224,92,53,.06),0 8px 22px rgba(0,0,0,.34)}
      .nv-sysmenu-column.submenu{min-width:228px;margin-left:-1px}
      .nv-sysmenu-item{width:100%;display:flex;align-items:center;justify-content:space-between;gap:12px;text-align:left;background:transparent;border:0;border-bottom:1px solid rgba(86,86,108,.52);padding:10px 16px;color:#b9bcc8;font:400 15px/1.15 'Courier New','Courier',monospace;cursor:pointer}
      .nv-sysmenu-item:last-child{border-bottom:0}
      .nv-sysmenu-item:hover{background:rgba(255,255,255,.03);color:#f0f1f6}
      .nv-sysmenu-item.active{color:#f0c040}
      .nv-sysmenu-item.disabled{color:#76798a;cursor:not-allowed}
      .nv-sysmenu-item.disabled:hover{background:transparent;color:#76798a}
      .nv-sysmenu-check{min-width:16px;text-align:right;color:#f0c040}
      .nv-sysmenu-caret{min-width:12px;text-align:right;color:#8d90a0}
      .nv-sysmenu-subtitle{padding:10px 16px;border-bottom:1px solid rgba(86,86,108,.52);background:transparent;color:#8d90a0;font:400 13px/1.1 'Courier New','Courier',monospace;letter-spacing:.08em;text-transform:uppercase}
    `;
    document.head.appendChild(style);
  }

  async function run(id) {
    const item = { id };
    if (!isEnabled(item)) return false;
    const cmd = commands[id];
    if (!cmd || typeof cmd.run !== 'function') return false;
    try {
      const result = await cmd.run();
      render();
      return result;
    } catch {
      toast('Menu action failed');
      appendLog(`✗ menu action failed: ${id}`, 'fail');
      return false;
    }
  }

  function buildSectionItem(section) {
    const active = section.id === getActiveSection().id;
    return `
      <button class="nv-sysmenu-item${active ? ' active' : ''}" data-section-id="${esc(section.id)}">
        <span>${esc(section.label)}</span>
        <span class="nv-sysmenu-caret">${active ? '›' : ''}</span>
      </button>
    `;
  }

  function buildCommandItem(item) {
    const enabled = isEnabled(item);
    const checked = isChecked(item);
    return `
      <button class="nv-sysmenu-item${enabled ? '' : ' disabled'}" data-command-id="${esc(item.id)}" ${enabled ? '' : 'disabled'}>
        <span>${esc(item.label)}</span>
        <span class="nv-sysmenu-check">${checked ? '✓' : ''}</span>
      </button>
    `;
  }

  function render() {
    if (!panel) return;
    const activeSection = getActiveSection();
    panel.innerHTML = `
      <div class="nv-sysmenu-column mainmenu">
        ${sections.map(buildSectionItem).join('')}
      </div>
      <div class="nv-sysmenu-column submenu">
        <div class="nv-sysmenu-subtitle">${esc(activeSection.label)}</div>
        ${activeSection.items.map(buildCommandItem).join('')}
      </div>
    `;

    panel.querySelectorAll('[data-section-id]').forEach(el => {
      el.addEventListener('mouseenter', () => {
        const id = el.getAttribute('data-section-id');
        if (!id || id === activeSectionId) return;
        activeSectionId = id;
        render();
      });
      el.addEventListener('click', () => {
        const id = el.getAttribute('data-section-id');
        if (!id || id === activeSectionId) return;
        activeSectionId = id;
        render();
      });
    });

    panel.querySelectorAll('[data-command-id]').forEach(el => {
      el.addEventListener('click', async () => {
        const id = el.getAttribute('data-command-id');
        if (!id) return;
        const ok = await run(id);
        if (ok !== false && id !== 'utilities.add_restore_point' && id !== 'utilities.view_restore_points') close();
      });
    });
  }

  function open() {
    injectStyles();
    if (!overlay) {
      overlay = document.createElement('div');
      overlay.className = 'nv-sysmenu-overlay';
      panel = document.createElement('div');
      panel.className = 'nv-sysmenu-panel';
      overlay.appendChild(panel);
      overlay.addEventListener('click', event => {
        if (event.target === overlay) close();
      });
      document.body.appendChild(overlay);
    }
    render();
  }

  function close() {
    overlay?.remove();
    overlay = null;
    panel = null;
  }

  function toggle() {
    if (overlay) close();
    else open();
  }

  document.addEventListener('keydown', event => {
    if (event.key === 'Escape' && overlay) {
      event.preventDefault();
      close();
      return;
    }
    if (event.key === 'Tab' && event.altKey && overlay) {
      close();
      return;
    }
    if (event.key === 'Alt') {
      const target = event.target;
      const tag = target?.tagName?.toLowerCase?.() || '';
      if (tag === 'input' || tag === 'textarea') return;
      event.preventDefault();
      toggle();
    }
  });

  window.addEventListener('blur', () => {
    if (overlay) close();
  });

  window.SysMenu = { sections, commands, open, close, toggle, run, render };
})();