/**
 * Projet                    : MageStock
 * Logiciel                  : MageStock
 * Rôle du fichier           : Adaptation mobile/tablette des CRUD secondaires
 * Version générale          : 2.6.116
 * Lot                       : MAGESTOCK WAREHOUSE UI CONSOLIDATION1
 * Base cumulative requise   : MageStock 2.6.115
 * Date de création          : 2026-07-20
 * Date de modification      : 2026-07-25
 * Dépendances               : DOM, composants MageStock
 * Données persistantes      : aucune directement
 * Permissions requises      : héritées des pages et API
 * Contraintes de sécurité   : aucune écriture directe, actions déléguées aux modules protégés
 * Compatibilité             : smartphone et tablette
 * Résumé des modifications  : retrait de la configuration de la page Magasins supprimée.
 *

 * Fichier  : assets/js/pages/crud-mobile.js
 * Auteur   : KREMER Régis
 * Version  : 2.6.116
 * Date     : 2026-07-25
 * Description : Adaptation mobile/tablette commune des CRUD secondaires — cartes métier,
 *               filtres en volet, actions contextuelles et formulaires en feuille tactile.
 *
 * Changelog :
 *   v2.6.86 (2026-07-20) — CRUD MOBILE CARDS10 : socle appliqué aux Kits, Réservations,
 *                          Lots, Emplacements, Magasins, Gestionnaire magasin, Alertes et Marques.
 *   v2.6.116 (2026-07-25) — Retrait de la configuration de l’ancienne page Magasins ; gestionnaire unique conservé.
 */
