<!-- services/manso/src/views/productos.ejs -->
<div class="d-flex align-items-center justify-content-between mb-3">
  <h1 class="h4 m-0">🛒 Productos</h1>
  <div class="d-flex gap-2">
    <button id="btnNuevo" class="btn btn-outline-secondary btn-sm">Nuevo</button>
    <button id="btnGuardar" class="btn btn-primary btn-sm">Guardar</button>
    <button class="btn btn-outline-dark btn-sm" data-bs-toggle="collapse" data-bs-target="#mpWrap" aria-expanded="false">Materias primas</button>

</div>
</div>

<div class="row g-3">
  <!-- ===== Listado ===== -->
  <div class="col-12 col-lg-6">
    <div class="card shadow-sm">
      <div class="card-header d-flex align-items-center">
        <strong>Listado</strong>
        <div class="ms-auto d-flex gap-2">
          <input id="q" type="search" class="form-control form-control-sm" placeholder="Buscar…">
          <button id="btnLimpiar" class="btn btn-outline-secondary btn-sm">Limpiar</button>
        </div>
      </div>
      <div class="card-body p-0">
        <div class="table-responsive" style="max-height: 65vh; overflow: auto;">
          <table class="table table-sm align-middle mb-0">
            <thead class="table-light">
              <tr>
                <th>#</th>
                <th>Nombre</th>
                <th class="text-end">Precio</th>
                <th>Activo</th>
                <th>Categoría</th>
              </tr>
            </thead>
            <tbody id="tbProductos">
              <tr><td colspan="5" class="p-3 text-muted">Cargando…</td></tr>
            </tbody>
          </table>
        </div>
      </div>
    </div>
  </div>

  <!-- ===== Edición / Alta ===== -->
  <div class="col-12 col-lg-6">
    <div class="card shadow-sm">
      <div class="card-header"><strong>Ficha</strong></div>
      <div class="card-body">
        <input type="hidden" id="id_producto">
        <div class="row g-3">
          <div class="col-12">
            <label class="form-label small text-muted mb-1" for="nombre">Nombre</label>
            <input id="nombre" class="form-control" autocomplete="off">
          </div>
          <div class="col-12 col-sm-6">
            <label class="form-label small text-muted mb-1" for="precio">Precio</label>
            <input id="precio" type="number" step="0.01" min="0" class="form-control">
          </div>
          <div class="col-12 col-sm-6">
            <label class="form-label small text-muted mb-1" for="id_categoria">Categoría</label>
            <select id="id_categoria" class="form-select"></select>
          </div>
          <div class="col-12">
            <label class="form-label small text-muted mb-1" for="img_producto">Imagen (URL)</label>
            <input id="img_producto" class="form-control" placeholder="img_producto.png">
            <div class="mt-2">
              <img id="preview" src="" alt="" class="img-thumbnail d-none" style="max-height: 140px;">
            </div>
          </div>
          <div class="col-12">
            <div class="form-check">
              <input id="activo" class="form-check-input" type="checkbox" checked>
              <label for="activo" class="form-check-label">Activo</label>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- ===== Receta ===== -->
    <div class="card shadow-sm mt-3">
      <div class="card-header d-flex align-items-center">
        <strong>Receta (materias primas por unidad)</strong>
        <button id="btnAddIng" class="btn btn-outline-secondary btn-sm ms-auto">Agregar ingrediente</button>
      </div>
      <div class="card-body p-0">
        <div class="table-responsive">
          <table class="table table-sm align-middle mb-0">
            <thead class="table-light">
              <tr>
                <th style="width: 55%;">Materia prima</th>
                <th class="text-end" style="width: 25%;">Cantidad</th>
                <th style="width: 20%;"></th>
              </tr>
            </thead>
            <tbody id="tbReceta">
              <tr><td colspan="3" class="p-3 text-muted">Sin ingredientes.</td></tr>
            </tbody>
          </table>
        </div>
      </div>
      <div class="card-footer d-flex align-items-center small text-muted">
        Cantidades en la unidad definida por cada materia prima.
        <span id="msg" class="ms-auto"></span>
      </div>
    </div>
  </div>
