/**
 * sort-table.js — Универсальный модуль сортировки таблиц.
 *
 * Автоматически находит все <table> на странице и делает
 * заголовки <th> кликабельными для сортировки по столбцам.
 *
 * Использование:
 *   1. Подключить <script src="/service/static/js/sort-table.js"></script>
 *   2. Таблицы автоматически получают сортировку при загрузке
 *   3. Для AJAX-таблиц: вызвать sortTables() после заполнения <tbody>
 */
(function(){
  'use strict';

  var SORT_CSS = [
    '.sort-th { cursor:pointer; user-select:none; position:relative; padding-right:18px !important; }',
    '.sort-th:hover { color:var(--accent); }',
    '.sort-th::after { content:""; position:absolute; right:6px; top:50%; transform:translateY(-50%); width:0; height:0; border-left:4px solid transparent; border-right:4px solid transparent; border-top:5px solid var(--text-muted); opacity:0.4; }',
    '.sort-th.sort-asc::after { border-top:none; border-bottom:5px solid var(--accent); opacity:1; }',
    '.sort-th.sort-desc::after { border-top:5px solid var(--accent); opacity:1; }'
  ].join('\n');

  /* Встраиваем стили один раз */
  function injectStyles(){
    if(document.getElementById('sort-table-styles')) return;
    var style = document.createElement('style');
    style.id = 'sort-table-styles';
    style.textContent = SORT_CSS;
    document.head.appendChild(style);
  }

  /* Определение типа значения ячейки */
  function getCellValue(tr, idx){
    var td = tr.children[idx];
    if(!td) return '';
    var text = (td.textContent || '').trim();
    return text;
  }

  /* Парсинг числа из текста */
  function parseNumber(text){
    if(!text || text === '—' || text === '-') return NaN;
    /* Убираем пробелы,.currency-символы, % */
    var cleaned = text.replace(/[^\d,\.\-]/g, '').replace(',', '.');
    var num = parseFloat(cleaned);
    return isNaN(num) ? NaN : num;
  }

  /* Парсинг даты из текста (DD.MM.YYYY или YYYY-MM-DD) */
  function parseDate(text){
    if(!text) return NaN;
    /* DD.MM.YYYY HH:MM */
    var m = text.match(/(\d{2})\.(\d{2})\.(\d{4})/);
    if(m) return new Date(m[3], m[2]-1, m[1]).getTime();
    /* YYYY-MM-DD */
    m = text.match(/(\d{4})-(\d{2})-(\d{2})/);
    if(m) return new Date(m[1], m[2]-1, m[3]).getTime();
    return NaN;
  }

  /* Сравнение двух значений */
  function compare(a, b, type){
    if(type === 'number'){
      var na = parseNumber(a), nb = parseNumber(b);
      if(isNaN(na) && isNaN(nb)) return 0;
      if(isNaN(na)) return 1;
      if(isNaN(nb)) return -1;
      return na - nb;
    }
    if(type === 'date'){
      var da = parseDate(a), db = parseDate(b);
      if(isNaN(da) && isNaN(db)) return 0;
      if(isNaN(da)) return 1;
      if(isNaN(db)) return -1;
      return da - db;
    }
    /* Текст */
    return a.localeCompare(b, 'ru');
  }

  /* Определение типа столбца по первым строкам */
  function detectColumnType(tbody, idx){
    var rows = tbody.children;
    var samples = [];
    var limit = Math.min(rows.length, 10);
    for(var i = 0; i < limit; i++){
      samples.push(getCellValue(rows[i], idx));
    }
    var numCount = 0, dateCount = 0;
    for(var j = 0; j < samples.length; j++){
      if(parseNumber(samples[j]) !== NaN && samples[j] !== '') numCount++;
      if(parseDate(samples[j]) !== NaN && samples[j] !== '') dateCount++;
    }
    if(samples.length > 0 && numCount / samples.length > 0.6) return 'number';
    if(samples.length > 0 && dateCount / samples.length > 0.6) return 'date';
    return 'text';
  }

  /* Привязка сортировки к таблице */
  function attachSort(table){
    if(table.dataset.sortAttached) return;
    table.dataset.sortAttached = '1';

    var thead = table.querySelector('thead');
    var tbody = table.querySelector('tbody');
    if(!thead || !tbody) return;

    var headers = thead.querySelectorAll('th');
    headers.forEach(function(th, idx){
      /* Пропускаем колонку действий */
      if(th.classList.contains('actions')) return;

      th.classList.add('sort-th');
      th.dataset.sortIdx = idx;
      th.dataset.sortDir = 'none';

      th.addEventListener('click', function(){
        var colIdx = parseInt(this.dataset.sortIdx);
        var currentDir = this.dataset.sortDir;
        var newDir = currentDir === 'asc' ? 'desc' : 'asc';

        /* Сброс других столбцов */
        headers.forEach(function(h){ h.classList.remove('sort-asc', 'sort-desc'); h.dataset.sortDir = 'none'; });
        this.classList.remove('sort-asc', 'sort-desc');
        this.classList.add('sort-' + newDir);
        this.dataset.sortDir = newDir;

        /* Определение типа данных */
        var colType = detectColumnType(tbody, colIdx);

        /* Сбор строк с значениями */
        var rowsArray = Array.prototype.slice.call(tbody.querySelectorAll('tr'));
        rowsArray.sort(function(rowA, rowB){
          var valA = getCellValue(rowA, colIdx);
          var valB = getCellValue(rowB, colIdx);
          var result = compare(valA, valB, colType);
          return newDir === 'asc' ? result : -result;
        });

        /* Перестановка строк */
        rowsArray.forEach(function(row){ tbody.appendChild(row); });
      });
    });
  }

  /* Публичная функция: инициализация/переинициализация всех таблиц */
  function sortTables(){
    injectStyles();
    var tables = document.querySelectorAll('table');
    for(var i = 0; i < tables.length; i++){
      attachSort(tables[i]);
    }
  }

  /* Автозапуск после загрузки DOM */
  if(document.readyState === 'loading'){
    document.addEventListener('DOMContentLoaded', sortTables);
  } else {
    sortTables();
  }

  /* Экспорт в глобальную область */
  window.sortTables = sortTables;
})();