(function crudMobileCards(global, document) {
    'use strict';

    const PAGE_CONFIG = {
        kits: {
            root: '#kitsPage', table: '#kitsTable', insertAfter: '#kitsTable', limit: 30,
            search: '#kitSearch', filters: [],
            card: { title: 0, meta: 1, badge: 3, fields: [['Composants', 2]] }
        },
        reservations: {
            root: '#reservationsPage', table: '#reservationsTable', insertAfter: '#reservationsTable', limit: 30,
            search: '#resSearch', filters: [{ selector: '#resStatus', label: 'Statut' }],
            card: { title: 0, meta: 1, badge: 5, fields: [['Emplacement', 2], ['Quantité', 3], ['Chantier', 4]] }
        },
        lots: {
            root: '#pgLots', table: '#tblLots', insertAfter: '#tblLots', limit: 30,
            search: '#lotsSearch', filters: [
                { selector: '#lotsWarehouse', label: 'Magasin' },
                { selector: '#lotsLocation', label: 'Emplacement' }
            ],
            card: { title: 0, meta: 1, badge: 5, fields: [['Péremption', 2], ['Quantité', 3], ['Emplacement', 4]] }
        },
        alerts: {
            root: '#pgAlerts', table: '#alertTable', insertAfter: '#alertTable', limit: 30,
            search: '#alertSearch', filters: [
                { selector: '#alertWhFilter', label: 'Magasin' },
                { selector: '#alertCatFilter', label: 'Catégorie' },
                { selector: '#alertStatusFilter', label: 'Statut' }
            ],
            card: { title: 1, eyebrow: 0, meta: 2, badge: 6, fields: [['Seuil minimum', 3], ['Seuil maximum', 4], ['Quantité actuelle', 5]] }
        },
        brands: {
            root: '#pgBrands', table: '#brandTable', insertAfter: '#brandTable', limit: 30,
            search: '#brandSearch', filters: [],
            card: { title: 0, meta: 3, fields: [['Fournisseurs liés', 1], ['Produits', 2]] }
        }
    };

    const ACTION_LABELS = {
        edit: 'Modifier', del: 'Supprimer', delete: 'Supprimer', release: 'Libérer',
        history: 'Historique', block: 'Bloquer', unblock: 'Débloquer', toggle: 'Modifier le statut'
    };

    const state = {
        page: '', config: null, root: null, cards: null, table: null, tbody: null,
        observer: null, limit: 30, filterButton: null, modalPatched: false
    };

    function isTouchLayout() {
        return Math.max(global.visualViewport?.width || global.innerWidth || 0, 1) < 1200;
    }

    function cleanText(value) {
        return String(value == null ? '' : value).replace(/\s+/g, ' ').trim();
    }

    function cell(row, index) {
        return row?.cells?.[index] || null;
    }

    function textAt(row, index, fallback = '—') {
        const value = cleanText(cell(row, index)?.textContent || '');
        return value || fallback;
    }

    function statusClass(value) {
        const text = cleanText(value).toLowerCase();
        if (state.page === 'lots' && text === 'oui') return 'is-danger';
        if (/crit|activée|bloqué|inactif|annul|danger|supprim/.test(text)) return 'is-danger';
        if (/alerte|active|attente|partiel|warning/.test(text)) return 'is-warning';
        if (/ok|conforme|actif|libérée|oui|débloqué/.test(text)) return 'is-success';
        return 'is-neutral';
    }

    function actionLabel(button) {
        const visible = cleanText(button.textContent || '');
        if (visible && !/^[✕×🗑️✏️]+$/.test(visible)) return visible;
        const title = cleanText(button.getAttribute('title') || button.getAttribute('aria-label') || '');
        if (title) return title;
        return ACTION_LABELS[button.dataset.act] || 'Action';
    }

    function isDangerAction(button, label) {
        return button.classList.contains('btn-danger') || /supprim|annul|bloquer/i.test(label);
    }

    function invokeSourceButton(button) {
        if (!button || !document.contains(button)) return;
        global.setTimeout(() => button.click(), 30);
    }

    function openActions(title, buttons, trigger) {
        if (!buttons.length) return;
        const actions = buttons.map((button) => {
            const label = actionLabel(button);
            return {
                label,
                className: isDangerAction(button, label) ? 'btn btn-danger' : 'btn btn-secondary',
                onClick: () => invokeSourceButton(button)
            };
        });
        global.ActionSheet?.open({
            title: 'Actions — ' + title,
            description: 'Choisissez l’action à effectuer.',
            trigger,
            actions
        });
    }

    function makeActionButton(label, className, source, entityTitle) {
        const button = document.createElement('button');
        button.type = 'button';
        button.className = className;
        button.textContent = label;
        button.setAttribute('aria-label', label + ' — ' + entityTitle);
        button.addEventListener('click', () => invokeSourceButton(source));
        return button;
    }

    function buildCard(row, config) {
        const title = textAt(row, config.title, 'Élément');
        const article = document.createElement('article');
        article.className = 'ms-entity-card crud-mobile-card';
        article.setAttribute('aria-label', title);

        const header = document.createElement('header');
        header.className = 'ms-entity-card__header';
        const identity = document.createElement('div');
        identity.className = 'ms-entity-card__identity';

        if (Number.isInteger(config.eyebrow)) {
            const eyebrow = document.createElement('span');
            eyebrow.className = 'ms-entity-card__eyebrow';
            eyebrow.textContent = textAt(row, config.eyebrow, '');
            identity.appendChild(eyebrow);
        }

        const heading = document.createElement('h3');
        heading.className = 'ms-entity-card__title';
        heading.textContent = title;
        identity.appendChild(heading);

        if (Number.isInteger(config.meta)) {
            const meta = document.createElement('p');
            meta.className = 'ms-entity-card__meta';
            meta.textContent = textAt(row, config.meta, '');
            identity.appendChild(meta);
        }
        header.appendChild(identity);

        if (Number.isInteger(config.badge)) {
            const badgeText = textAt(row, config.badge, '');
            if (badgeText) {
                const badge = document.createElement('span');
                badge.className = 'crud-mobile-card__status ' + statusClass(badgeText);
                badge.textContent = badgeText;
                header.appendChild(badge);
            }
        }
        article.appendChild(header);

        const fields = Array.isArray(config.fields) ? config.fields : [];
        if (fields.length) {
            const list = document.createElement('dl');
            list.className = 'ms-entity-card__fields';
            fields.forEach(([label, index]) => {
                const item = document.createElement('div');
                item.className = 'ms-entity-card__field';
                const dt = document.createElement('dt');
                const dd = document.createElement('dd');
                dt.textContent = label;
                dd.textContent = textAt(row, index);
                item.append(dt, dd);
                list.appendChild(item);
            });
            article.appendChild(list);
        }

        const sourceActions = Array.from(row.querySelectorAll('button')).filter((button) => !button.disabled);
        if (sourceActions.length) {
            const footer = document.createElement('footer');
            footer.className = 'ms-entity-card__actions crud-mobile-card__actions';
            const preferred = sourceActions.find((button) => !isDangerAction(button, actionLabel(button))) || sourceActions[0];
            const preferredLabel = actionLabel(preferred);
            footer.appendChild(makeActionButton(preferredLabel, 'btn btn-primary', preferred, title));

            const remaining = sourceActions.filter((button) => button !== preferred);
            if (remaining.length) {
                const more = document.createElement('button');
                more.type = 'button';
                more.className = 'btn btn-secondary';
                more.textContent = 'Autres actions';
                more.setAttribute('aria-label', 'Autres actions — ' + title);
                more.addEventListener('click', () => openActions(title, remaining, more));
                footer.appendChild(more);
            }
            article.appendChild(footer);
        }
        return article;
    }

    function rowsFromTable() {
        if (!state.tbody) return [];
        return Array.from(state.tbody.rows || []).filter((row) => {
            if (row.cells.length <= 1 && row.cells[0]?.hasAttribute('colspan')) return false;
            return row.cells.length > 1;
        });
    }

    function renderCards(resetLimit = false) {
        if (!state.cards || !state.config || !isTouchLayout()) return;
        if (resetLimit) state.limit = state.config.limit || 30;
        const rows = rowsFromTable();
        state.cards.innerHTML = '';

        if (!rows.length) {
            const empty = document.createElement('div');
            empty.className = 'crud-mobile-empty';
            empty.innerHTML = '<strong>Aucun résultat</strong><span>Modifiez la recherche ou les filtres.</span>';
            state.cards.appendChild(empty);
            return;
        }

        const fragment = document.createDocumentFragment();
        rows.slice(0, state.limit).forEach((row) => fragment.appendChild(buildCard(row, state.config.card)));
        state.cards.appendChild(fragment);

        if (rows.length > state.limit) {
            const more = document.createElement('button');
            more.type = 'button';
            more.className = 'btn btn-secondary crud-mobile-load-more';
            more.textContent = `Afficher ${Math.min(30, rows.length - state.limit)} élément(s) supplémentaire(s)`;
            more.addEventListener('click', () => {
                state.limit += 30;
                renderCards(false);
            });
            state.cards.appendChild(more);
        }
    }

    function setupTableCards(config) {
        state.table = document.querySelector(config.table);
        state.tbody = state.table?.tBodies?.[0] || state.table?.querySelector('tbody');
        if (!state.table || !state.tbody) return;

        const tableContainer = state.table.closest('.card, .table-container') || state.table.parentElement;
        tableContainer?.classList.add('crud-mobile-source');

        const cards = document.createElement('section');
        cards.className = 'crud-mobile-cards';
        cards.id = 'crudMobileCards-' + state.page;
        cards.setAttribute('aria-label', 'Liste adaptée mobile et tablette');
        const anchor = state.table.closest('.card') || state.table.closest('.table-container') || state.table;
        anchor.insertAdjacentElement('afterend', cards);
        state.cards = cards;

        state.observer = new MutationObserver(() => renderCards(true));
        state.observer.observe(state.tbody, { childList: true, subtree: true, characterData: true });
        renderCards(true);
    }

    function setupFilterPanel(config) {
        if (!config.filters?.length || !state.root) return;
        const controls = config.filters.map((item) => ({ ...item, element: document.querySelector(item.selector) })).filter((item) => item.element);
        if (!controls.length) return;

        const toolbar = document.createElement('div');
        toolbar.className = 'crud-mobile-filter-toolbar';
        const button = document.createElement('button');
        button.type = 'button';
        button.className = 'btn btn-secondary crud-mobile-filter-button';
        button.textContent = 'Filtres';
        button.setAttribute('aria-haspopup', 'dialog');
        toolbar.appendChild(button);

        const firstBar = state.root.querySelector('.filters-bar, .report-filters, .loc-topbar');
        if (firstBar) firstBar.insertAdjacentElement('beforebegin', toolbar);
        else state.root.prepend(toolbar);
        state.filterButton = button;

        const updateCount = () => {
            const active = controls.filter(({ element }) => {
                if (element.tagName === 'SELECT') return cleanText(element.value) !== '';
                return cleanText(element.value) !== '';
            }).length;
            button.textContent = active ? `Filtres (${active})` : 'Filtres';
            button.classList.toggle('is-active', active > 0);
        };
        controls.forEach(({ element }) => element.addEventListener('change', updateCount));
        updateCount();

        button.addEventListener('click', () => {
            const content = document.createElement('div');
            content.className = 'crud-mobile-filter-form';
            const restores = [];

            controls.forEach(({ element, label }) => {
                const parent = element.parentNode;
                const next = element.nextSibling;
                restores.push(() => {
                    if (!parent) return;
                    if (next && next.parentNode === parent) parent.insertBefore(element, next);
                    else parent.appendChild(element);
                });
                const group = document.createElement('label');
                group.className = 'crud-mobile-filter-field';
                const caption = document.createElement('span');
                caption.textContent = label;
                group.append(caption, element);
                content.appendChild(group);
            });

            const opener = global.MageStockMobileUI?.device?.isPhone?.() ? global.ActionSheet : global.FilterDrawer;
            opener?.open({
                title: 'Filtres',
                description: 'Affinez la liste affichée.',
                trigger: button,
                content,
                actions: [{ label: 'Afficher les résultats', className: 'btn btn-primary' }],
                onClose: () => {
                    restores.reverse().forEach((restore) => restore());
                    updateCount();
                    renderCards(true);
                }
            });
        });
    }

    function patchLegacyModal() {
        if (state.modalPatched || !global.Modal) return;
        state.modalPatched = true;
        const originalShow = global.Modal.show.bind(global.Modal);
        const originalClose = global.Modal.close.bind(global.Modal);
        const overlay = document.getElementById('modalOverlay');

        global.Modal.show = (...args) => {
            const result = originalShow(...args);
            if (isTouchLayout() && overlay) {
                overlay.classList.add('crud-mobile-modal');
                overlay.dataset.crudPage = state.page;
            }
            return result;
        };
        global.Modal.open = (...args) => global.Modal.show(...args);
        global.Modal.close = (...args) => {
            const result = originalClose(...args);
            global.setTimeout(() => {
                overlay?.classList.remove('crud-mobile-modal');
                if (overlay) delete overlay.dataset.crudPage;
            }, 210);
            return result;
        };
    }

    function enhanceLocations() {
        const root = document.getElementById('pgLocations');
        if (!root) return;
        const forceZones = () => {
            if (!isTouchLayout()) return;
            const zonesButton = root.querySelector('[data-view="zones"]');
            if (zonesButton && !zonesButton.classList.contains('active')) zonesButton.click();
        };
        forceZones();
        global.addEventListener('magestock:devicechange', forceZones);

        const host = document.getElementById('locZonesView');
        const enhance = () => {
            host?.querySelectorAll('.loc-emplacement').forEach((card) => {
                card.classList.add('ms-entity-card', 'crud-mobile-location-card');
                card.setAttribute('role', 'group');
                const code = cleanText(card.querySelector('.loc-emp-code')?.textContent || 'Emplacement');
                const label = cleanText(card.querySelector('.loc-emp-label')?.textContent || '');
                card.setAttribute('aria-label', `${code}${label ? ' — ' + label : ''}`);
                card.querySelectorAll('button').forEach((button) => {
                    const action = cleanText(button.textContent) || (button.dataset.act === 'del' ? 'Supprimer' : 'Modifier');
                    button.setAttribute('aria-label', `${action} — ${code}`);
                });
            });
        };
        const observer = new MutationObserver(enhance);
        if (host) observer.observe(host, { childList: true, subtree: true });
        enhance();
    }

    function enhanceWarehouseManager() {
        const root = document.getElementById('pgWarehouseManager');
        if (!root) return;
        const grid = root.querySelector('.warehouse-manager-grid');
        const enhance = () => {
            grid?.querySelectorAll('.warehouse-card').forEach((card) => {
                card.classList.add('ms-entity-card', 'crud-mobile-manager-card');
                card.setAttribute('role', 'group');
                const name = cleanText(card.querySelector('.warehouse-name')?.textContent || 'Magasin');
                card.setAttribute('aria-label', name);
                card.querySelectorAll('button').forEach((button) => {
                    const label = cleanText(button.textContent) || button.title || 'Action';
                    button.setAttribute('aria-label', `${label} — ${name}`);
                });
            });
        };
        const observer = new MutationObserver(enhance);
        if (grid) observer.observe(grid, { childList: true, subtree: true });
        enhance();
    }

    function init() {
        state.page = global.SM_PAGE || document.body?.dataset.page || '';
        state.config = PAGE_CONFIG[state.page] || null;
        state.root = state.config ? document.querySelector(state.config.root) : null;

        const supported = !!state.config || state.page === 'locations' || state.page === 'warehouse-manager';
        if (!supported) return;
        document.documentElement.dataset.crudMobilePage = state.page;
        patchLegacyModal();

        if (state.config && state.root) {
            setupTableCards(state.config);
            setupFilterPanel(state.config);
            state.config.search && document.querySelector(state.config.search)?.addEventListener('input', () => renderCards(true));
        }
        if (state.page === 'locations') {
            state.root = document.getElementById('pgLocations');
            setupFilterPanel({ filters: [{ selector: '#locWarehouse', label: 'Magasin' }] });
            enhanceLocations();
        }
        if (state.page === 'warehouse-manager') enhanceWarehouseManager();

        global.addEventListener('magestock:devicechange', () => renderCards(false));
    }

    global.CrudMobileCards = { init, refresh: () => renderCards(true) };
    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init, { once: true });
    else init();
})(window, document);