</div>

<!-- ====== GESTIÓN DE MATERIAS PRIMAS (OCULTO POR DEFECTO) ====== -->
<div class="collapse mt-4" id="mpWrap">
  <div class="d-flex align-items-center justify-content-between mb-2">
    <h2 class="h5 m-0">⚙️ Materias primas</h2>
    <div class="d-flex gap-2">
      <button id="mpNuevo" class="btn btn-outline-secondary btn-sm">Nuevo</button>
      <button id="mpGuardar" class="btn btn-primary btn-sm">Guardar</button>
    </div>
  </div>

  <div class="row g-3">
    <!-- Listado MP -->
    <div class="col-12 col-lg-6">
      <div class="card shadow-sm">
        <div class="card-header d-flex align-items-center">
          <strong>Listado</strong>
          <div class="ms-auto d-flex gap-2">
            <input id="mpQ" type="search" class="form-control form-control-sm" placeholder="Buscar…">
            <button id="mpLimpiar" class="btn btn-outline-secondary btn-sm">Limpiar</button>
          </div>
        </div>
        <div class="card-body p-0">
          <div class="table-responsive" style="max-height:60vh;overflow:auto;">
            <table class="table table-sm align-middle mb-0">
              <thead class="table-light">
                <tr>
                  <th>#</th>
                  <th>Nombre</th>
                  <th>Unidad</th>
                  <th>Activo</th>
                </tr>
              </thead>
              <tbody id="mpTb">
                <tr><td colspan="4" class="p-3 text-muted">Cargando…</td></tr>
              </tbody>
            </table>
          </div>
        </div>
      </div>
    </div>

    <!-- Ficha MP -->
    <div class="col-12 col-lg-6">
      <div class="card shadow-sm">
        <div class="card-header"><strong>Ficha</strong></div>
        <div class="card-body">
          <input type="hidden" id="mp_id_mat_prima">
          <div class="row g-3">
            <div class="col-12">
              <label class="form-label small text-muted mb-1" for="mp_nombre">Nombre</label>
              <input id="mp_nombre" class="form-control" autocomplete="off">
            </div>
            <div class="col-12 col-sm-6">
              <label class="form-label small text-muted mb-1" for="mp_unidad">Unidad</label>
              <input id="mp_unidad" class="form-control" placeholder="ej: gr, ml, u.">
            </div>
            <div class="col-12 col-sm-6 d-flex align-items-end">
              <div class="form-check">
                <input id="mp_activo" class="form-check-input" type="checkbox" checked>
                <label class="form-check-label" for="mp_activo">Activo</label>
              </div>
            </div>

            <div class="col-12">
              <label class="form-label small text-muted mb-1" for="mp_proveedores">Proveedores (asignación)</label>
              <select id="mp_proveedores" class="form-select" multiple></select>
              <div class="form-text">Mantén presionadas Ctrl/⌘ para seleccionar varios.</div>
            </div>
          </div>
        </div>
        <div class="card-footer small text-muted d-flex">
          <span id="mpMsg"></span>
        </div>
      </div>
    </div>
  </div>
</div>

