<!-- services/manso/src/views/estadoComandas.ejs -->
<div class="d-flex align-items-center justify-content-between mb-3">
  <h1 class="h4 m-0">🧾 Estado de Comandas</h1>
  <a class="btn btn-sm btn-dark" href="/comandas">➕ Nueva comanda</a>
</div>

<div class="row g-3">
  <!-- ===== Listado (izquierda) ===== -->
  <div class="col-12 col-lg-7">
    <div class="card shadow-sm">
      <div class="card-header d-flex align-items-center">
        <strong>Listado</strong>
        <div class="form-check form-switch ms-auto">
          <input class="form-check-input" type="checkbox" id="soloAbiertas" checked>
          <label class="form-check-label" for="soloAbiertas">Solo abiertas</label>
        </div>
      </div>
      <div class="card-body">
        <div class="row g-2 align-items-center mb-2">
          <div class="col">
            <input id="buscar" type="search" class="form-control" placeholder="Buscar por #, mesa o usuario…">
          </div>
          <div class="col-auto">
            <button class="btn btn-outline-secondary" id="limpiar">Limpiar</button>
          </div>
        </div>

        <div id="lista" class="table-responsive" style="max-height:62vh; overflow:auto;">
          <div class="p-3 text-muted">Cargando…</div>
        </div>
      </div>
    </div>
  </div>

  <!-- ===== Detalle (derecha) ===== -->
  <div class="col-12 col-lg-5">
    <div class="card shadow-sm">
      <div class="card-header d-flex align-items-center">
        <strong>Detalle</strong>
        <span id="detalleEstado" class="badge badge-outline ms-auto">—</span>
      </div>

      <div class="card-body" id="detalle">
        <div class="text-muted">Selecciona una comanda para ver el detalle.</div>
      </div>

      <div class="d-flex align-items-center gap-3 p-3 border-top" style="position:sticky; bottom:0; background:#fff;">
        <div class="small"><span class="text-muted">ID:</span> <strong id="kpiId">—</strong></div>
        <div class="small"><span class="text-muted">Mesa:</span> <strong id="kpiMesa">—</strong></div>
        <div class="small"><span class="text-muted">Total:</span> <strong id="kpiTotal">$ 0.00</strong></div>
        <div class="ms-auto"></div>
        <button class="btn btn-outline-secondary" id="reabrir">Reabrir</button>
        <button class="btn btn-primary" id="cerrar">Cerrar</button>
      </div>

      <div class="card-body">
        <div id="msg" class="text-muted small"></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(Number(n)));
  const toast = (msg, ok=false) => {
    const el = $('#msg');
    el.className = ok ? 'text-success small' : 'text-danger small';
    el.textContent = msg;
    setTimeout(()=>{ el.textContent=''; el.className='text-muted small'; }, 3000);
  };
  const badgeClass = (estadoRaw) => {
    const s = String(estadoRaw||'').toLowerCase();
    if (s.includes('abier')) return 'badge badge-outline badge-estado-abierta';
    if (s.includes('pagad') || s.includes('paga')) return 'badge badge-outline badge-estado-pagada';
    if (s.includes('cerr')) return 'badge badge-outline badge-estado-cerrada';
    if (s.includes('anul') || s.includes('cancel')) return 'badge badge-outline badge-estado-anulada';
    return 'badge badge-outline';
  };

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

  // ===== Estado =====
  const state = {
    filtro: '',
    soloAbiertas: true,
    lista: [],    // [{ id_comanda, mesa_numero, mesa_apodo, usuario_nombre, usuario_apellido, fec_creacion, estado, items, total }]
    sel: null,    // id seleccionado
    detalle: []   // [{ id_det_comanda, producto_nombre, cantidad, pre_unitario, subtotal, observaciones }]
  };

  // ===== Data =====
  async function loadLista() {
    const estado = state.soloAbiertas ? 'abierta' : '';
    const url = estado ? `/api/comandas?estado=${encodeURIComponent(estado)}&limit=300` : '/api/comandas?limit=300';
    const rows = await jget(url);
    state.lista = Array.isArray(rows) ? rows : [];
    renderLista();
  }

  async function loadDetalle(id) {
    const det = await jget(`/api/comandas/${id}/detalle`);
    state.detalle = Array.isArray(det) ? det : [];
    renderDetalle();
  }

  // ===== UI: Lista =====
  function renderLista(){
    let rows = state.lista.slice();
    const f = state.filtro?.trim().toLowerCase();
    if (f) {
      rows = rows.filter(r =>
        String(r.id_comanda).includes(f) ||
        String(r.mesa_numero ?? '').includes(f) ||
        (`${r.usuario_nombre||''} ${r.usuario_apellido||''}`).toLowerCase().includes(f)
      );
    }

    const box = $('#lista');
    if (!rows.length) { box.innerHTML = '<div class="p-3 text-muted">Sin resultados.</div>'; return; }

    const tbl = document.createElement('table');
    tbl.className = 'table table-sm align-middle mb-0';
    tbl.innerHTML = `
      <thead class="table-light">
        <tr>
          <th>#</th>
          <th>Mesa</th>
          <th>Usuario</th>
          <th>Fecha</th>
          <th>Estado</th>
          <th class="text-end">Ítems</th>
          <th class="text-end">Total</th>
        </tr>
      </thead>
      <tbody></tbody>
    `;
    const tb = tbl.querySelector('tbody');

    rows.forEach(r => {
      const tr = document.createElement('tr');
      tr.style.cursor = 'pointer';
      tr.innerHTML = `
        <td>${r.id_comanda}</td>
        <td>#${r.mesa_numero ?? '—'} ${r.mesa_apodo ? '· '+r.mesa_apodo : ''}</td>
        <td>${(r.usuario_nombre||'') + ' ' + (r.usuario_apellido||'')}</td>
        <td>${r.fec_creacion ? new Date(r.fec_creacion).toLocaleString() : '—'}</td>
        <td><span class="${badgeClass(r.estado)}">${r.estado ?? '—'}</span></td>
        <td class="text-end">${r.items ?? '—'}</td>
        <td class="text-end">${money(r.total ?? 0)}</td>
      `;
      tr.addEventListener('click', () => { state.sel = r.id_comanda; loadDetalle(r.id_comanda); applyHeader(r); });
      tb.appendChild(tr);
    });

    box.innerHTML = '';
    box.appendChild(tbl);
  }

  // ===== UI: Detalle + KPIs =====
  function applyHeader(r){
    $('#kpiId').textContent   = r.id_comanda ?? '—';
    $('#kpiMesa').textContent = r.mesa_numero ? `#${r.mesa_numero}` : '—';
    $('#detalleEstado').className = badgeClass(r.estado);
    $('#detalleEstado').textContent = r.estado ?? '—';
    $('#kpiTotal').textContent = money(r.total ?? 0);

    // Botones (más precisos según estado)
    const cerr = $('#cerrar'), reab = $('#reabrir');
    const s = String(r.estado||'').toLowerCase();
    if (s.includes('abier')) {
      cerr.disabled = false; cerr.title = '';
      reab.disabled = true;  reab.title = 'Ya está abierta';
    } else if (s.includes('cerr')) {
      cerr.disabled = true;  cerr.title = 'Ya está cerrada';
      reab.disabled = false; reab.title = '';
    } else {
      // Otros estados: permitir ambas acciones
      cerr.disabled = false; cerr.title = '';
      reab.disabled = false; reab.title = '';
    }
  }

  function renderDetalle(){
    const box = $('#detalle');
    if (!state.detalle.length) {
      box.innerHTML = '<div class="text-muted">Sin detalle.</div>';
      return;
    }

    const tbl = document.createElement('table');
    tbl.className = 'table table-sm align-middle mb-0';
    tbl.innerHTML = `
      <thead class="table-light">
        <tr>
          <th>Producto</th>
          <th class="text-end">Unitario</th>
          <th class="text-end">Cantidad</th>
          <th class="text-end">Subtotal</th>
          <th>Observaciones</th>
        </tr>
      </thead>
      <tbody></tbody>
    `;
    const tb = tbl.querySelector('tbody');

    let total = 0;
    state.detalle.forEach(r => {
      const sub = Number(r.subtotal || (Number(r.pre_unitario||0) * Number(r.cantidad||0)));
      total += sub;
      const tr = document.createElement('tr');
      tr.innerHTML = `
        <td>${r.producto_nombre ?? '—'}</td>
        <td class="text-end">${money(r.pre_unitario)}</td>
        <td class="text-end">${Number(r.cantidad||0).toFixed(3)}</td>
        <td class="text-end">${money(sub)}</td>
        <td>${r.observaciones || ''}</td>
      `;
      tb.appendChild(tr);
    });

    box.innerHTML = '';
    box.appendChild(tbl);
    $('#kpiTotal').textContent = money(total);
  }

  // ===== Actions (usa /abrir y /cerrar) =====
  async function accionComanda(accion){ // 'abrir' | 'cerrar'
    if (!state.sel) return;
    try {
      await jpost(`/api/comandas/${state.sel}/${accion}`, {}); // el body no se usa en el backend
      toast(`Comanda #${state.sel} ${accion === 'abrir' ? 'reabierta' : 'cerrada'}`, true);

      // Recargar lista y re-aplicar cabecera/detalle si sigue visible
      const id = state.sel;
      await loadLista();
      const found = state.lista.find(x => x.id_comanda === id);
      if (found) {
        applyHeader(found);
        await loadDetalle(found.id_comanda);
      } else {
        // Puede desaparecer del listado si está activado "Solo abiertas" y la cerramos
        state.sel = null;
        $('#detalle').innerHTML = '<div class="text-muted">Selecciona una comanda para ver el detalle.</div>';
        $('#detalleEstado').textContent = '—'; $('#detalleEstado').className = 'badge badge-outline';
        $('#kpiId').textContent = '—'; $('#kpiMesa').textContent='—'; $('#kpiTotal').textContent = money(0);
      }
    } catch (e) {
      toast(e.message || 'No se pudo actualizar la comanda');
    }
  }

  // ===== Hooks con Sidebar (offcanvas) =====
  window.scRefreshList = loadLista;
  window.scExportCsv = function(){
    const rows = state.lista.slice();
    const header = ["id_comanda","mesa_numero","mesa_apodo","usuario","fec_creacion","estado","items","total"];
    const csv = [header.join(",")].concat(rows.map(r => {
      const usuario = `${r.usuario_nombre||''} ${r.usuario_apellido||''}`.trim();
      const vals = [
        r.id_comanda,
        r.mesa_numero ?? '',
        (r.mesa_apodo ?? '').replaceAll('"','""'),
        usuario.replaceAll('"','""'),
        r.fec_creacion ?? '',
        r.estado ?? '',
        r.items ?? '',
        r.total ?? ''
      ];
      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:`estadoComandas_${new Date().toISOString().slice(0,10)}.csv`});
    document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url);
  };

  // ===== Init =====
  $('#soloAbiertas').addEventListener('change', async (e) => { state.soloAbiertas = e.target.checked; await loadLista(); });
  $('#buscar').addEventListener('input', () => { state.filtro = $('#buscar').value.trim(); renderLista(); });
  $('#limpiar').addEventListener('click', () => { $('#buscar').value=''; state.filtro=''; renderLista(); });

  // Ahora los botones llaman a los nuevos endpoints
  $('#cerrar').addEventListener('click', () => accionComanda('cerrar'));
  $('#reabrir').addEventListener('click', () => accionComanda('abrir'));

  (async function main(){ try { await loadLista(); } catch(e){ toast(e.message||'Error cargando comandas'); }})();
