// =============================================================
// UI.JS — общие клиентские хелперы dashboard
// Сортировка таблиц + относительное время. Без зависимостей.
// =============================================================

// ---- Сортировка таблиц --------------------------------------
// Вешается на все <table class="sortable">: клик по th сортирует
// строки tbody по этой колонке (повторный клик — обратный порядок).
// Значение ячейки берётся из data-sort (число), иначе — текст.
// th с классом nosort не сортируется. tfoot не трогаем.

function uiCellValue(row, idx) {
    const td = row.cells[idx];
    if (!td) return null;
    if (td.dataset.sort !== undefined) {
        const n = parseFloat(td.dataset.sort);
        return isNaN(n) ? td.dataset.sort : n;
    }
    return td.textContent.trim().toLowerCase();
}

function uiCompare(a, b) {
    // Числа между собой — численно; строки — localeCompare;
    // пустые/нечисловые значения уходят в конец при любом направлении.
    const aEmpty = a === null || a === '' || a === '—';
    const bEmpty = b === null || b === '' || b === '—';
    if (aEmpty && bEmpty) return 0;
    if (aEmpty) return 1;
    if (bEmpty) return -1;
    if (typeof a === 'number' && typeof b === 'number') return a - b;
    return String(a).localeCompare(String(b), 'ru');
}

function uiSortTable(table, th, idx) {
    const desc = !th.classList.contains('sort-desc');
    table.querySelectorAll('thead th').forEach(h => h.classList.remove('sort-asc', 'sort-desc'));
    th.classList.add(desc ? 'sort-desc' : 'sort-asc');

    const tbody = table.tBodies[0];
    if (!tbody) return;
    const rows = Array.from(tbody.rows);
    rows.sort((r1, r2) => {
        const cmp = uiCompare(uiCellValue(r1, idx), uiCellValue(r2, idx));
        // Пустые значения всегда в конце — знак не инвертируем для них
        const v1 = uiCellValue(r1, idx), v2 = uiCellValue(r2, idx);
        const e1 = v1 === null || v1 === '' || v1 === '—';
        const e2 = v2 === null || v2 === '' || v2 === '—';
        if (e1 || e2) return cmp;
        return desc ? -cmp : cmp;
    });
    rows.forEach(r => tbody.appendChild(r));
}

function uiInitSortableTables() {
    document.querySelectorAll('table.sortable').forEach(table => {
        table.querySelectorAll('thead th').forEach((th, idx) => {
            if (th.classList.contains('nosort')) return;
            th.classList.add('sortable-th');
            th.addEventListener('click', () => uiSortTable(table, th, idx));
        });
    });
}

// ---- Относительное время ------------------------------------
// Элементы с data-reltime="<unix ts>" получают короткий относительный
// текст («12 мин назад»), полная дата уезжает в title (tooltip).
// Старше 7 дней — оставляем исходную дату как есть.

function uiFormatRel(diffSec) {
    if (diffSec < 0) return null;               // будущее — не трогаем
    if (diffSec < 60) return 'только что';
    if (diffSec < 3600) return Math.floor(diffSec / 60) + ' мин назад';
    if (diffSec < 86400) return Math.floor(diffSec / 3600) + ' ч назад';
    if (diffSec < 7 * 86400) return Math.floor(diffSec / 86400) + ' д назад';
    return null;                                // старое — оставляем дату
}

function uiInitRelativeTimes() {
    const now = Date.now() / 1000;
    document.querySelectorAll('[data-reltime]').forEach(el => {
        const ts = parseInt(el.dataset.reltime, 10);
        if (!ts) return;
        const rel = uiFormatRel(now - ts);
        if (rel === null) return;
        el.title = el.textContent.trim();
        el.textContent = rel;
    });
}

document.addEventListener('DOMContentLoaded', () => {
    uiInitSortableTables();
    uiInitRelativeTimes();
});