<script>
  // ===== Helpers =====
  const $  = (s, r=document)=>r.querySelector(s);
  const $$ = (s, r=document)=>Array.from(r.querySelectorAll(s));
  const money = (n)=> isNaN(n) ? '—' : new Intl.NumberFormat('es-UY',{style:'currency',currency:'UYU'}).format(+n);
  const toast = (t, ok=false)=> { const el=$('#msg'); el.className = 'ms-auto ' + (ok?'text-success':'text-danger'); el.textContent=t; setTimeout(()=>{ el.textContent=''; el.className='ms-auto text-muted'; }, 3000); };

  async function jget(u){ const r=await fetch(u); const j=await r.json().catch(()=>null); if(!r.ok) throw new Error(j?.error||r.statusText); return j; }
  async function jpost(u,b){ const r=await fetch(u,{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(b)}); const j=await r.json().catch(()=>null); if(!r.ok) throw new Error(j?.error||r.statusText); return j; }

  // ===== Estado =====
  const state = {
    productos: [],
    categorias: [],
    materias: [],
    receta: [],           // [{id_mat_prima, nombre, unidad, qty_por_unidad}]
    filtro: '',
    selId: null
  };

  // ===== Carga inicial =====
  async function init(){
    const [prods, cats, mats] = await Promise.all([
      jget('/api/table/productos?limit=2000'),
      jget('/api/table/categorias?limit=2000').catch(()=>[]),
      jget('/api/table/mate_primas?limit=2000')
    ]);
    state.productos = Array.isArray(prods)? prods : [];
    state.categorias = Array.isArray(cats)? cats : [];
    state.catById = new Map(state.categorias.map(c => [c.id_categoria, c.nombre]));
    state.materias = Array.isArray(mats)? mats : [];

    hydrateCategorias();
    renderLista();
    clearForm();
  }

  function hydrateCategorias(){
    const sel = $('#id_categoria'); sel.innerHTML='';
    sel.appendChild(new Option('(sin categoría)', '', true, true));
    state.categorias.forEach(c => sel.appendChild(new Option(c.nombre || ('#'+c.id_categoria), c.id_categoria)));
  }

  // ===== Listado =====
  const catName = (id) => state?.catById?.get(id) ?? (id ? `#${id}` : '');
  function renderLista(){
    const tb = $('#tbProductos');
    let rows = state.productos.slice();
    const f = state.filtro.trim().toLowerCase();
    if (f) rows = rows.filter(p => (p.nombre||'').toLowerCase().includes(f) || String(p.id_producto).includes(f));

    if (!rows.length) { tb.innerHTML = '<tr><td colspan="5" class="p-3 text-muted">Sin resultados.</td></tr>'; return; }

    tb.innerHTML = '';
    rows.forEach(p => {
      const tr = document.createElement('tr');
      tr.style.cursor='pointer';
      tr.innerHTML = `
        <td>${p.id_producto}</td>
        <td>${p.nombre||'—'}</td>
        <td class="text-end">${money(p.precio)}</td>
        <td>${p.activo ? 'Sí' : 'No'}</td>
        <td>${catName(p.id_categoria)}</td>
      `;
      tr.addEventListener('click', ()=> loadProducto(p.id_producto));
      tb.appendChild(tr);
    });
  }

  // ===== Ficha =====
  function clearForm(){
    state.selId = null;
    $('#id_producto').value = '';
    $('#nombre').value = '';
    $('#precio').value = '';
    $('#id_categoria').value = '';
    $('#img_producto').value = '';
    $('#preview').src = ''; $('#preview').classList.add('d-none');
    $('#activo').checked = true;
    state.receta = [];
    renderReceta();
  }

  async function loadProducto(id){
    try {
      // Usamos la función SQL (RPC) para traer producto + receta en un solo tiro
      const data = await jget(`/api/rpc/get_producto/${id}`);
      const p = data.producto || {};
      const r = Array.isArray(data.receta) ? data.receta : [];

      state.selId = p.id_producto;
      $('#id_producto').value = p.id_producto ?? '';
      $('#nombre').value = p.nombre ?? '';
      $('#precio').value = p.precio ?? '';
      $('#id_categoria').value = p.id_categoria ?? '';
      $('#img_producto').value = p.img_producto ?? '';
      if (p.img_producto) { $('#preview').src = p.img_producto; $('#preview').classList.remove('d-none'); } else { $('#preview').src=''; $('#preview').classList.add('d-none'); }
      $('#activo').checked = (p.activo !== false);

      // receta
      state.receta = r.map(x => ({
        id_mat_prima: x.id_mat_prima,
        nombre: x.nombre ?? (state.materias.find(m=>m.id_mat_prima===x.id_mat_prima)?.nombre || ('#'+x.id_mat_prima)),
        unidad: x.unidad ?? (state.materias.find(m=>m.id_mat_prima===x.id_mat_prima)?.unidad || ''),
        qty_por_unidad: Number(x.qty_por_unidad||0)
      }));
      renderReceta();
    } catch(e) {
      toast(e.message || 'No se pudo cargar el producto');
    }
  }

  // ===== Receta (UI) =====
  function renderReceta(){
    const tb = $('#tbReceta');
    if (!state.receta.length) { tb.innerHTML = '<tr><td colspan="3" class="p-3 text-muted">Sin ingredientes.</td></tr>'; return; }
    tb.innerHTML = '';

    state.receta.forEach((it, idx) => {
      const tr = document.createElement('tr');
      const sel = document.createElement('select');
      sel.className = 'form-select form-select-sm';
      state.materias.forEach(m => sel.appendChild(new Option(`${m.nombre} (${m.unidad||'-'})`, m.id_mat_prima, false, m.id_mat_prima===it.id_mat_prima)));
      sel.addEventListener('change', () => {
        const val = parseInt(sel.value, 10);
        if (!Number.isInteger(val) || val <= 0) {         // si algo raro
            const first = state.materias[0];
            it.id_mat_prima = Number(first?.id_mat_prima || 0);
        } else {
            it.id_mat_prima = val;
        }
        const m = state.materias.find(x => x.id_mat_prima === it.id_mat_prima);
        it.nombre = m?.nombre || '';
        it.unidad = m?.unidad || '';
      });


      const qty = document.createElement('input');
      qty.type = 'number'; qty.min='0.001'; qty.step='0.001'; qty.value = (it.qty_por_unidad||0).toFixed(3);
      qty.className = 'form-control form-control-sm text-end';
      qty.addEventListener('change', ()=> it.qty_por_unidad = Number(qty.value||0));

      const del = document.createElement('button');
      del.className = 'btn btn-outline-secondary btn-sm';
      del.textContent = 'Quitar';
      del.addEventListener('click', ()=> { state.receta.splice(idx,1); renderReceta(); });

      const td1 = document.createElement('td'); td1.appendChild(sel);
      const td2 = document.createElement('td'); td2.className='text-end'; td2.appendChild(qty);
      const td3 = document.createElement('td'); td3.appendChild(del);

      tr.append(td1,td2,td3);
      tb.appendChild(tr);
    });
  }

    function addIngrediente(){
    if (!state.materias.length) {
        toast('Primero cargá materias primas', false);
        return;
    }
    const m = state.materias[0];
    state.receta.push({
        id_mat_prima: Number(m.id_mat_prima),   // siempre número válido
        nombre: m.nombre || '',
        unidad: m.unidad || '',
        qty_por_unidad: 1.000
    });
    renderReceta();
    }

  // ===== Guardar (INSERT/UPDATE + receta) vía función SQL =====
  async function guardar(){
    try {
        const cleanedReceta = state.receta
        .map(r => ({
            id: parseInt(r.id_mat_prima, 10),
            qty: Number(r.qty_por_unidad)
        }))
        .filter(x => Number.isInteger(x.id) && x.id > 0 && Number.isFinite(x.qty) && x.qty > 0)
        .map(x => ({ id_mat_prima: x.id, qty_por_unidad: +x.qty.toFixed(3) }));

        const payload = {
        id_producto: $('#id_producto').value ? Number($('#id_producto').value) : null,
        nombre: $('#nombre').value.trim(),
        img_producto: $('#img_producto').value.trim() || null,
        precio: Number($('#precio').value || 0),
        activo: $('#activo').checked,
        id_categoria: $('#id_categoria').value ? Number($('#id_categoria').value) : null,
        receta: cleanedReceta
        };

        if (cleanedReceta.length !== state.receta.length) {
        toast('Se ignoraron ingredientes inválidos (id o cantidad).', false);
        }

      if (!payload.nombre) { toast('Nombre requerido'); return; }
      if (!(payload.precio >= 0)) { toast('Precio inválido'); return; }

      const { id_producto } = await jpost('/api/rpc/save_producto', payload);
      toast(`Guardado #${id_producto}`, true);

      // refrescar listado y reabrir seleccionado
      state.productos = await jget('/api/table/productos?limit=2000');
      renderLista();
      await loadProducto(id_producto);
    } catch (e) {
      toast(e.message || 'No se pudo guardar');
    }
  }

  // ===== Eventos =====
  $('#q').addEventListener('input', ()=> { state.filtro = $('#q').value||''; renderLista(); });
  $('#btnLimpiar').addEventListener('click', ()=> { $('#q').value=''; state.filtro=''; renderLista(); });
  $('#btnNuevo').addEventListener('click', clearForm);
  $('#btnAddIng').addEventListener('click', addIngrediente);
  $('#btnGuardar').addEventListener('click', guardar);
  $('#img_producto').addEventListener('input', ()=> {
    const v=$('#img_producto').value.trim();
    if (v) { $('#preview').src=v; $('#preview').classList.remove('d-none'); } else { $('#preview').src=''; $('#preview').classList.add('d-none'); }
  });

  // Hooks con sidebar (opcional)
  window.scRefreshList = async function(){ state.productos = await jget('/api/table/productos?limit=2000'); renderLista(); };
  window.scExportCsv   = function(){
    const rows = state.productos.slice();
    const head = ["id_producto","nombre","precio","activo","id_categoria"];
    const csv = [head.join(",")].concat(rows.map(r => {
      const vals = [r.id_producto,r.nombre,(r.precio??''),(r.activo??''),(r.id_categoria??'')];
      return vals.map(v => `"${String(v??'').replaceAll('"','""')}"`).join(",");
    })).join("\n");
    const blob = new Blob([csv],{type:"text/csv;charset=utf-8"});
    const url = URL.createObjectURL(blob);
    const a = Object.assign(document.createElement("a"), {href:url, download:`productos_${new Date().toISOString().slice(0,10)}.csv`});
    document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url);
  };

  /* ========= EXTENSIÓN: MATERIAS PRIMAS ========= */

  // 1) ampliar el estado global existente:
  state.proveedores = state.proveedores || [];
  state.mpFiltro = '';
  state.mpSelId = null;
  state.mpAsignados = []; // array de id_proveedor seleccionados para la MP

  // 2) cargar proveedores también en init()
  const __oldInit = init;
  init = async function() {
    const [provs] = await Promise.all([
      jget('/api/table/proveedores?limit=5000').catch(()=>[])
    ]);
    state.proveedores = Array.isArray(provs) ? provs : [];
    await __oldInit();        // llama a tu init original (productos + categorías + materias)
    hydrateMpProveedoresOptions(); // por si abres el panel de MP
  };

  // helpers UI MP
  function mpToast(t, ok=false){ const el=$('#mpMsg'); el.className = ok?'text-success':'text-danger'; el.textContent=t; setTimeout(()=>{el.textContent=''; el.className='';}, 3000); }
  function hydrateMpProveedoresOptions(selectedIds=[]) {
    const sel = $('#mp_proveedores'); if (!sel) return;
    sel.innerHTML = '';
    state.proveedores.forEach(p => {
      const opt = new Option(p.raz_social || ('#'+p.id_proveedor), p.id_proveedor, false, selectedIds.includes(p.id_proveedor));
      sel.appendChild(opt);
    });
  }

  // 3) listado MP
  function renderMpLista() {
    const tb = $('#mpTb'); if (!tb) return;
    let rows = state.materias.slice();
    const f = (state.mpFiltro||'').trim().toLowerCase();
    if (f) rows = rows.filter(m => (m.nombre||'').toLowerCase().includes(f) || String(m.id_mat_prima).includes(f));

    if (!rows.length) { tb.innerHTML = '<tr><td colspan="4" class="p-3 text-muted">Sin resultados.</td></tr>'; return; }
    tb.innerHTML = '';
    rows.forEach(m => {
      const tr = document.createElement('tr');
      tr.style.cursor='pointer';
      tr.innerHTML = `
        <td>${m.id_mat_prima}</td>
        <td>${m.nombre||'—'}</td>
        <td>${m.unidad||'—'}</td>
        <td>${m.activo ? 'Sí' : 'No'}</td>
      `;
      tr.addEventListener('click', ()=> loadMp(m.id_mat_prima));
      tb.appendChild(tr);
    });
  }

  // 4) limpiar ficha MP
  function clearMpForm() {
    state.mpSelId = null;
    $('#mp_id_mat_prima').value = '';
    $('#mp_nombre').value = '';
    $('#mp_unidad').value = '';
    $('#mp_activo').checked = true;
    state.mpAsignados = [];
    hydrateMpProveedoresOptions([]);
  }

  // 5) cargar MP + proveedores asignados (via función SQL)
  async function loadMp(id) {
    try {
      const data = await jget(`/api/rpc/get_materia/${id}`); // { materia: {...}, proveedores: [...] }
      const m = data.materia || {};
      const provs = Array.isArray(data.proveedores) ? data.proveedores : [];

      state.mpSelId = m.id_mat_prima;
      $('#mp_id_mat_prima').value = m.id_mat_prima ?? '';
      $('#mp_nombre').value = m.nombre ?? '';
      $('#mp_unidad').value = m.unidad ?? '';
      $('#mp_activo').checked = (m.activo !== false);

      state.mpAsignados = provs.map(x => x.id_proveedor);
      hydrateMpProveedoresOptions(state.mpAsignados);
    } catch (e) {
      mpToast(e.message || 'No se pudo cargar la materia prima');
    }
  }

  // 6) guardar MP (insert/update) y sincronizar proveedores (JSONB)
  async function saveMp() {
    try {
      const payload = {
        id_mat_prima: $('#mp_id_mat_prima').value ? Number($('#mp_id_mat_prima').value) : null,
        nombre: $('#mp_nombre').value.trim(),
        unidad: $('#mp_unidad').value.trim(),
        activo: $('#mp_activo').checked,
        proveedores: Array.from($('#mp_proveedores').selectedOptions).map(o => Number(o.value))
      };
      if (!payload.nombre) { mpToast('Nombre requerido'); return; }

      const r = await jpost('/api/rpc/save_materia', payload); // => { id_mat_prima }
      mpToast(`Guardado #${r.id_mat_prima}`, true);

      // refrescar listas globales
      state.materias = await jget('/api/table/mate_primas?limit=5000');
      renderMpLista();
      hydrateCategorias();   // no hace falta, pero mantenemos consistencia si dependiera de MPs
      // refrescar selects de receta del producto (por si se usa en receta)
      renderReceta(); // tu función existente reusará state.materias
      await loadMp(r.id_mat_prima);
    } catch (e) {
      mpToast(e.message || 'No se pudo guardar');
    }
  }

  // 7) listeners MP
  document.getElementById('mpQ')?.addEventListener('input', ()=> { state.mpFiltro = $('#mpQ').value||''; renderMpLista(); });
  document.getElementById('mpLimpiar')?.addEventListener('click', ()=> { $('#mpQ').value=''; state.mpFiltro=''; renderMpLista(); });
  document.getElementById('mpNuevo')?.addEventListener('click', clearMpForm);
  document.getElementById('mpGuardar')?.addEventListener('click', saveMp);

  // 8) cuando se despliega el panel MP por primera vez, renderizar listado
  document.getElementById('mpWrap')?.addEventListener('shown.bs.collapse', ()=> renderMpLista());

  function imgUrl(v){
    if (!v) return '';
    return v.startsWith('http') ? v : `/img/productos/${v}`;
  }

    $('#img_producto').addEventListener('input', ()=>{
    const v = $('#img_producto').value.trim();
    const src = imgUrl(v);
    if (src) { $('#preview').src = src; $('#preview').classList.remove('d-none'); }
        else     { $('#preview').src = '';  $('#preview').classList.add('d-none'); }
    });

  // Go
  init().catch(e => toast(e.message||'Error cargando datos'));
</script>
