/**
 * Projet                    : MageStock
 * Logiciel                  : MageStock
 * Rôle du fichier           : Finitions d’accessibilité et de recette mobile/tablette
 * 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, shell mobile MageStock
 * Données persistantes      : aucune
 * Permissions requises      : aucune supplémentaire
 * Contraintes de sécurité   : aucune donnée sensible manipulée
 * Compatibilité             : smartphone, tablette et clavier
 * Résumé des modifications  : retrait du libellé associé au champ de l’ancienne page Magasins.
 *

 * Fichier  : assets/js/mobile-recette.js
 * Auteur   : KREMER Régis
 * Version  : 2.6.116
 * Date     : 2026-07-25
 * Description : Finitions de recette mobile/tablette — noms accessibles, état réseau et navigation courante.
 *
 * Changelog :
 *   v2.6.87 (2026-07-20) — MOBILE FULL FIELD RECETTE11 : correctifs accessibles cumulatifs après recette finale.
 *   v2.6.116 (2026-07-25) — Retrait du champ de recherche propre à l’ancienne page Magasins.
 */
(function mobileFullFieldRecette(global) {
  'use strict';

  const LABELS = {
    btnMvMobileScan: 'Scanner un produit pour enregistrer un mouvement',
    alertSearch: 'Rechercher une alerte par produit ou SKU',
    alertWhFilter: 'Filtrer les alertes par magasin',
    alertCatFilter: 'Filtrer les alertes par catégorie',
    alertStatusFilter: 'Filtrer les alertes par statut',
    anWh: 'Filtrer les analyses par magasin',
    anWindow: 'Fenêtre d’analyse en jours',
    anHorizon: 'Horizon de projection en jours',
    brandSearch: 'Rechercher une marque',
    kitSearch: 'Rechercher un kit par nom ou SKU',
    locWarehouse: 'Filtrer les emplacements par magasin',
    locSearch: 'Rechercher un emplacement',
    lotsWarehouse: 'Filtrer les lots par magasin',
    lotsLocation: 'Filtrer les lots par emplacement',
    lotsSearch: 'Rechercher un produit, un lot ou une date',
    prodPageSize: 'Nombre de produits affichés par page',
    resStatus: 'Filtrer les réservations par statut',
    resSearch: 'Rechercher une réservation',
    suppSearch: 'Rechercher un fournisseur',
    userSearch: 'Rechercher un utilisateur'
  };

  function associatedLabel(control) {
    if (!control) return false;
    if (control.getAttribute('aria-label') || control.getAttribute('aria-labelledby')) return true;
    if (control.id && document.querySelector(`label[for="${CSS.escape(control.id)}"]`)) return true;
    return !!control.closest('label');
  }

  function cleanLabel(value) {
    return String(value || '')
      .replace(/[🔍📦🗑️✏️➕➖▦☰]+/gu, '')
      .replace(/\s+/g, ' ')
      .trim();
  }

  function matchesAndDescendants(scope, selector) {
    const nodes = [];
    if (scope && scope.nodeType === Node.ELEMENT_NODE && scope.matches(selector)) nodes.push(scope);
    scope?.querySelectorAll?.(selector).forEach((node) => nodes.push(node));
    return nodes;
  }

  function applyAccessibleNames(root) {
    const scope = root && root.querySelectorAll ? root : document;

    Object.entries(LABELS).forEach(([id, label]) => {
      const node = document.getElementById(id);
      if (node && !node.getAttribute('aria-label')) node.setAttribute('aria-label', label);
    });

    matchesAndDescendants(scope, 'input:not([type="hidden"]), select, textarea').forEach((control) => {
      if (associatedLabel(control)) return;
      const fallback = cleanLabel(control.getAttribute('title') || control.getAttribute('placeholder'));
      if (fallback) control.setAttribute('aria-label', fallback);
    });

    matchesAndDescendants(scope, 'button, [role="button"]').forEach((button) => {
      const title = cleanLabel(button.getAttribute('title'));
      if (!button.getAttribute('aria-label') && title) button.setAttribute('aria-label', title);

      if (button.matches('.category-tag-remove') && !button.getAttribute('aria-label')) {
        button.setAttribute('aria-label', 'Retirer la catégorie');
      }

      const action = String(button.getAttribute('data-act') || '').toLowerCase();
      const inline = String(button.getAttribute('onclick') || '').toLowerCase();
      const visibleText = cleanLabel(button.textContent);
      const iconOnly = visibleText === '' || /^[×x]$/i.test(visibleText);
      if (!button.getAttribute('aria-label') && (action === 'del' || /delete|remove/.test(inline)) && iconOnly) {
        button.setAttribute('aria-label', 'Supprimer');
      }
      if (!button.getAttribute('aria-label') && /openmodal|edit/.test(inline) && iconOnly) {
        button.setAttribute('aria-label', 'Modifier');
      }
    });
  }

  function markCurrentNavigation() {
    document.querySelectorAll('.sidebar-link.active, .bnav-item.active').forEach((link) => {
      link.setAttribute('aria-current', 'page');
    });
  }

  function announceNetwork(online, announce) {
    document.documentElement.dataset.msNetwork = online ? 'online' : 'offline';
    if (!announce) return;
    const region = document.getElementById(online ? 'msLiveRegionPolite' : 'msLiveRegionAssertive');
    if (region) {
      region.textContent = online
        ? 'Connexion rétablie. Les données peuvent être synchronisées.'
        : 'Connexion perdue. Les actions terrain compatibles restent conservées localement.';
    }
  }

  function init() {
    applyAccessibleNames(document);
    markCurrentNavigation();
    announceNetwork(navigator.onLine !== false, false);

    const observer = new MutationObserver((records) => {
      records.forEach((record) => record.addedNodes.forEach((node) => {
        if (node.nodeType === Node.ELEMENT_NODE) applyAccessibleNames(node);
      }));
      markCurrentNavigation();
    });
    observer.observe(document.body, { childList: true, subtree: true });

    global.addEventListener('online', () => announceNetwork(true, true));
    global.addEventListener('offline', () => announceNetwork(false, true));
    global.addEventListener('pageshow', () => {
      applyAccessibleNames(document);
      markCurrentNavigation();
      announceNetwork(navigator.onLine !== false, false);
    });
  }

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