// auxrender.js — AUX sidepanel renderer
// Owns cards, buttons, status display, skin display, and visual UI behavior.
// Does not own detection, Verbatim transport, or belt decisions.

import {
  lineIn,
  lineOut,
  getHealth,
  endpoint,
  requestFileInquiry,
  autoFileInquiry,
  feedLineInItem,
  sendLineOutItem,
  sendAllLineOut,
  completeCodeDetails,
  discardLineOutItem,
  clearLineOut,
  runHardwareButton,
  toFeedText
} from './auxio.js';

let renderOptions = {
  saveConfig: null,
  getConfig: null
};

const traceRows = [];
const MAX_TRACE_ROWS = 80;

const els = {};

export async function initRender(options = {}) {
  renderOptions = {
    ...renderOptions,
    ...options
  };

  collectElements();
  bindSettings();
  bindManualFileInquiry();
  bindTraceTools();
  bindHardwareButtons();
  bindMonitorMenu();
  bindRenderEvents();

  renderAll();

  return true;
}

// ─────────────────────────────────────────────────────────────
// Public status hooks used by auxsystem.js
// ─────────────────────────────────────────────────────────────

export function applyAuxSkin(skin = 'cruise') {
  const clean = skin === 'studio' ? 'studio' : 'cruise';

  if (document.body) {
    document.body.dataset.skin = clean;
  }

  const logo = document.getElementById('skin-logo');

  if (logo) {
    logo.src = clean === 'studio'
      ? 'assets/studiologo.png'
      : 'assets/cruiselogo.png';
  }

  const buttons = document.getElementById('skin-buttons');

  if (buttons) {
    buttons.src = clean === 'studio'
      ? 'assets/studiobuttons.png'
      : 'assets/cruisebuttons.png';
  }

  const buttonFrame = document.getElementById('skin-button-frame');

  if (buttonFrame) {
    buttonFrame.src = clean === 'studio'
      ? 'assets/studiobuttonframe.png'
      : 'assets/cruisebuttonframe.png';
  }

  const frame = document.getElementById('skin-frame');

  if (frame) {
    frame.src = clean === 'studio'
      ? 'assets/studioframe.png'
      : 'assets/cruiseframe.png';
  }

  const toggle = document.getElementById('skin-toggle');

  if (toggle) {
    if (!toggle.querySelector('.SkinMoon-Eo') || !toggle.querySelector('.SkinSun-Eo')) {
      toggle.innerHTML = '<span class="SkinMoon-Eo">☾</span><span class="SkinSun-Eo">☀</span>';
    }

    const nextLabel = clean === 'studio' ? 'cruise' : 'studio';
    toggle.title = `Switch to ${nextLabel} skin`;
    toggle.setAttribute('aria-label', `Switch to ${nextLabel} skin`);
  }

  return clean;
}
export function setProviderStatus(provider = 'IDLE', profile = {}) {
  const label = String(provider || 'IDLE').toUpperCase();

  setText([
    'provider-status',
    'active-provider',
    'surface-provider',
    'status-provider',
    'model-name'
  ], label);

  setText([
    'surface-name',
    'active-surface',
    'surface-status'
  ], profile.surfaceName || profile.surfaceType || label);

  setClassState([
    'provider-status',
    'active-provider',
    'surface-provider',
    'status-provider',
    'status-light-ai'
  ], 'is-active', label !== 'IDLE' && label !== 'UNKNOWN');

  pushTrace({
    file: 'auxrender.js',
    fn: 'setProviderStatus',
    step: 'active tab updated',
    note: `${label}${profile.contractAware ? ' · contract aware' : ''}`
  });
}
export function setVerbatimStatus(isConnected) {
  const connected = Boolean(isConnected);

  if (document.body) {
    document.body.dataset.verbatim = connected ? 'connected' : 'offline';
  }

  setText([
    'verbatim-status',
    'connection-status',
    'status-verbatim',
    'status-text'
  ], connected ? 'Verbatim connected' : 'Verbatim offline');

  setClassState([
    'verbatim-status',
    'connection-status',
    'status-verbatim',
    'status-light-verbatim'
  ], 'is-connected', connected);

  setClassState([
    'verbatim-status',
    'connection-status',
    'status-verbatim',
    'status-light-verbatim'
  ], 'is-offline', !connected);
}
export function pushTrace(row = {}) {
  const trace = {
    at: new Date().toLocaleTimeString(),
    file: row.file || 'AUX',
    fn: row.fn || '',
    step: row.step || '',
    note: row.note || row.msg || ''
  };

  traceRows.unshift(trace);

  if (traceRows.length > MAX_TRACE_ROWS) {
    traceRows.length = MAX_TRACE_ROWS;
  }

  renderTrace();
}

