// ══════════════════════════════════════════════════════════════
// nterm — Gutter bar rendering
// ══════════════════════════════════════════════════════════════
// Renders block indicator marks alongside the terminal viewport.
// Uses requestAnimationFrame to coalesce rapid updates.
// Depends on: state, diag, perf, escapeHtml

const _gutterRafPending = {};

function scheduleGutterRender(tabId) {
  if (_gutterRafPending[tabId]) return;
  _gutterRafPending[tabId] = true;
  requestAnimationFrame(() => {
    _gutterRafPending[tabId] = false;
    renderGutter(tabId);
  });
}

function renderGutter(tabId) {
  perf.start('render_gutter');

  const gutter = document.getElementById('gutter-' + tabId);
  if (!gutter) { perf.end('render_gutter'); return; }

  const session = state.sessions[tabId];
  if (!session || !session.term) { gutter.innerHTML = ''; perf.end('render_gutter'); return; }

  const bext = diag.snifferBlocks[tabId];
  if (!bext || bext.blocks.length === 0) { gutter.innerHTML = ''; perf.end('render_gutter'); return; }

  const term = session.term;
  const buf = term.buffer.active;
  const viewportRows = term.rows;
  const gutterHeight = gutter.clientHeight;

  if (gutterHeight <= 0 || viewportRows <= 0) { perf.end('render_gutter'); return; }

  // ── Dynamic offset: correct drift between sniffer lines and xterm rows ──
  const acc = diag.snifferAccumulators[tabId];
  const snifferTotal = acc ? acc.lineCount : 0;
  const xtermCursorRow = buf.baseY + buf.cursorY;
  const offset = snifferTotal > 0 ? (xtermCursorRow - (snifferTotal - 1)) : 0;

  // ── Viewport position ──
  let viewportTop = buf.baseY;
  if (typeof buf.viewportY === 'number') {
    viewportTop = buf.viewportY;
  } else {
    const container = document.querySelector(`#pane-${tabId} .xterm-container`);
    const vpEl = container ? container.querySelector('.xterm-viewport') : null;
    if (vpEl && vpEl.scrollHeight > vpEl.clientHeight) {
      const rowPixelHeight = vpEl.scrollHeight / buf.length;
      if (rowPixelHeight > 0) {
        viewportTop = Math.round(vpEl.scrollTop / rowPixelHeight);
      }
    }
  }
  const viewportBottom = viewportTop + viewportRows - 1;

  const rowHeight = gutterHeight / viewportRows;
  let html = '';

  for (const block of bext.blocks) {
    const bStart = (block.startLine - 1) + offset;
    const bEnd = (block.endLine - 1) + offset - 2;

    if (bEnd < viewportTop || bStart > viewportBottom) continue;

    const startInView = Math.max(bStart - viewportTop, 0);
    const endInView = Math.min(bEnd - viewportTop, viewportRows - 1);

    const top = startInView * rowHeight;
    const height = Math.max((endInView - startInView + 1) * rowHeight, 4);
    const cls = block.interrupted ? 'gutter-interrupted' : 'gutter-normal';

    html += `<div class="gutter-mark ${cls}" style="top:${top.toFixed(1)}px;height:${height.toFixed(1)}px" data-block-id="${block.blockId}" title="${escapeHtml(block.command)} · ${block.lineCount} lines · ${block.durationMs}ms"></div>`;
  }
  gutter.innerHTML = html;

  perf.end('render_gutter');
}
