/**
 * Fichier  : assets/js/table-sort.js
 * Auteur   : KREMER Régis
 * Version  : 1.0.0
 * Date     : 2026-03-01
 * Description : Module de tri générique pour tous les tableaux de StockMaster Pro
 *
 * Usage :
 *   TableSort.init('myTableId', data, renderFn, {
 *     defaultKey: 'name',
 *     defaultDir: 'asc',
 *     getters: { stock: row => totalStock(row) }  // optionnel : valeurs calculées
 *   });
 *
 *   TableSort.sort('myTableId', 'name', 'asc') → retourne data triée
 *
 * Dans le <thead>, ajouter data-sort="clé" sur chaque <th> triable.
 * La colonne active reçoit les classes : th-sort-asc / th-sort-desc
 */

const TableSort = (() => {

    // ── État par tableau ──────────────────────────────────────────
    const _state = {};   // { tableId: { key, dir, data, renderFn, getters } }

    // ── CSS injecté une seule fois ───────────────────────────────
    let _cssInjected = false;
    function _injectCss(){
        if(_cssInjected) return;
        _cssInjected = true;
        const s = document.createElement('style');
        s.id = 'table-sort-css';
        s.textContent = `
/* ── En-têtes triables ──────────────────────────────── */
th[data-sort]{
    cursor:pointer;
    user-select:none;
    white-space:nowrap;
    position:relative;
    padding-right:22px !important;
    transition:background .12s, color .12s;
}
th[data-sort]:hover{
    background:var(--bg-elevated,#f1f5f9);
    color:var(--blue,#3b82f6);
}
/* Flèche neutre (indicateur disponible) */
th[data-sort]::after{
    content:'';
    position:absolute;
    right:6px;
    top:50%;
    transform:translateY(-50%);
    width:14px;
    height:14px;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23cbd5e1' stroke-width='2.5'%3E%3Cpath d='M8 9l4-4 4 4'/%3E%3Cpath d='M16 15l-4 4-4-4'/%3E%3C/svg%3E");
    background-repeat:no-repeat;
    background-size:14px;
    background-position:center;
    opacity:.6;
    transition:opacity .15s;
}
th[data-sort]:hover::after{ opacity:1; }

/* Flèche montante (ASC actif) */
th.th-sort-asc{
    color:var(--blue,#3b82f6) !important;
    background:var(--blue-pale,#eff6ff) !important;
}
th.th-sort-asc::after{
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233b82f6' stroke-width='2.5'%3E%3Cpath d='M12 19V5m0 0l-7 7m7-7l7 7'/%3E%3C/svg%3E");
    opacity:1;
}

/* Flèche descendante (DESC actif) */
th.th-sort-desc{
    color:var(--blue,#3b82f6) !important;
    background:var(--blue-pale,#eff6ff) !important;
}
th.th-sort-desc::after{
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%233b82f6' stroke-width='2.5'%3E%3Cpath d='M12 5v14m0 0l7-7m-7 7l-7-7'/%3E%3C/svg%3E");
    opacity:1;
}
/* Ligne de tableau : curseur pointer si triable activé */
table.sortable-active tbody tr{ cursor:pointer; }
        `;
        document.head.appendChild(s);
    }

    // ── Valeur de tri extraite depuis un objet ───────────────────
    function _val(row, key, getters){
        // getter custom (valeur calculée)
        if(getters && getters[key]) return getters[key](row);
        const v = row[key];
        if(v === null || v === undefined) return '';
        if(typeof v === 'number') return v;
        return String(v).toLowerCase().trim();
    }

    // ── Comparateur universel ────────────────────────────────────
    function _compare(a, b, key, dir, getters){
        const va = _val(a, key, getters);
        const vb = _val(b, key, getters);
        let cmp = 0;
        if(typeof va === 'number' && typeof vb === 'number'){
            cmp = va - vb;
        } else {
            cmp = String(va).localeCompare(String(vb), 'fr', { numeric:true, sensitivity:'base' });
        }
        return dir === 'asc' ? cmp : -cmp;
    }

    // ── Trier un tableau de données ──────────────────────────────
    function sort(data, key, dir, getters){
        if(!key) return [...data];
        return [...data].sort((a,b) => _compare(a, b, key, dir, getters));
    }

    // ── Mettre à jour les classes sur les th ─────────────────────
    function _updateHeaders(table, activeKey, activeDir){
        table.querySelectorAll('th[data-sort]').forEach(th => {
            th.classList.remove('th-sort-asc','th-sort-desc');
            if(th.dataset.sort === activeKey){
                th.classList.add(activeDir === 'asc' ? 'th-sort-asc' : 'th-sort-desc');
            }
        });
    }

    // ── Initialiser le tri sur un tableau ────────────────────────
    // tableId    : id du <table>
    // getData    : fn() → retourne le tableau de données courant
    // renderFn   : fn(sortedData) → re-render le tbody
    // options    : { defaultKey, defaultDir, getters }
    function init(tableId, getData, renderFn, options = {}){
        _injectCss();
        const table = document.getElementById(tableId);
        if(!table) return;

        table.classList.add('sortable-active');

        const state = {
            key  : options.defaultKey  || '',
            dir  : options.defaultDir  || 'asc',
            getData,
            renderFn,
            getters: options.getters || {}
        };
        _state[tableId] = state;

        // Appliquer tri initial si defaultKey fourni
        if(state.key){
            _updateHeaders(table, state.key, state.dir);
        }

        // Brancher les clics sur les th[data-sort]
        table.querySelectorAll('th[data-sort]').forEach(th => {
            th.addEventListener('click', () => {
                const clickedKey = th.dataset.sort;
                if(state.key === clickedKey){
                    // Même colonne → inverser direction
                    state.dir = (state.dir === 'asc') ? 'desc' : 'asc';
                } else {
                    state.key = clickedKey;
                    state.dir = 'asc';
                }
                _updateHeaders(table, state.key, state.dir);
                const sorted = sort(state.getData(), state.key, state.dir, state.getters);
                state.renderFn(sorted);
            });
        });
    }

    // ── Re-déclencher le tri actif (après rechargement des données)
    function refresh(tableId){
        const state = _state[tableId];
        if(!state || !state.key) return;
        const table = document.getElementById(tableId);
        if(table) _updateHeaders(table, state.key, state.dir);
        const sorted = sort(state.getData(), state.key, state.dir, state.getters);
        state.renderFn(sorted);
    }

    // ── Trier des données sans toucher au DOM ─────────────────────
    function sortData(tableId, data){
        const state = _state[tableId];
        if(!state || !state.key) return data;
        return sort(data, state.key, state.dir, state.getters);
    }

    // ── Réinitialiser ────────────────────────────────────────────
    function destroy(tableId){
        delete _state[tableId];
        const table = document.getElementById(tableId);
        if(table) table.querySelectorAll('th[data-sort]').forEach(th => {
            th.classList.remove('th-sort-asc','th-sort-desc');
        });
    }

    return { init, refresh, sortData, sort, destroy };

})();