// ─────────────────────────────────────────────────────────────
// Element collection
// ─────────────────────────────────────────────────────────────

function collectElements() {
  els.lineIn = byId('linein-cards') || byId('line-in-cards') || query('[data-aux-line="in"]');
  els.lineOut = byId('lineout-cards') || byId('line-out-cards') || query('[data-aux-line="out"]');
  els.trace = byId('trace-cards') || byId('trace-list') || query('[data-aux-trace]');

  els.hostInput = byId('verbatim-host') || byId('host-input') || byId('endpoint-host');
  els.portInput = byId('port') || byId('verbatim-port') || byId('port-input') || byId('endpoint-port');

  els.saveConfig = byId('save-settings') || byId('save-config-btn') || byId('save-host-btn') || query('[data-action="save-config"]');
  els.checkConnection = byId('check-connection-btn') || query('[data-action="check-connection"]') || query('[data-action="check-connections"]');

  els.manualTarget = byId('manual-file-inquiry') || byId('auxcall-input') || query('[data-aux-manual-file]');
  els.manualAux = byId('manual-file-aux') || query('[data-action="manual-file-aux"]');
  els.manualVrbm = byId('manual-file-vrbm') || query('[data-action="manual-file-vrbm"]');
  els.manualAuto = byId('manual-file-auto') || query('[data-action="manual-file-auto"]');
  els.copyTrace = byId('copy-trace') || query('[data-action="copy-trace"]');
}
function byId(id) {
  return document.getElementById(id);
}

function query(selector) {
  return document.querySelector(selector);
}

// ─────────────────────────────────────────────────────────────
// Main render
// ─────────────────────────────────────────────────────────────

function renderAll() {
  renderLineIn();
  renderLineOut();
  renderTrace();
  renderCounts();
}

function renderCounts() {
  setText(['linein-count', 'line-in-count'], String(lineIn.items.length));
  setText(['lineout-count', 'line-out-count'], String(lineOut.items.length));
}

// ─────────────────────────────────────────────────────────────
// LINE IN render
// ─────────────────────────────────────────────────────────────

function renderLineIn() {
  if (!els.lineIn) return;

  els.lineIn.innerHTML = '';

  if (!lineIn.items.length) {
    els.lineIn.appendChild(emptyCard('LINE IN', 'No File Inquiry results yet.'));
    return;
  }

  lineIn.items.forEach((item, index) => {
    els.lineIn.appendChild(renderLineInCard(item, index));
  });
}

function visibleAuxAction(item = {}) {
  const explicit = String(item.routeLabel || '').trim().toUpperCase();
  if (explicit) return explicit;

  const action = String(item.action || item.command || item.Action || '').trim().toLowerCase();
  if (action.includes('vrbm')) return 'VRBM';
  if (action.includes('auto')) return 'AUTO';
  if (action.includes('aux')) return 'AUX';
  if (action === 'AUX') return 'AUX';
  if (action === 'VRBM') return 'VRBM';
  if (action === 'AUTO') return 'AUTO';
  return '';
}
function visiblePayload(item = {}) {
  return toFeedText(item.reply ?? item.block ?? item.packet ?? item.payload ?? item.raw ?? '');
}

function renderLineInCard(item, index) {
  const bodyText = visiblePayload(item);

  return renderAuxCard({
    className: 'line-in-card AuxCard--line-in',
    status: item.status,
    title: lineInTitle(item),
    tag: visibleAuxAction(item) || 'IN',
    description: lineInDescription(item),
    body: bodyText,
    controls: [
      button('FEED', () => {
        feedLineInItem(index).then(result => {
          pushTrace({
            file: 'auxrender.js',
            fn: 'feedLineInItem',
            step: result.ok ? 'fed line in item' : 'feed failed',
            note: result.msg || item.title || ''
          });

          renderAll();
        });
      }, item.status === 'waiting' || !bodyText),

      button('COPY', () => copyText(bodyText), !bodyText),

      button('CLEAR', () => {
        lineIn.items.splice(index, 1);
        renderAll();
      })
    ]
  });
}

