// renderProcTable — 3-секционная таблица во время обработки
// (готово / текущий / ожидают / пропущены сверх лимита).
import { fmtSec } from './fmt_sec.js';
import { estForFile, DEFAULT_EST_MB_SEC } from './est_for_file.js';
import { procRow } from './proc_row.js';
export function renderProcTable(state, els, cfg) {
const procState = state.proc.procState;
const groups = { done: [], current: [], pending: [], over: [] };
for (let i = 0; i < state.files.length; i++) {
if (state.overNames.has(state.files[i].name)) { groups.over.push(i); continue; }
const st = procState[i] ? procState[i].st : 'pending';
if (st === 'done' || st === 'skipped') groups.done.push(i);
else if (st === 'current') groups.current.push(i);
else groups.pending.push(i);
}
// Оценка скорости из текущего файла (сек/символ) — для «ожидающих»
let rate = null;
for (const i of groups.current) {
const p = procState[i];
const cur = (performance.now() - p.t0) / 1000;
const total = cur + (p.eta != null ? p.eta : 0);
if (p.chars > 0 && total > 0) rate = total / p.chars;
}
const rows = [];
if (groups.done.length) {
rows.push('
| ✓ Обработанные (' + groups.done.length + ') |
');
for (const i of groups.done) {
const p = procState[i];
const txt = p.st === 'skipped'
? 'не извлечён'
: '✓ ' + (p.elapsed ? p.elapsed.toFixed(1) : '0.0') + 'с';
rows.push(procRow(state, i, txt));
}
}
if (groups.over.length) {
rows.push('| ⛔ Пропущены (сверх лимита) (' + groups.over.length + ') |
');
for (const i of groups.over) {
rows.push(procRow(state, i, 'пропущен (лимит)'));
}
}
if (groups.current.length) {
rows.push('| ▶ Текущий файл |
');
for (const i of groups.current) {
const p = procState[i];
const cur = ((performance.now() - p.t0) / 1000).toFixed(1);
const eta = (p.eta != null) ? ' / ~' + fmtSec(p.eta) : '';
rows.push(procRow(state, i, '⏳ ' + cur + 'с' + eta + ''));
}
}
if (groups.pending.length) {
rows.push('| ○ Ожидают обработки (' + groups.pending.length + ') |
');
for (const i of groups.pending) {
const p = procState[i] || {};
// Оценка: LLM (chars x rate) если известна; иначе грубая по размеру/скорости извлечения
if (rate && !p.est && p.chars > 0) p.est = p.chars * rate;
if (!p.est) {
const szMB = (state.files[i] ? state.files[i].size : 0) / 1048576;
const k = (state.proc && state.proc.procExtractRate) || cfg.estMbSec || DEFAULT_EST_MB_SEC; // сек/МБ
p.est = Math.max(1, Math.round(szMB * k));
}
let txt;
if (p.st === 'analyzed') txt = 'анализ ✓';
else if (p.st === 'current') txt = '⏳';
else if (p.est != null) txt = '~' + fmtSec(p.est) + '';
else txt = '—';
rows.push(procRow(state, i, txt));
}
}
els.tableBody.innerHTML = rows.join('');
const cntDone = groups.done.length;
els.countEl.textContent = 'Готово ' + cntDone + ' / ' + state.files.length + ' файлов';
}