/**
 * Fichier  : assets/js/pages/locations.js
 * Version  : 2.3.2
 * Description : JS — Emplacements internes — CRUD via Modal global (pas de modal inline)
 */
function escapeHtml(s){
  return String(s??'').replace(/[&<>"']/g, c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#039;'}[c]));
}

const LocationsPage = {
  rows: [],
  warehouses: [],
  stock: [],
  filter: { warehouseId: null, q: '' },

  async init(){
    const root = document.getElementById('pgLocations');
    if(!root) return;

    this.el = {
      wh:     document.getElementById('locWarehouse'),
      search: document.getElementById('locSearch'),
      tbl:    document.getElementById('tblLocations')?.querySelector('tbody'),
      btnAdd: document.getElementById('btnLocAdd'),
    };

    this.bind();
    await this.loadWarehouses();
    await this.load();
  },

  bind(){
    if(this.el.btnAdd) this.el.btnAdd.onclick = () => this.openModal(null);

    if(this.el.search){
      this.el.search.addEventListener('input', () => {
        this.filter.q = (this.el.search.value||'').trim().toLowerCase();
        this.render();
      });
    }

    if(this.el.wh){
      this.el.wh.addEventListener('change', async () => {
        this.filter.warehouseId = this.el.wh.value || null;
        await this.load();
      });
    }
  },

  async loadWarehouses(){
    this.warehouses = await Api.warehouses();
    const opts = ['<option value="">Tous les magasins</option>']
      .concat(this.warehouses.map(w=>`<option value="${w.id}">${escapeHtml(w.name||('Magasin #'+w.id))}</option>`));
    if(this.el.wh) this.el.wh.innerHTML = opts.join('');
  },

  async load(){
    const wid = this.filter.warehouseId;
    [this.rows, this.stock] = await Promise.all([
      Api.locations(wid),
      Api.stock()
    ]);
    this.render();
  },

  render(){
    if(!this.el.tbl) return;
    const q = this.filter.q;
    let rows = this.rows.slice();
    if(q){
      rows = rows.filter(r=>{
        const s = `${r.code||''} ${r.label||''} ${r.zone||''}`.toLowerCase();
        return s.includes(q);
      });
    }
    rows.sort((a,b)=> (a.code||'').localeCompare(b.code||''));

    if(rows.length === 0){
      this.el.tbl.innerHTML = `<tr><td colspan="6" style="text-align:center;color:var(--text-muted);padding:32px">Aucun emplacement</td></tr>`;
      return;
    }

    this.el.tbl.innerHTML = rows.map(r=>{
      const wh = this.warehouses.find(w=>String(w.id)===String(r.warehouseId));
      const whName = wh ? escapeHtml(wh.name) : '—';
      const activeHtml = r.active === false
        ? `<span class="badge badge-muted">Non</span>`
        : `<span class="badge badge-green">Oui</span>`;
      // Compter les lignes de stock liées à cet emplacement
      const linkedCount = this.stock.filter(s => String(s.locationId) === String(r.id)).length;
      const linkedHtml = linkedCount > 0
        ? `<span class="badge badge-blue" title="${linkedCount} produit(s) stocké(s) ici">${linkedCount} produit${linkedCount>1?'s':''}</span>`
        : `<span style="color:var(--text-muted);font-size:12px">—</span>`;
      return `<tr>
        <td><strong>${escapeHtml(r.code||'')}</strong></td>
        <td>${escapeHtml(r.label||'') || '<span style="color:var(--text-muted)">—</span>'}</td>
        <td>${escapeHtml(r.zone||'') || '<span style="color:var(--text-muted)">—</span>'}</td>
        <td>${whName}</td>
        <td style="text-align:center">${linkedHtml}</td>
        <td style="text-align:center">${activeHtml}</td>
        <td style="text-align:right;white-space:nowrap">
          <button class="btn btn-ghost btn-sm" data-act="edit" data-id="${r.id}">Éditer</button>
          <button class="btn btn-danger btn-sm" data-act="del" data-id="${r.id}">Suppr.</button>
        </td>
      </tr>`;
    }).join('');

    this.el.tbl.querySelectorAll('button[data-act]').forEach(btn=>{
      btn.onclick = () => {
        const id  = btn.getAttribute('data-id');
        const act = btn.getAttribute('data-act');
        const row = this.rows.find(x=>String(x.id)===String(id));
        if(act==='edit') this.openModal(row);
        if(act==='del')  this.deleteRow(row);
      };
    });
  },

  _buildForm(row){
    const whOptions = this.warehouses.map(w=>`<option value="${w.id}">${escapeHtml(w.name||('Magasin #'+w.id))}</option>`).join('');
    const selectedWh = String(row?.warehouseId || this.warehouses[0]?.id || '');
    return `
      <div style="display:grid;grid-template-columns:1fr 1fr;gap:12px">
        <div>
          <label class="lbl">Magasin *</label>
          <select id="locMWarehouse" class="sel">${whOptions}</select>
        </div>
        <div>
          <label class="lbl">Code *</label>
          <input id="locMCode" class="inp" placeholder="A1" value="${escapeHtml(row?.code||'')}" />
        </div>
        <div>
          <label class="lbl">Zone</label>
          <input id="locMZone" class="inp" placeholder="Réserve / Quarantaine…" value="${escapeHtml(row?.zone||'')}" />
        </div>
        <div>
          <label class="lbl">Libellé</label>
          <input id="locMLabel" class="inp" placeholder="Rack 2 – Étage 1" value="${escapeHtml(row?.label||'')}" />
        </div>
        <div>
          <label class="lbl">Actif</label>
          <select id="locMActive" class="sel">
            <option value="1" ${row?.active !== false ? 'selected' : ''}>Oui</option>
            <option value="0" ${row?.active === false  ? 'selected' : ''}>Non</option>
          </select>
        </div>
      </div>
      <input type="hidden" id="locMId" value="${escapeHtml(String(row?.id||''))}" />
    `;
  },

  openModal(row){
    const isNew = !row;
    const html  = this._buildForm(row);

    Modal.show(
      isNew ? 'Ajouter un emplacement' : 'Modifier un emplacement',
      html,
      [
        {label:'Annuler', cls:'btn-secondary', onclick:()=>Modal.close()},
        {label:isNew?'Enregistrer':'Mettre à jour', cls:'btn-primary', onclick:()=>this.saveModal()},
      ],
      isNew ? 'success' : 'info'
    );

    // Set selected warehouse after modal opened
    const sel = document.getElementById('locMWarehouse');
    if(sel) sel.value = String(row?.warehouseId || this.warehouses[0]?.id || '');
  },

  async saveModal(){
    const id   = (document.getElementById('locMId')?.value||'').trim();
    const payload = {
      id: id || undefined,
      warehouseId: parseInt(document.getElementById('locMWarehouse')?.value||'0',10),
      code:   (document.getElementById('locMCode')?.value||'').trim(),
      label:  (document.getElementById('locMLabel')?.value||'').trim(),
      zone:   (document.getElementById('locMZone')?.value||'').trim(),
      active: document.getElementById('locMActive')?.value === '1'
    };

    if(!payload.warehouseId || !payload.code){
      toast('Magasin et code sont obligatoires.', 'warn');
      return;
    }

    try{
      if(id){
        await Api.locationUpdate(payload);
        toast('Emplacement mis à jour.', 'success');
      } else {
        await Api.locationSave(payload);
        toast('Emplacement ajouté.', 'success');
      }
      Modal.close();
      await this.load();
    } catch(e){
      toast(e?.message || 'Erreur', 'error');
    }
  },

  async deleteRow(row){
    if(!row) return;
    if(!confirm(`Supprimer l'emplacement "${row.code}" ?`)) return;
    try{
      await Api.locationDelete(row.id);
      toast('Supprimé.', 'success');
      await this.load();
    } catch(e){
      toast(e?.message || 'Erreur', 'error');
    }
  }
};


// ─────────────────────────────────────────────────────────────
// Extension StockMaster — Étiquettes emplacements (multi)
// Injection robuste (évite régressions même si le core évolue)
// ─────────────────────────────────────────────────────────────
(function(){
  if(!window || !LocationsPage) return;

  // Ajoute les méthodes manquantes sans dépendre de la structure interne
  Object.assign(LocationsPage, {
    labelState: LocationsPage.labelState || { q: '', selected: new Set() },

    _labelEls(){
      this.el = this.el || {};
      // éléments seulement si le module est présent dans la vue
      this.el.lblSearch     = document.getElementById('locLabelSearch');
      this.el.lblSelectAll  = document.getElementById('locLabelSelectAll');
      this.el.lblCount      = document.getElementById('locLabelCount');
      this.el.lblList       = document.getElementById('locLabelList');
      this.el.lblGrid       = document.getElementById('locLabelGrid');
      this.el.lblPrintArea  = document.getElementById('locLabelPrintArea');
      this.el.btnLblPrint   = document.getElementById('btnLocLabelsPrint');
    },

    _labelsEnabled(){
      return !!(this.el && this.el.lblList && this.el.lblGrid && this.el.btnLblPrint);
    },

    _bindLabels(){
      if(!this._labelsEnabled()) return;

      if(this.el.lblSearch && !this.el.lblSearch.__smBound){
        this.el.lblSearch.__smBound = true;
        this.el.lblSearch.addEventListener('input', () => {
          this.labelState.q = (this.el.lblSearch.value||'').trim().toLowerCase();
          this.renderLabelList();
        });
      }

      if(this.el.lblSelectAll && !this.el.lblSelectAll.__smBound){
        this.el.lblSelectAll.__smBound = true;
        this.el.lblSelectAll.addEventListener('change', () => {
          const checked = !!this.el.lblSelectAll.checked;
          const ids = this.getLabelListIds();
          if(checked) ids.forEach(id => this.labelState.selected.add(String(id)));
          else ids.forEach(id => this.labelState.selected.delete(String(id)));
          this.renderLabels();
          this.renderLabelList();
        });
      }

      if(this.el.btnLblPrint && !this.el.btnLblPrint.__smBound){
        this.el.btnLblPrint.__smBound = true;
        this.el.btnLblPrint.addEventListener('click', () => {
          if(this.labelState.selected.size === 0) return;
          window.print();
        });
      }
    },

    getLabelListIds(){
      const q = (this.labelState.q||'').trim();
      let rows = (this.rows||[]).slice();
      if(q){
        rows = rows.filter(r => {
          const s = `${r.code||''} ${r.label||''} ${r.zone||''}`.toLowerCase();
          return s.includes(q);
        });
      }
      rows.sort((a,b)=> (a.code||'').localeCompare(b.code||''));
      return rows.map(r => r.id);
    },

    renderLabelList(){
      if(!this._labelsEnabled()) return;

      const q = (this.labelState.q||'').trim();
      let rows = (this.rows||[]).slice();
      if(q){
        rows = rows.filter(r => {
          const s = `${r.code||''} ${r.label||''} ${r.zone||''}`.toLowerCase();
          return s.includes(q);
        });
      }
      rows.sort((a,b)=> (a.code||'').localeCompare(b.code||''));

      if(rows.length === 0){
        this.el.lblList.innerHTML = `<div class="loc-label-empty-sm">Aucun emplacement.</div>`;
        this.renderLabelListHeaderState();
        return;
      }

      this.el.lblList.innerHTML = rows.map(r => {
        const id = String(r.id);
        const checked = this.labelState.selected.has(id) ? 'checked' : '';
        const code = (r.code || '').trim() || '—';
        const sub = [ (r.label||'').trim(), (r.zone||'').trim() ].filter(Boolean).join(' · ');
        return `
          <label class="loc-label-item">
            <input type="checkbox" class="locLabelChk" value="${escapeHtml(id)}" ${checked}>
            <div class="loc-label-item-txt">
              <div class="loc-label-item-title">${escapeHtml(code)}</div>
              <div class="loc-label-item-sub">${sub ? escapeHtml(sub) : '—'}</div>
            </div>
          </label>
        `;
      }).join('');

      this.el.lblList.querySelectorAll('input.locLabelChk').forEach(inp => {
        inp.addEventListener('change', () => {
          const id = String(inp.value);
          if(inp.checked) this.labelState.selected.add(id);
          else this.labelState.selected.delete(id);
          this.renderLabels();
          this.renderLabelListHeaderState();
        });
      });

      this.renderLabelListHeaderState();
    },

    renderLabelListHeaderState(){
      if(!this._labelsEnabled()) return;

      const count = this.labelState.selected.size;
      if(this.el.lblCount) this.el.lblCount.textContent = `${count} sélection${count>1?'s':''}`;
      if(this.el.btnLblPrint) this.el.btnLblPrint.disabled = count === 0;

      if(this.el.lblSelectAll){
        const ids = this.getLabelListIds().map(String);
        const all = ids.length>0 && ids.every(id => this.labelState.selected.has(id));
        const none = ids.every(id => !this.labelState.selected.has(id));
        this.el.lblSelectAll.indeterminate = !all && !none;
        this.el.lblSelectAll.checked = all;
      }
    },

    buildLabelHTML(row){
    // Étiquette V2 : logo plus grand au-dessus + infos en dessous (lisible, terrain)
    const name = (row?.code || '').trim() || '—';
    const sub = [ (row?.zone||'').trim(), (row?.warehouseName||'').trim() ].filter(Boolean).join(' · ');

    return `
      <div class="loc-label-sheet loc-label-sheet--v2">
        <div class="loc-label-logo-wrap">
          <img class="loc-label-logo loc-label-logo--v2" src="assets/img/sm_logo.png" alt="StockMaster">
        </div>
        <div class="loc-label-text loc-label-text--v2">
          <div class="loc-label-name loc-label-name--v2">${escapeHtml(name)}</div>
          ${sub ? `<div class="loc-label-sub loc-label-sub--v2">${escapeHtml(sub)}</div>` : ''}
        </div>
      </div>
    `;
  },

    renderLabels(){
      if(!this._labelsEnabled()) return;

      const ids = Array.from(this.labelState.selected.values());
      const rows = ids
        .map(id => (this.rows||[]).find(r => String(r.id)===String(id)))
        .filter(Boolean)
        .map(r => {
          const wh = (this.warehouses||[]).find(w => String(w.id)===String(r.warehouseId));
          return { ...r, warehouseName: wh ? wh.name : '' };
        });

      if(rows.length === 0){
        this.el.lblGrid.innerHTML = `<div class="loc-label-empty">Cochez des emplacements pour afficher les étiquettes.</div>`;
        if(this.el.lblPrintArea) this.el.lblPrintArea.innerHTML = '';
        this.renderLabelListHeaderState();
        return;
      }

      this.el.lblGrid.innerHTML = rows.map(r => this.buildLabelHTML(r)).join('');
      if(this.el.lblPrintArea){
        this.el.lblPrintArea.innerHTML = `<div class="loc-label-print-grid">${rows.map(r => this.buildLabelHTML(r)).join('')}</div>`;
      }
      this.renderLabelListHeaderState();
    },

    _refreshLabels(){
      this._labelEls();
      if(!this._labelsEnabled()) return;
      this._bindLabels();
      this.renderLabelList();
      this.renderLabels();
    }
  });

  // Hook init/load without rewriting existing code
  const _init = LocationsPage.init;
  LocationsPage.init = async function(){
    await _init.call(this);
    this._refreshLabels();
  };

  const _load = LocationsPage.load;
  LocationsPage.load = async function(){
    await _load.call(this);
    this._refreshLabels();
  };
})();


document.addEventListener('DOMContentLoaded', ()=>{
  if(window.SM_PAGE === 'locations') LocationsPage.init();
});