function renderLineOut() {
  if (!els.lineOut) return;

  els.lineOut.innerHTML = '';

  if (!lineOut.items.length) {
    els.lineOut.appendChild(emptyCard('LINE OUT', 'No items yet.'));
    return;
  }

  lineOut.items.forEach((item, index) => {
    els.lineOut.appendChild(renderLineOutCard(item, index));
  });
}

function renderLineOutCard(item, index) {
  const bodyText = lineOutPreview(item);
  const needsDetails = isCodePending(item);

  return renderAuxCard({
    className: 'line-out-card AuxCard--line-out',
    status: needsDetails ? 'details-needed' : item.status,
    title: lineOutTitle(item),
    tag: needsDetails ? 'DETAILS' : visibleAuxAction(item) || 'OUT',
    description: lineOutDescription(item),
    body: bodyText,
    details: needsDetails ? renderCodeDetails(item) : null,
    controls: [
      button('SEND', () => {
        sendLineOutItem(item).then(result => {
          pushTrace({
            file: 'auxrender.js',
            fn: 'sendLineOutItem',
            step: result.result?.ok ? 'sent line out item' : 'send failed',
            note: result.result?.msg || item.title || ''
          });

          renderAll();
        });
      }, !canSendLineOut(item)),

      button('COPY', () => copyText(bodyText), !bodyText),

      button('CLEAR', () => {
        discardLineOutItem(index);
        renderAll();
      })
    ]
  });
}

function renderAuxCard({
  className = '',
  status = '',
  title = 'AUX ITEM',
  tag = '',
  description = '',
  body = '',
  details = null,
  controls = []
} = {}) {
  const card = cardBase(className, status);

  const head = document.createElement('div');
  head.className = 'AuxCardHead';

  const titleEl = document.createElement('div');
  titleEl.className = 'AuxCardTitle';
  titleEl.textContent = String(title || 'AUX ITEM').trim();
  head.appendChild(titleEl);

  if (tag) {
    const tagEl = document.createElement('div');
    tagEl.className = 'AuxCardTag';
    tagEl.textContent = String(tag).trim().toUpperCase();
    head.appendChild(tagEl);
  }

  card.appendChild(head);

  if (description) {
    const meta = document.createElement('div');
    meta.className = 'AuxCardDescription AuxCardMeta';
    meta.textContent = String(description).trim();
    card.appendChild(meta);
  }

  const bodyEl = document.createElement('pre');
  bodyEl.className = 'AuxCardBody';
  bodyEl.textContent = String(body || '');
  card.appendChild(bodyEl);

  if (details) card.appendChild(details);

  if (controls.length) {
    const controlsEl = document.createElement('div');
    controlsEl.className = 'AuxCardControls';
    controls.forEach(control => controlsEl.appendChild(control));
    card.appendChild(controlsEl);
  }

  return card;
}

function lineInTitle(item = {}) {
  return String(item.title || 'LINE IN').trim();
}

function lineOutTitle(item = {}) {
  return String(item.title || 'LINE OUT').trim();
}

function lineInDescription(item = {}) {
  return ['INBOUND', statusLabel(item.status), visibleAuxAction(item)].filter(Boolean).join(' · ');
}

function lineOutDescription(item = {}) {
  return ['OUTBOUND', isCodePending(item) ? 'DETAILS' : statusLabel(item.status), visibleAuxAction(item)].filter(Boolean).join(' · ');
}

function renderCodeDetails(item) {
  const wrap = document.createElement('div');
  wrap.className = 'AuxDetailsBox';

  const action = document.createElement('select');
  action.className = 'AuxInput';
  action.dataset.field = 'Action';

  [
    ['', 'Choose action'],
    ['newfile', 'newfile'],
    ['rewritefile', 'rewritefile']
  ].forEach(([value, label]) => {
    const opt = document.createElement('option');
    opt.value = value;
    opt.textContent = label;
    action.appendChild(opt);
  });

  action.value = item.Action || '';

  const filePath = document.createElement('input');
  filePath.className = 'AuxInput';
  filePath.dataset.field = 'FilePath';
  filePath.placeholder = 'FilePath';
  filePath.value = item.FilePath || '';

  const apply = button('OK', () => {
    completeCodeDetails(item, action.value, filePath.value);

    pushTrace({
      file: 'auxrender.js',
      fn: 'completeCodeDetails',
      step: isCodePending(item) ? 'details incomplete' : 'code compiled to json',
      note: item.title || ''
    });

    renderAll();
  });

  wrap.appendChild(action);
  wrap.appendChild(filePath);
  wrap.appendChild(apply);

  return wrap;
}