</script>


<!-- <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(Number(n)));
  const toast = (msg, ok=false) => {
    const el = $('#msg');
    el.className = ok ? 'text-success small' : 'text-danger small';
    el.textContent = msg;
    setTimeout(()=>{ el.textContent=''; el.className='text-muted small'; }, 3000);
  };
  const badgeClass = (estadoRaw) => {
    const s = String(estadoRaw||'').toLowerCase();
    if (s.includes('abier')) return 'badge badge-outline badge-estado-abierta';
    if (s.includes('pagad') || s.includes('paga')) return 'badge badge-outline badge-estado-pagada';
    if (s.includes('cerr')) return 'badge badge-outline badge-estado-cerrada';
    if (s.includes('anul') || s.includes('cancel')) return 'badge badge-outline badge-estado-anulada';
    return 'badge badge-outline';
  };

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

  // ===== Estado =====
  const state = {
    filtro: '',
    soloAbiertas: true,
    lista: [],    // [{ id_comanda, mesa_numero, mesa_apodo, usuario_nombre, usuario_apellido, fec_creacion, estado, items, total }]
    sel: null,    // id seleccionado
    detalle: []   // [{ id_det_comanda, producto_nombre, cantidad, pre_unitario, subtotal, observaciones }]
  };

  // ===== Data =====
  async function loadLista() {
    const estado = state.soloAbiertas ? 'abierta' : '';
    const url = estado ? `/api/comandas?estado=${encodeURIComponent(estado)}&limit=300` : '/api/comandas?limit=300';
    const rows = await jget(url);
    state.lista = Array.isArray(rows) ? rows : [];
    renderLista();
  }

  async function loadDetalle(id) {
    const det = await jget(`/api/comandas/${id}/detalle`);
    state.detalle = Array.isArray(det) ? det : [];
    renderDetalle();
  }

  // ===== UI: Lista =====
  function renderLista(){
    let rows = state.lista.slice();
    const f = state.filtro?.trim().toLowerCase();
    if (f) {
      rows = rows.filter(r =>
        String(r.id_comanda).includes(f) ||
        String(r.mesa_numero ?? '').includes(f) ||
        (`${r.usuario_nombre||''} ${r.usuario_apellido||''}`).toLowerCase().includes(f)
      );
    }

    const box = $('#lista');
    if (!rows.length) { box.innerHTML = '<div class="p-3 text-muted">Sin resultados.</div>'; return; }

    const tbl = document.createElement('table');
    tbl.className = 'table table-sm align-middle mb-0';
    tbl.innerHTML = `
      <thead class="table-light">
        <tr>
          <th>#</th>
          <th>Mesa</th>
          <th>Usuario</th>
          <th>Fecha</th>
          <th>Estado</th>
          <th class="text-end">Ítems</th>
          <th class="text-end">Total</th>
        </tr>
      </thead>
      <tbody></tbody>
    `;
    const tb = tbl.querySelector('tbody');

    rows.forEach(r => {
      const tr = document.createElement('tr');
      tr.style.cursor = 'pointer';
      tr.innerHTML = `
        <td>${r.id_comanda}</td>
        <td>#${r.mesa_numero ?? '—'} ${r.mesa_apodo ? '· '+r.mesa_apodo : ''}</td>
        <td>${(r.usuario_nombre||'') + ' ' + (r.usuario_apellido||'')}</td>
        <td>${r.fec_creacion ? new Date(r.fec_creacion).toLocaleString() : '—'}</td>
        <td><span class="${badgeClass(r.estado)}">${r.estado ?? '—'}</span></td>
        <td class="text-end">${r.items ?? '—'}</td>
        <td class="text-end">${money(r.total ?? 0)}</td>
      `;
      tr.addEventListener('click', () => { state.sel = r.id_comanda; loadDetalle(r.id_comanda); applyHeader(r); });
      tb.appendChild(tr);
    });

    box.innerHTML = '';
    box.appendChild(tbl);
  }

  // ===== UI: Detalle + KPIs =====
  function applyHeader(r){
    $('#kpiId').textContent   = r.id_comanda ?? '—';
    $('#kpiMesa').textContent = r.mesa_numero ? `#${r.mesa_numero}` : '—';
    $('#detalleEstado').className = badgeClass(r.estado);
    $('#detalleEstado').textContent = r.estado ?? '—';
    $('#kpiTotal').textContent = money(r.total ?? 0);

    // Botones
    const cerr = $('#cerrar'), reab = $('#reabrir');
    if ((r.estado||'').toLowerCase().includes('abier')) {
      cerr.disabled = false; cerr.title = '';
      reab.disabled = true;  reab.title = 'Ya está abierta';
    } else {
      cerr.disabled = false;
      reab.disabled = false;
      cerr.title = ''; reab.title = '';
    }
  }

  function renderDetalle(){
    const box = $('#detalle');
    if (!state.detalle.length) {
      box.innerHTML = '<div class="text-muted">Sin detalle.</div>';
      return;
    }

    const tbl = document.createElement('table');
    tbl.className = 'table table-sm align-middle mb-0';
    tbl.innerHTML = `
      <thead class="table-light">
        <tr>
          <th>Producto</th>
          <th class="text-end">Unitario</th>
          <th class="text-end">Cantidad</th>
          <th class="text-end">Subtotal</th>
          <th>Observaciones</th>
        </tr>
      </thead>
      <tbody></tbody>
    `;
    const tb = tbl.querySelector('tbody');

    let total = 0;
    state.detalle.forEach(r => {
      const sub = Number(r.subtotal || (Number(r.pre_unitario||0) * Number(r.cantidad||0)));
      total += sub;
      const tr = document.createElement('tr');
      tr.innerHTML = `
        <td>${r.producto_nombre ?? '—'}</td>
        <td class="text-end">${money(r.pre_unitario)}</td>
        <td class="text-end">${Number(r.cantidad||0).toFixed(3)}</td>
        <td class="text-end">${money(sub)}</td>
        <td>${r.observaciones || ''}</td>
      `;
      tb.appendChild(tr);
    });

    box.innerHTML = '';
    box.appendChild(tbl);
    $('#kpiTotal').textContent = money(total);
  }

  // ===== Actions =====
  async function setEstado(estado){
    if (!state.sel) return;
    try {
      const { updated } = await jpost(`/api/comandas/${state.sel}/estado`, { estado });
      toast(`Comanda #${updated.id_comanda} → ${updated.estado}`, true);
      await loadLista();
      const found = state.lista.find(x => x.id_comanda === updated.id_comanda);
      if (found) { applyHeader(found); await loadDetalle(found.id_comanda); }
      else {
        state.sel = null;
        $('#detalle').innerHTML = '<div class="text-muted">Selecciona una comanda para ver el detalle.</div>';
        $('#detalleEstado').textContent = '—'; $('#detalleEstado').className = 'badge badge-outline';
        $('#kpiId').textContent = '—'; $('#kpiMesa').textContent='—'; $('#kpiTotal').textContent = money(0);
      }
    } catch (e) {
      toast(e.message || 'No se pudo cambiar el estado');
    }
  }

  // ===== Hooks con Sidebar (offcanvas) =====
  // Permite que el botón "Actualizar" del sidebar recargue este listado
  window.scRefreshList = loadLista;
  // Exportación simple del listado actual
  window.scExportCsv = function(){
    const rows = state.lista.slice();
    const header = ["id_comanda","mesa_numero","mesa_apodo","usuario","fec_creacion","estado","items","total"];
    const csv = [header.join(",")].concat(rows.map(r => {
      const usuario = `${r.usuario_nombre||''} ${r.usuario_apellido||''}`.trim();
      const vals = [
        r.id_comanda,
        r.mesa_numero ?? '',
        (r.mesa_apodo ?? '').replaceAll('"','""'),
        usuario.replaceAll('"','""'),
        r.fec_creacion ?? '',
        r.estado ?? '',
        r.items ?? '',
        r.total ?? ''
      ];
      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:`estadoComandas_${new Date().toISOString().slice(0,10)}.csv`});
    document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url);
  };

  // ===== Init =====
  $('#soloAbiertas').addEventListener('change', async (e) => { state.soloAbiertas = e.target.checked; await loadLista(); });
  $('#buscar').addEventListener('input', () => { state.filtro = $('#buscar').value.trim(); renderLista(); });
  $('#limpiar').addEventListener('click', () => { $('#buscar').value=''; state.filtro=''; renderLista(); });
  $('#cerrar').addEventListener('click', () => setEstado('cerrada'));
  $('#reabrir').addEventListener('click', () => setEstado('abierta'));

  (async function main(){ try { await loadLista(); } catch(e){ toast(e.message||'Error cargando comandas'); }})();
</script> -->