function isCodePending(item = {}) {
  return item.type === 'code' || item.needsDetails === true || String(item.status || '').toLowerCase() === 'details-needed';
}

function canSendLineOut(item) {
  if (!item || isCodePending(item)) return false;
  if (String(item.status || '').toLowerCase() === 'sending') return false;
  return Boolean(item.packet || item.block || item.payload);
}

function lineOutPreview(item) {
  return toFeedText(item.block ?? item.packet ?? item.payload ?? item.raw ?? '');
}

function buildLineOutCopy(item) {
  return item.packet ?? item.block ?? item.payload ?? item.raw ?? '';
}
function bindTraceTools() {
  if (!els.copyTrace || els.copyTrace.dataset.auxTraceCopyBound === 'true') return;
  els.copyTrace.dataset.auxTraceCopyBound = 'true';
  els.copyTrace.addEventListener('click', event => {
    event.preventDefault();
    const text = traceRows.map(row => {
      return `${row.at} · ${row.file}${row.fn ? ` · ${row.fn}` : ''}\n${row.step}${row.note ? `\n${row.note}` : ''}`;
    }).join('\n\n');
    copyText(text || 'No trace events yet.');
  });
}

function bindManualFileInquiry() {
  if (els.manualAux) {
    els.manualAux.addEventListener('click', () => {
      const target = manualTargetValue();

      if (!target) {
        pushTrace({
          file: 'auxrender.js',
          fn: 'manualFileInquiry',
          step: 'missing target',
          note: 'Enter a file path or inquiry target'
        });
        return;
      }

      import('./auxio.js').then(io => {
        io.addFileInquiryToLineIn(target, { source: 'manual-file-inquiry' });
        renderAll();
      });
    });
  }

  if (els.manualVrbm) {
    els.manualVrbm.addEventListener('click', () => {
      const target = manualTargetValue();

      if (!target) {
        pushTrace({
          file: 'auxrender.js',
          fn: 'manualFileInquiry',
          step: 'missing target',
          note: 'Enter a file path or inquiry target'
        });
        return;
      }

      requestFileInquiry(target, { source: 'manual-file-inquiry' }).then(result => {
        pushTrace({
          file: 'auxrender.js',
          fn: 'requestFileInquiry',
          step: result.ok ? 'returned file inquiry' : 'file inquiry failed',
          note: result.msg || target
        });

        renderAll();
      });
    });
  }

  if (els.manualAuto) {
    els.manualAuto.addEventListener('click', () => {
      const target = manualTargetValue();

      if (!target) {
        pushTrace({
          file: 'auxrender.js',
          fn: 'manualFileInquiry',
          step: 'missing target',
          note: 'Enter a file path or inquiry target'
        });
        return;
      }

      autoFileInquiry(target, { source: 'manual-file-inquiry' }).then(result => {
        pushTrace({
          file: 'auxrender.js',
          fn: 'autoFileInquiry',
          step: result.ok ? 'auto fed file inquiry' : 'auto failed',
          note: result.msg || target
        });

        renderAll();
      });
    });
  }
}

function manualTargetValue() {
  const raw = String(els.manualTarget?.value || '').trim();

  return raw
    .replace(/^\[/, '')
    .replace(/\]$/, '')
    .replace(/^AUXCALL@\s*/i, '')
    .trim();
}

// ─────────────────────────────────────────────────────────────
// Settings / connection
// ─────────────────────────────────────────────────────────────

function bindSettings() {
  hydrateConfigInputs();

  if (els.saveConfig) {
    els.saveConfig.addEventListener('click', async event => {
      event.preventDefault();

      const host = String(els.hostInput?.value || '127.0.0.1').trim();
      const port = String(els.portInput?.value || '').trim();

      const saved = await saveConfigFromRender(host, port);

      pushTrace({
        file: 'auxrender.js',
        fn: 'saveConfig',
        step: 'connection config saved',
        note: `${saved.host}${saved.port ? `:${saved.port}` : ''}`
      });

      const health = await getHealth();

      pushTrace({
        file: 'auxrender.js',
        fn: 'getHealth',
        step: health.ok ? 'Verbatim connected' : 'Verbatim offline',
        note: health.endpoint
      });

      renderAll();
    });
  }

  if (els.checkConnection) {
    els.checkConnection.addEventListener('click', async event => {
      event.preventDefault();

      const health = await getHealth();

      pushTrace({
        file: 'auxrender.js',
        fn: 'getHealth',
        step: health.ok ? 'Verbatim connected' : 'Verbatim offline',
        note: health.endpoint
      });

      renderAll();
    });
  }
}

function hydrateConfigInputs() {
  const config = renderOptions.getConfig ? renderOptions.getConfig() : null;

  if (config?.host && els.hostInput) {
    els.hostInput.value = config.host;
  }

  if (typeof config?.port !== 'undefined' && els.portInput) {
    els.portInput.value = config.port;
  }
}

async function saveConfigFromRender(host, port) {
  if (renderOptions.saveConfig) {
    return renderOptions.saveConfig(host, port);
  }

  await chrome.storage.local.set({
    'verbatim.host': host,
    'verbatim.port': port
  });

  return { host, port };
}

// ─────────────────────────────────────────────────────────────
// Hardware buttons
// ─────────────────────────────────────────────────────────────

function bindHardwareButtons() {
  document.addEventListener('click', event => {
    const target = event.target.closest('[data-action]');
    if (!target) return;

    const action = String(target.dataset.action || '').trim().toLowerCase();

    if (!['play', 'stop', 'next'].includes(action)) return;

    event.preventDefault();

    runHardwareButton(action).then(result => {
      pushTrace({
        file: 'auxrender.js',
        fn: 'runHardwareButton',
        step: `${action} button`,
        note: result.msg || ''
      });

      renderAll();
    });
  });
}

// ─────────────────────────────────────────────────────────────
// Monitor/menu
// ─────────────────────────────────────────────────────────────

function bindMonitorMenu() {
  const getMenu = () => document.getElementById('monitor-ctx-menu')
    || document.getElementById('monitor-menu')
    || document.querySelector('[data-monitor-menu]');

  const closeMenu = () => {
    const menu = getMenu();
    if (!menu) return;
    menu.classList.remove('is-open');
    menu.classList.add('hidden');
    menu.hidden = true;
  };

  const openMenu = () => {
    const menu = getMenu();
    if (!menu) return;
    menu.classList.remove('hidden');
    menu.classList.add('is-open');
    menu.hidden = false;
  };

  const toggleMenu = () => {
    const menu = getMenu();
    if (!menu) return;
    const shouldOpen = menu.hidden || menu.classList.contains('hidden');
    if (shouldOpen) openMenu();
    else closeMenu();
  };

  document.addEventListener('click', event => {
    const monitor = event.target.closest('#aux-monitor-trigger');
    const menuOption = event.target.closest('#monitor-ctx-menu .MenuOption-Eo, #monitor-menu .MenuOption-Eo, [data-monitor-menu] .MenuOption-Eo');

    if (monitor) {
      event.preventDefault();
      toggleMenu();
      return;
    }

    if (menuOption) {
      const action = String(menuOption.dataset.action || '').trim().toLowerCase();

      if (action === 'local-ui') {
        chrome.tabs.create({ url: endpoint('/') }).catch(() => {});
      }

      if (action === 'contract') {
        loadLocalRecordingContractToLineIn().then(local => {
          if (local.ok) {
            pushTrace({
              file: 'auxrender.js',
              fn: 'loadLocalRecordingContractToLineIn',
              step: 'loaded packaged recording contract',
              note: local.item?.FilePath || 'VerbatimRecordingContract.txt'
            });

            renderAll();
            return;
          }

          requestFileInquiry('VerbatimRecordingContract.txt', { source: 'monitor-menu' }).then(result => {
            pushTrace({
              file: 'auxrender.js',
              fn: 'requestFileInquiry',
              step: result.ok ? 'fetched recording contract' : 'contract fetch failed',
              note: result.msg || 'VerbatimRecordingContract.txt'
            });

            renderAll();
          });
        });
      }

      setTimeout(closeMenu, 0);
    }
  });

  document.addEventListener('keydown', event => {
    if (event.key === 'Escape') closeMenu();
  });
}

async function loadLocalRecordingContractToLineIn() {
  const candidates = [
    'VerbatimRecordingContract.txt',
    'docs/VerbatimRecordingContract.txt',
    'assets/VerbatimRecordingContract.txt'
  ];

  let text = '';
  let filePath = '';

  for (const candidate of candidates) {
    try {
      const res = await fetch(chrome.runtime.getURL(candidate));
      if (!res.ok) continue;

      text = await res.text();
      filePath = candidate;
      break;
    } catch {}
  }

  if (!text.trim()) {
    return {
      ok: false,
      msg: 'Local VerbatimRecordingContract.txt not found in AUX package'
    };
  }

  const row = {
    id: `li-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`,
    stream: 'INQUIRY',
    action: 'recording-contract',
    routeLabel: 'AUX',
    Task: 'Recording Contract',
    FilePath: filePath,
    payload: text,
    target: filePath,
    reply: {
      ok: true,
      channel: 'inquiry',
      request: 'recording-contract',
      files: [
        {
          FilePath: filePath,
          ok: true,
          type: 'file',
          content: text
        }
      ]
    },
    status: 'ready',
    source: 'aux-local-contract',
    receivedAt: Date.now()
  };

  lineIn.items.push(row);

  return {
    ok: true,
    item: row
  };
}

function renderTrace() {
  if (!els.trace) return;

  els.trace.innerHTML = '';

  if (!traceRows.length) {
    els.trace.appendChild(emptyCard('TRACE', 'No trace events yet.'));
    return;
  }

  traceRows.forEach(row => {
    const card = document.createElement('div');
    card.className = 'TraceCard';

    const top = document.createElement('div');
    top.className = 'TraceTop';
    top.textContent = `${row.at} · ${row.file}${row.fn ? ` · ${row.fn}` : ''}`;

    const step = document.createElement('div');
    step.className = 'TraceStep';
    step.textContent = row.step;

    const note = document.createElement('div');
    note.className = 'TraceNote';
    note.textContent = row.note;

    card.appendChild(top);
    card.appendChild(step);
    if (row.note) card.appendChild(note);

    els.trace.appendChild(card);
  });
}

// ─────────────────────────────────────────────────────────────
// Events
// ─────────────────────────────────────────────────────────────

function bindRenderEvents() {
  window.addEventListener('aux:io-changed', () => renderAll());
  window.addEventListener('aux:filetree-updated', event => {
    pushTrace({
      file: 'auxrender.js',
      fn: 'filetree',
      step: 'filetree updated',
      note: `${event.detail?.filesCount || 0} files`
    });

    renderAll();
  });

  document.addEventListener('keydown', event => {
    if (event.key !== 'Escape') return;

    const menu = document.getElementById('monitor-menu') || document.querySelector('[data-monitor-menu]');
    if (!menu) return;

    menu.classList.remove('is-open');
    menu.hidden = true;
  });
}

// ─────────────────────────────────────────────────────────────
// Shared DOM helpers
// ─────────────────────────────────────────────────────────────

function cardBase(className, status = '') {
  const card = document.createElement('article');

  card.className = `AuxCard ${className}`;
  card.dataset.status = String(status || 'ready').toLowerCase();

  return card;
}

function emptyCard(title, body) {
  const card = document.createElement('article');
  card.className = 'AuxCard AuxCardEmpty';

  const text = document.createElement('div');
  text.className = 'AuxCardEmptyText';
  text.textContent = body;

  card.appendChild(text);

  return card;
}

function button(label, onClick, disabled = false) {
  const btn = document.createElement('button');

  btn.type = 'button';
  btn.className = 'AuxButton';
  btn.textContent = label;
  btn.disabled = Boolean(disabled);

  btn.addEventListener('click', event => {
    event.preventDefault();
    event.stopPropagation();

    if (!btn.disabled) onClick(event);
  });

  return btn;
}

function statusLabel(status) {
  const clean = String(status || 'ready').trim().toUpperCase();

  if (clean === 'AUTO-READY') return 'AUTO';
  if (clean === 'DETAILS-NEEDED') return 'DETAILS';

  return clean;
}

async function copyText(value) {
  const text = String(value || '');

  try {
    await navigator.clipboard.writeText(text);

    pushTrace({
      file: 'auxrender.js',
      fn: 'copyText',
      step: 'copied',
      note: `${text.length} chars`
    });

    return true;
  } catch {
    pushTrace({
      file: 'auxrender.js',
      fn: 'copyText',
      step: 'copy failed',
      note: 'Clipboard unavailable'
    });

    return false;
  }
}

function setText(ids = [], value = '') {
  ids.forEach(id => {
    const el = byId(id);
    if (el) el.textContent = value;
  });
}

function setClassState(ids = [], className, enabled) {
  ids.forEach(id => {
    const el = byId(id);
    if (el) el.classList.toggle(className, Boolean(enabled));
  });
}