/* ---------- Variables globales ---------- */
var Categorias = [];
var Productos = [];

// ─── STOCK RUNTIME COMPARTIDO ────────────────────────────────────────────────
var StockRuntime = {};

function buildStockRuntime(productos) {
  StockRuntime = {};
  (productos || []).forEach(function(p) {
    if (!p.Stock || p.Stock.crt_stock != 1 || !p.Stock.ingredientes) return;
    try {
      var ings = JSON.parse(p.Stock.ingredientes || '[]');
      ings.forEach(function(ing) {
        var key = String(ing.id_ins);
        if (!(key in StockRuntime)) {
          StockRuntime[key] = parseFloat(ing.stock_actual) || 0;
        }
      });
    } catch(e) {}
  });
}

function getStockVendible(item) {
  if (!item.Stock || item.Stock.crt_stock != 1 || !item.Stock.ingredientes) return null;
  try {
    var ings = JSON.parse(item.Stock.ingredientes || '[]');
    if (!ings.length) return 0;
    if (item.Stock.receta == 1) {
      var minVendible = Infinity;
      for (var i = 0; i < ings.length; i++) {
        var ing = ings[i];
        var cant = parseFloat(ing.cant) || 0;
        if (cant <= 0) continue;
        var key = String(ing.id_ins);
        var stockBase = (key in StockRuntime) ? StockRuntime[key] : (parseFloat(ing.stock_actual) || 0);
        var vendible = Math.floor(stockBase / cant);
        if (vendible < minVendible) minVendible = vendible;
      }
      return minVendible === Infinity ? 0 : minVendible;
    } else {
      var ing0 = ings[0];
      var key0 = String(ing0.id_ins);
      var base = (key0 in StockRuntime) ? StockRuntime[key0] : (parseFloat(ing0.stock_actual) || 0);
      return Math.floor(base);
    }
  } catch(e) { return 0; }
}

function actualizarStockRuntime(item, qty, operacion) {
  if (!item.Stock || item.Stock.crt_stock != 1 || !item.Stock.ingredientes) return;
  try {
    var ings = JSON.parse(item.Stock.ingredientes || '[]');
    var keysAfectadas = [];
    var procesados = {}; // guard: evita doble-descuento si id_ins está duplicado en el JSON (bug SQL de JOIN cartesiano)
    ings.forEach(function(ing) {
      var key = String(ing.id_ins);
      if (procesados[key]) return; // mismo insumo ya procesado → skip
      procesados[key] = true;
      if (!(key in StockRuntime)) StockRuntime[key] = parseFloat(ing.stock_actual) || 0;
      var delta = item.Stock.receta == 1 ? (parseFloat(ing.cant) || 0) * qty : qty;
      if (operacion === 'restar') {
        StockRuntime[key] = Math.max(0, StockRuntime[key] - delta);
      } else {
        StockRuntime[key] += delta;
      }
      keysAfectadas.push(key);
    });
    repaintPresentacionesAfectadas(keysAfectadas);
  } catch(e) { console.warn('actualizarStockRuntime:', e); }
}

function repaintPresentacionesAfectadas(keysAfectadas) {
  var keySet = {};
  keysAfectadas.forEach(function(k) { keySet[String(k)] = true; });
  Productos.forEach(function(p) {
    if (!p.Stock || p.Stock.crt_stock != 1 || !p.Stock.ingredientes) return;
    try {
      var pIngs = JSON.parse(p.Stock.ingredientes || '[]');
      var afectado = pIngs.some(function(i) { return keySet[String(i.id_ins)]; });
      if (!afectado) return;
      $('.section-list .card-menu-wrapper').each(function() {
        var it = $(this).data('item');
        if (!it || it.id_pres !== p.id_pres) return;
        if ($(this).closest('.grid-view').length) {
          var $h = $(this).find('.card-menu-header');
          $h.find('.stock-badge').remove();
          $h.append(renderStockBadge(p));
        } else {
          var $c = $(this).find('.stock-container-list');
          $c.empty();
          $c.append(renderStockBadgeList(p));
        }
      });
    } catch(e) {}
  });
}

function refrescarTodosLosBadgesVisibles() {
  $('.section-list .card-menu-wrapper').each(function() {
    var $wrap = $(this);
    var it = $wrap.data('item');
    if (!it || !it.Stock || it.Stock.crt_stock != 1) return;
    var fresh = Productos.find(function(p) { return p.id_pres === it.id_pres; });
    var p = fresh || it;
    if (fresh) $wrap.data('item', fresh);
    if ($wrap.closest('.grid-view').length) {
      var $h = $wrap.find('.card-menu-header');
      $h.find('.stock-badge').remove();
      $h.append(renderStockBadge(p));
    } else {
      var $c = $wrap.find('.stock-container-list');
      $c.empty();
      $c.append(renderStockBadgeList(p));
    }
  });
}
// ─────────────────────────────────────────────────────────────────────────────
var modoListaProductos = "grid";
var selectionMode = false;
var PedidoSeleccionado = [];
var Pedidos = [];
const splitSelection = new Map();

// Validador interno de imagenes de productos (con fallback silencioso).
const productoImagenCache = new Map();

function normalizarNombreImagenProducto(valor) {
  let raw = (valor == null ? "" : String(valor)).trim();
  if (!raw) return "default.png";

  const lower = raw.toLowerCase();
  if (lower === "null" || lower === "undefined") return "default.png";

  raw = raw.replace(/\\/g, "/").replace(/^\.?\//, "");
  raw = raw.replace(/^public\/images\/productos\//i, "");
  raw = raw.replace(/^images\/productos\//i, "");
  return raw || "default.png";
}

function construirUrlImagenProducto(valor) {
  const normalized = normalizarNombreImagenProducto(valor);
  if (/^https?:\/\//i.test(normalized)) return normalized;

  const base = ($("#url").val() || "").replace(/\/+$/, "") + "/";
  const encoded = normalized
    .split("/")
    .map((part) => encodeURIComponent(part))
    .join("/");
  return `${base}public/images/productos/${encoded}`;
}

function validarImagenesProductosEnSegundoPlano($scope) {
  const $root = $scope && $scope.length ? $scope : $(document);
  const base = ($("#url").val() || "").replace(/\/+$/, "") + "/";
  const fallbackPrincipal = construirUrlImagenProducto("default.png");
  const fallbackSecundario = `${base}public/images/default.png`;

  $root.find("img.js-product-img").each(function () {
    const img = this;
    if (img.dataset.validatorBound === "1") return;
    img.dataset.validatorBound = "1";

    const applyFallback = () => {
      const step = Number(img.dataset.fallbackStep || 0);
      if (step === 0) {
        img.dataset.fallbackStep = "1";
        img.src = fallbackPrincipal;
        return;
      }
      if (step === 1) {
        img.dataset.fallbackStep = "2";
        img.src = fallbackSecundario;
      }
    };

    img.addEventListener("error", applyFallback);

    const src = img.getAttribute("src") || "";
    if (!src) {
      applyFallback();
      return;
    }

    if (productoImagenCache.has(src)) {
      if (!productoImagenCache.get(src)) applyFallback();
      return;
    }

    // Validacion silenciosa en segundo plano.
    const probe = new Image();
    probe.onload = function () {
      productoImagenCache.set(src, true);
    };
    probe.onerror = function () {
      productoImagenCache.set(src, false);
      applyFallback();
    };
    probe.src = src;
  });
}

function parseMontoSeguro(value) {
  if (value === null || value === undefined) return 0;
  let str = String(value).trim();
  if (!str) return 0;

  str = str.replace(/\s+/g, "");
  str = str.replace(/[^0-9,.-]/g, "");
  if (!str) return 0;

  const hasComma = str.indexOf(",") !== -1;
  const hasDot = str.indexOf(".") !== -1;

  if (hasComma && hasDot) {
    if (str.lastIndexOf(",") > str.lastIndexOf(".")) {
      str = str.replace(/\./g, "").replace(",", ".");
    } else {
      str = str.replace(/,/g, "");
    }
  } else if (hasComma && !hasDot) {
    str = str.replace(",", ".");
  }

  const num = parseFloat(str);
  return Number.isFinite(num) ? num : 0;
}

function getTotalPedidoActual() {
  const $visible = $(".totalPedidoMenosTarjeta:visible").first();
  if ($visible.length) return parseMontoSeguro($visible.text());
  return parseMontoSeguro($(".totalPedidoMenosTarjeta").first().text());
}

function getPagoInput(selector) {
  const $visible = $(`${selector}:visible`).first();
  if ($visible.length) return parseMontoSeguro($visible.val());
  return parseMontoSeguro($(selector).first().val());
}

function getComisionTarjetaActual() {
  if (!(getTipoPagoActual() === 2 && $(".comision_tarjeta_venta").is(":checked"))) {
    return 0;
  }
  return parseMontoSeguro($(".comisionTarjeta").first().text());
}

function getPorcentajeComisionTarjetaConfig() {
  const $config = $("#config_comision_tarjeta").first();
  if ($config.length) return parseMontoSeguro($config.val());

  // Fallback de compatibilidad para versiones anteriores.
  const $legacy = $("#comision_tarjeta").first();
  if ($legacy.length) return parseMontoSeguro($legacy.val());

  return 0;
}

function getTipoPagoActual() {
  const $tipoPago = $("#tipo_pago");
  if (!$tipoPago.length) return 1;

  const $selected = $tipoPago.find("option:selected");
  const tipoDesdeLabel = parseInt($selected.attr("label"), 10);
  if (Number.isFinite(tipoDesdeLabel)) return tipoDesdeLabel;

  const tipoDesdeValue = parseInt($tipoPago.val(), 10);
  return Number.isFinite(tipoDesdeValue) ? tipoDesdeValue : 1;
}

function actualizarVuelto() {
  const tipoPago = getTipoPagoActual();
  const total = getTotalPedidoActual();
  const pagoEfe = getPagoInput("#pago_efe");
  const pagoTar = getPagoInput("#pago_tar");
  const pagoYape = getPagoInput("#pago_yape");
  const pagoPlin = getPagoInput("#pago_plin");
  const pagoTran = getPagoInput("#pago_tran");
  const comision = getComisionTarjetaActual();

  let saldoEfectivoPendiente = total;
  if (tipoPago === 1) {
    saldoEfectivoPendiente = total;
  } else if (tipoPago === 3) {
    saldoEfectivoPendiente =
      total - pagoTar - pagoYape - pagoPlin - pagoTran - comision;
  } else {
    saldoEfectivoPendiente = 0;
  }

  if (!Number.isFinite(saldoEfectivoPendiente) || saldoEfectivoPendiente < 0) {
    saldoEfectivoPendiente = 0;
  }

  let vuelto = pagoEfe - saldoEfectivoPendiente;
  if (!Number.isFinite(vuelto) || vuelto < 0) vuelto = 0;

  $("#vuelto").text(formatNumber(vuelto));
  toggleDynamicTotals();
}

// Estado global sencillo
var PedidosState = {
  orders: new Map(),
  cart: [],
  categoriasLoaded: false,
  igv: 0.1,
};

$(function () {
  "use strict";

  console.log("JS de venta rápida cargado");

  getPedidos();

  const pusher = new Pusher("01c14cdca26db19318e0", {
    cluster: "us2",
    forceTLS: true,
  });

  const channel = pusher.subscribe($("#pusher_channel").val());

  channel.bind("notification-ventaRapida", function (data) {
    console.log("notification-ventaRapida:", data);
    getPedidos();
  });

  // stock-update: otro terminal hizo una venta → recargar desde servidor y reconstruir runtime
  channel.bind("stock-update", function () {
    listarCategorias().then(function() {
      refrescarTodosLosBadgesVisibles();
    });
  });

  // Seed de pedidos (borra cuando conectes backend)
  [
    {
      id: "A1001",
      mesa: "12",
      salon: "Principal",
      mozo: "Carlos",
      createdAt: Date.now() - 1000 * 60 * 10,
      status: "pendiente",
      priority: "high",
      items: [
        { name: "Lomo Saltado", qty: 1, note: "poco picante" },
        { name: "Chicha", qty: 2 },
      ],
      total: 58.5,
    },
    {
      id: "A1002",
      mesa: "5",
      salon: "Terraza",
      mozo: "Ana",
      createdAt: Date.now() - 1000 * 60 * 6,
      status: "preparacion",
      priority: "med",
      items: [
        { name: "Ceviche", qty: 1 },
        { name: "Inka Kola", qty: 1 },
      ],
      total: 42.0,
    },
    {
      id: "A1003",
      mesa: "3",
      salon: "Principal",
      mozo: "Luis",
      createdAt: Date.now() - 1000 * 60 * 2,
      status: "pendiente",
      priority: "low",
      items: [
        { name: "Pollo a la brasa", qty: 1, note: "pecho" },
        { name: "Puré", qty: 1 },
      ],
      total: 36.0,
    },
  ].forEach((o) => PedidosState.orders.set(o.id, o));

  // Render inicial de pedidos

  // Eventos toolbar principal

  // Botón +Nuevo abre el modal y asegura carta cargada
  $("#btnNuevo").on("click", function () {
    if (!Array.isArray(PedidoSeleccionado)) {
      PedidoSeleccionado = [];
    }
    vaciarListaProductos();
    activateOptionsPedido(0);
    iniciarModalPedido();

    // Force reset of buttons for Phase 1 (just in case)
    $("#btnCobrar").addClass("d-none");
    $("#btn_entregado").addClass("d-none");
    $("#btn_registrar_pedido").removeClass("d-none");

    // Force hide secondary actions
    $("#btn_anular_venta").addClass("d-none");
    $("#btnDividirCuenta").addClass("d-none");
    $("#openDialog").addClass("d-none");
  });

  $("#btnCobrar").on("click", function (event) {
    event.preventDefault();
    procesarData();
  });

  $("#btnClientePedidoLimpiar").click(function () {
    $("#cliente_id").val("");
    $("#id_cliente").val("");
    $("#cliente_documento").val("");
    $("#buscar_cliente_pedido").val("");
    $("#buscar_cliente_pedido").focus();
  });

  $("#openDialog").on("click", function () {
    if (typeof aplicarEstadoDescuentoModal === "function") {
      aplicarEstadoDescuentoModal($("#tipo_descuento_select").val(), {
        showAlerts: false,
      });
    }
    $(".dialogBtn")[0].showModal();
  });

  // Cerrar con el botón Cancelar
  $(".closeDialogBtn").on("click", function () {
    $(".dialogBtn")[0].close();
  });

  $("#btn_anular_venta").on("click", function (event) {
    event.preventDefault();
    anular_pedido(PedidoSeleccionado.id_pedido);
  });

  function getTipoDocumentoSeleccionado() {
    return Number($("input:radio[name=\"tipo_doc\"]:checked").val() || 0);
  }

  function aplicarEstadoDescuentoModal(tipoRaw, options = {}) {
    const opts = {
      showAlerts: true,
      resetValuesOnNone: false,
      ...options,
    };

    const tipo = Number(tipoRaw || 0);
    const tipoDoc = getTipoDocumentoSeleccionado();
    const $rowMonto = $(".display-descuento-monto");
    const $rowPersonal = $(".display-personal");
    const $rowMotivo = $("#fila_motivo_descuento");
    const $personal = $("#personal_descuento");

    $rowMonto.hide();
    $rowPersonal.hide();
    $rowMotivo.toggle(tipo !== 0);
    $("#descuento_porcentaje, #descuento_monto_fijo").prop("disabled", true);
    $personal.prop("disabled", true);

    if (tipo === 1 && (tipoDoc === 1 || tipoDoc === 2)) {
      if (opts.showAlerts) {
        mostrarAlerta(
          "warning",
          "Atención",
          "No se puede aplicar cortesía con boleta o factura."
        );
      }
      $("#tipo_descuento_select").val("0");
      return aplicarEstadoDescuentoModal(0, {
        showAlerts: false,
        resetValuesOnNone: true,
      });
    }

    if (tipo === 2) {
      $rowMonto.show();
      $("#descuento_porcentaje, #descuento_monto_fijo").prop("disabled", false);
      return true;
    }

    if (tipo === 3) {
      $rowMonto.show();
      $rowPersonal.show();
      $("#descuento_porcentaje, #descuento_monto_fijo").prop("disabled", false);
      $personal.prop("disabled", false);
      if (!$personal.children().length) {
        listarPersonal();
      }
      return true;
    }

    if (opts.resetValuesOnNone) {
      $("#descuento_porcentaje").val("");
      $("#descuento_monto_fijo").val("");
      $("#descuento_motivo").val("");
      $personal.val("");
    }

    $("#descuento_personal_hidden").val("0");
    $("#descuento_tipo_hidden").val("0");
    return true;
  }

  $("#tipo_descuento_select").on("change", function () {
    aplicarEstadoDescuentoModal($(this).val());
  });
  $("#descuento_porcentaje").on("input", function () {
    let pct = parseFloat(this.value) || 0;
    let total = parseFloat($(".SubtotalPedido").text()) || 0;
    if (pct < 0) pct = 0;
    if (pct > 100) pct = 100;
    // 3) Calculas el monto de descuento
    const monto = (total * pct) / 100;
    // 4) Lo vuelcas donde quieras y haces tu log
    console.log("TotalPedido:", total, "- %:", pct, "- Descuento:", monto);
    $("#descuento_monto_fijo").val(monto.toFixed(2));
  });

  $("#btn_descuentos").on("click", function (event) {
    actualizarPrecioDescuentos();
    event.preventDefault(); // Evitar redirección
  });

  $(document).on("input", "#numero_cliente", function () {
    const $this = $(this);
    const soloDigitos = ($this.val() || "").replace(/\D+/g, "").slice(0, 11);
    if ($this.val() !== soloDigitos) {
      $this.val(soloDigitos);
    }

    $("#button-addon2").prop("disabled", soloDigitos.length !== 11);
    showWspInlineFeedback("clear", "");
    updateWspStatusDot("idle");
  });

  $(document).on("focus click touchstart", "#numero_cliente", function () {
    $(this).prop("readonly", false).prop("disabled", false).css("pointer-events", "auto");
  });

  $("#buscar_cliente_pedido").on("input", function () {
    const start = this.selectionStart,
      end = this.selectionEnd;
    const upper = this.value.toUpperCase();
    if (this.value !== upper) {
      this.value = upper;
      this.setSelectionRange(start, end);
    }
  });

  let dataMozo = $("#mozos_data").val();
  dataMozo = JSON.parse(dataMozo);
  const $select = $('<select class="form-control"></select>');
  // Agregar las opciones
  dataMozo.forEach(function (mozo) {
    const nombre = `${mozo.nombres} ${mozo.ape_paterno} ${mozo.ape_materno}`;
    const $option = $("<option></option>").val(mozo.id_usu).text(nombre);
    $select.append($option);
  });

  $("#select_mozo").html($select);

  // Carga categorías al cargar la página (una sola vez)
  if (!PedidosState.categoriasLoaded) {
    PedidosState.categoriasLoaded = true;
    listarCategorias();
  }

  $("#tipo_pago").change(function () {
    const value = getTipoPagoActual();

    console.log(value);

    if (value != 2) {
      $(".comision_tarjeta_venta").prop("checked", false);
      $(".view_comision_tarjeta").hide();
      $(".comisionTarjeta").text(formatNumber(0));
      const subtotalBase = parseMontoSeguro($(".SubtotalPedido").first().text());
      const descuentoBase = parseMontoSeguro($(".totalDescuento").first().text());
      const deliveryBase = parseMontoSeguro($(".totalDelivery").first().text());
      const totalSinComision = subtotalBase - descuentoBase + deliveryBase;
      $(".totalPedidoMenosTarjeta").text(formatNumber(totalSinComision));
    }

    if (value == 1) {
      limpiar_pagos_a();
      $(".mensaje-pago").hide();
      $(".display-pago-efectivo").show();
      $(".display-pago-tarjeta").hide();
      //$(".display-pago-default").show();
      $(".display-cod-voucher").hide();
      $(".display-pago-rapido-efectivo").show();
      $(".display-codigo-operacion").hide();
      $("#pago_efe").val(formatNumber(getTotalPedidoActual()));
      $(".opc-01").text(formatNumber($(".totalPedido").val()));
      actualizarVuelto();
    } else if (value == 3) {
      limpiar_pagos_a();
      $(".mensaje-pago").hide();
      $(".display-pago-efectivo").show();
      $(".display-pago-tarjeta").show();
      //$(".display-pago-default").show();
      $(".display-cod-voucher").hide();
      $(".display-pago-rapido-efectivo").show();
      $(".display-codigo-operacion").hide();
      actualizarVuelto();
    } else if (value == 4) {
      $(".mensaje-pago").hide();
      //$('.mensaje-pago-text').text(' Ingrese codigo de transferencia');
      $(".display-pago-efectivo").hide();
      $(".display-pago-tarjeta").hide();
      //$(".display-pago-default").hide();
      $(".display-cod-voucher").show();
      $(".display-pago-rapido-efectivo").hide();
      $(".display-codigo-operacion").show();
      actualizarVuelto();
    } else if (value == 2) {
      limpiar_pagos_a();
      $(".mensaje-pago").hide();
      //$('.mensaje-pago-text').text(' Ingrese codigo de transferencia');
      $(".display-pago-efectivo").hide();
      $(".display-pago-tarjeta").hide();
      //$(".display-pago-default").hide();
      $(".display-cod-voucher").show();
      $(".display-pago-rapido-efectivo").hide();
      $(".display-codigo-operacion").show();
      actualizarVuelto();
    } else if (value >= 5) {
      $(".mensaje-pago").hide();
      //$('.mensaje-pago-text').text(' Ingrese codigo de transferencia');
      $(".display-pago-efectivo").hide();
      $(".display-pago-tarjeta").hide();
      //$(".display-pago-default").hide();
      $(".display-cod-voucher").show();
      $(".display-pago-rapido-efectivo").hide();
      $(".display-codigo-operacion").show();
      actualizarVuelto();
    }
    //calculo_total();
  });

  iniciarModalPedido();

  // Unsaved Exit Protection
  $('#modal-pedidos').on('hide.bs.modal', function (e) {
    if (window.forceCloseModal) {
      window.forceCloseModal = false;
      return; // Allow close
    }

    let hasNewItems = false;
    $(".po-item-wrapper").each(function () {
      if ($(this).data("item").isNew) hasNewItems = true;
    });

    if (hasNewItems) {
      e.preventDefault(); // Stop closing
      e.stopImmediatePropagation();

      Swal.fire({
        title: '¿Salir sin guardar?',
        text: "Tienes pedidos marcados en AZUL que no se han enviado a cocina. Se perderán si sales.",
        icon: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#d33',
        cancelButtonColor: '#3085d6',
        confirmButtonText: 'Sí, salir y perder cambios',
        cancelButtonText: 'No, quedarme'
      }).then((result) => {
        if (result.isConfirmed) {
          // User wants to leave. Clear new items? Or just close?
          // Best to just close.
          window.forceCloseModal = true;
          $('#modal-pedidos').modal('hide');
        }
      });
    }
  });

  $(document).on("click", ".po-item .edit_precio", function (e) {
    e.stopPropagation();
    const permisoEditarPrecio = $("#permisoEditarPrecio").val() === "1";

    if (!permisoEditarPrecio) {
      mostrarAlerta(
        "warning",
        "sin permisos",
        "No tienes permiso para editar el precio"
      );
      return;
    }

    const $wrapper = $(this).closest(".po-item-wrapper");
    const product = $wrapper.data("item");
    const $priceSpan = $wrapper.find(".price");
    const oldPrice = parseFloat($priceSpan.text()) || 0;

    if ($wrapper.find(".price-edit-input").length) return;

    const $input = $(`
      <input
        type="number"
        class="price-edit-input form-control form-control-sm"
        style="width:80px; display:inline-block; margin-left:.5rem;"
        step="0.01"
        value="${oldPrice.toFixed(2)}"
      >
    `);

    $priceSpan.replaceWith($input);
    $input.focus().select();

    $input.on("blur keyup", function (evt) {
      if (evt.type === "blur" || evt.key === "Enter") {
        let nv = parseFloat($input.val());
        if (isNaN(nv) || nv < 0) nv = oldPrice;

        product.pro_cos = nv.toFixed(2);
        const $newSpan = $(`<span class="price">${nv.toFixed(2)}</span>`);
        $input.replaceWith($newSpan);

        actualizarTotalesDesdeLista();
      }
    });
  });

  //   $("#btnDividirCuenta").on("click", function (event) {
  //     event.preventDefault();
  //     selectionMode = !selectionMode;

  //     if (selectionMode) {
  //       // === ACTIVAR SELECCIÓN ===
  //       $(this).text("Desactivar");
  //       $(".po-items").addClass("selection-mode");

  //       // Mostrar contadores y ocultar cantidad completa
  //       $(".po-items .po-item-wrapper").each(function () {
  //         const $w = $(this);
  //         const data = $w.data("item") || {};

  //         // Cantidad Máxima (lo que hoy muestra tu UI o lo que guardaste al agregar)
  //         const maxQtyDOM =
  //           parseInt($w.find(".cantidad span").eq(1).text().trim()) || 0;
  //         const maxQtyData = parseInt(data.cantidad || 0) || 0;
  //         const maxQty = maxQtyDOM || maxQtyData;

  //         // Asegurar clases para poder alternar visibilidad como en tu código anterior
  //         const $qtySpan = $w.find(".cantidad span").eq(1); // span central
  //         $qtySpan.addClass("full-quantity"); // ahora podemos ocultarlo/mostrarlo

  //         if ($w.find(".selection-counter").length === 0) {
  //           $qtySpan.after('<span class="selection-counter ms-2"></span>');
  //         }

  //         $w.attr("data-selected", 0);
  //         $w.find(".selection-counter").removeClass("d-none").text(`0/${maxQty}`);
  //         $w.find(".full-quantity").addClass("d-none");

  //         const $price = $w.find(".price");
  //         $price.text(`${moneda} ${formatNumber(0)}`);
  //       });

  //       const monto_descuento = parseFloat($("#descuento_monto_fijo").val() || 0);
  //       const monto_delivery = parseFloat($("#comision_delivery").val() || 0);

  //       $("#pago_efe").val(formatNumber(0));
  //       $(".SubtotalPedido").text(formatNumber(0));
  //       $(".totalDelivery").text(formatNumber(monto_delivery));
  //       $(".totalDescuento").text(formatNumber(monto_descuento));
  //       $(".totalPedidoMenosTarjeta").text(formatNumber(0));
  //       TotalPedido = 0;
  //     } else {
  //       // === DESACTIVAR SELECCIÓN ===
  //       $(this).text("Activar selección");
  //       $(".po-items").removeClass("selection-mode");

  //       let globalTotal = 0;

  //       $(".po-items .po-item-wrapper").each(function () {
  //         const $w = $(this);
  //         const data = $w.data("item") || {};

  //         const unitPrice = parseFloat(data.pro_cos || 0) || 0;

  //         // Recuperar cantidad completa (la que mostrabas originalmente)
  //         const maxQtyDOM =
  //           parseInt($w.find(".cantidad span").eq(1).text().trim()) || 0;
  //         const maxQtyData = parseInt(data.cantidad || 0) || 0;
  //         const maxQty = maxQtyDOM || maxQtyData;

  //         // Limpiar estado de selección
  //         $w.removeClass("selected").attr("data-selected", 0);
  //         $w.find(".selection-counter").addClass("d-none"); // si prefieres, podrías .remove()
  //         $w.find(".full-quantity").removeClass("d-none").text(maxQty);

  //         // Recalcular total de la línea (cantidad completa * precio unitario)
  //         const itemTotal = maxQty * unitPrice;
  //         $w.find(".price").text(`${moneda} ${formatNumber(itemTotal)}`);
  //         globalTotal += itemTotal;
  //       });

  //       // === Restaurar totales ===
  //       const monto_descuento = parseFloat($("#descuento_monto_fijo").val() || 0);
  //       const monto_delivery = parseFloat($("#comision_delivery").val() || 0);
  //       const total_pedido = globalTotal - monto_descuento + monto_delivery;

  //       // Ajusta estos campos si tu flujo lo requiere distinto
  //       $("#pago_efe").val(formatNumber(0)); // en tu código setea y luego vuelve a 0; mantengo comportamiento
  //       $(".SubtotalPedido").text(formatNumber(globalTotal));
  //       $(".totalDelivery").text(formatNumber(monto_delivery));
  //       $(".totalDescuento").text(formatNumber(monto_descuento));
  //       $(".totalPedidoMenosTarjeta").text(formatNumber(total_pedido));
  //       TotalPedido = globalTotal;
  //     }
  //   });

  $("#btn_close_aside").on("click", function (e) {
    e.preventDefault();

    var $panel = $("#modal-pedidos");

    console.log("Attempting to close panel:", $panel);

    // 1) Si es un modal de BS4, ciérralo
    if ($panel.hasClass("modal")) {
      $panel.modal("hide");
      // también quita el backdrop si queda alguno
      $(".modal-backdrop").remove();

      // 2) Si es un Collapse (offcanvas custom), ciérralo
    } else if ($panel.hasClass("collapse")) {
      $panel.collapse("hide");

      // 3) Fallback: quita clases manualmente
    } else {
      $panel.removeClass("show");
    }
  });

  $(document).on("click", ".po-item .comments", function (e) {
    e.stopPropagation();

    const $wrapper = $(this).closest(".po-item-wrapper");
    const product = $wrapper.data("item");
    const $content = $wrapper.find(".content");
    const $checkboxContainer = $wrapper.find(".nota-list .demo-checkbox");

    console.log(product);

    // 1) Calculamos aquí el array de notas originales (si existen)
    const notasOriginal =
      product.notas && product.notas.notas
        ? product.notas.notas
          .split(",")
          .map((n) => n.trim())
          .filter((n) => n)
        : [];

    $content.slideToggle("fast");
    if (!$content.is(":visible")) return;

    // 2) Inicialización de los checkboxes (sólo la primera vez)
    if (!$wrapper.data("initialized")) {
      $checkboxContainer.empty().addClass("row");

      notasOriginal.forEach((nota, idx) => {
        const cbId = `nota-${product.wrapperId}-${idx}`;
        const checked = (product.selectedNotas || []).includes(nota)
          ? "checked"
          : "";
        const html = `
          <div class="col-6 mb-2">
            <div class="form-check">
              <input class="form-check-input" type="checkbox" id="${cbId}"
                     value="${nota}" ${checked}>
              <label class="form-check-label" for="${cbId}">${nota}</label>
            </div>
          </div>
        `;
        $checkboxContainer.append(html);
      });

      $wrapper.find(".nota-new").toggle(notasOriginal.length === 0);
      $wrapper.find(".nota-list").show();
      $wrapper.data("initialized", true);
    }

    // 3) Manejo de cambios en los checkboxes
    $checkboxContainer
      .off("change")
      .on("change", "input[type=checkbox]", function () {
        // recolectamos seleccionadas
        const seleccionadas = $checkboxContainer
          .find("input:checked")
          .map((i, el) => el.value.trim())
          .get();

        // guardamos en el producto
        product.selectedNotas = seleccionadas;

        // reconstruimos el texto intermedio: notas manuales + seleccionadas
        const $texto = $wrapper.find(".texto-intermedio");
        const actualTexto = $texto.text().trim();
        const manuales = actualTexto
          .split(",")
          .map((t) => t.trim())
          .filter((t) => t && !notasOriginal.includes(t));

        $texto.text([...manuales, ...seleccionadas].join(", "));
      });

    // 4) Al abrir siempre actualizamos el texto según lo guardado
    const prevSel = product.selectedNotas || [];
    const $texto = $wrapper.find(".texto-intermedio");
    const manuales = $texto
      .text()
      .split(",")
      .map((t) => t.trim())
      .filter((t) => t && !notasOriginal.includes(t));

    $texto.text([...manuales, ...prevSel].join(", "));
  });

  $(document).on("click", "#btn_cobrar", function (e) {
    e.stopPropagation();
    procesarData();
  });

  $(document).on("click", "#btn_entregado", function (e) {
    e.stopPropagation();
    console.log(PedidoSeleccionado);
    pedidoAccion(
      2,
      3,
      PedidoSeleccionado.estado_pedido,
      PedidoSeleccionado.id_pedido
    );
  });

  $(document).on("click", ".guardar-nota-manual", function () {
    const $clickedWrapper = $(this).closest(".po-item-wrapper");
    const nota = $clickedWrapper.find(".nota_manual_text").val().trim();
    const producto = $clickedWrapper.data("item");

    if (nota === "") {
      alert("Por favor escribe una nota antes de guardar.");
      return;
    }

    $.ajax({
      url: $("#url").val() + "venta/tags_crud",
      method: "POST",
      dataType: "json",
      data: {
        id_prod: producto.notas.id_prod,
        notas: nota.toUpperCase(),
      },
      success: function (response) {
        if (response.success) {
          const cleanNota = nota.toUpperCase();

          // ACTUALIZA LAS NOTAS EN EL OBJETO PRODUCTO
          producto.notas.notas = producto.notas.notas
            ? `${producto.notas.notas},${cleanNota}`
            : cleanNota;

          if (!Array.isArray(producto.selectedNotas)) {
            producto.selectedNotas = [];
          }

          if (!producto.selectedNotas.includes(cleanNota)) {
            producto.selectedNotas.push(cleanNota);
          }

          // Recorrer todos los productos con el mismo id_pres
          $(".po-item-wrapper").each(function () {
            const $wrapper = $(this);
            const item = $wrapper.data("item");

            if (item.id_pres === producto.id_pres) {
              const $checkboxContainer = $wrapper.find(
                ".nota-list .demo-checkbox"
              );
              const existeCheckbox =
                $checkboxContainer.find(`input[value="${cleanNota}"]`).length >
                0;

              if (!existeCheckbox) {
                const id = `nota-${item.id_pres}-${Date.now()}`;
                const checkboxHtml = `
                <div class="col-md-6 col-sm-12 mb-2">
                  <div class="form-check">
                    <input class="form-check-input checkk chk-col-light-green" type="checkbox" id="${id}" name="checks[]" value="${cleanNota}" checked>
                    <label class="form-check-label" for="${id}">${cleanNota}</label>
                  </div>
                </div>
              `;
                $checkboxContainer.append(checkboxHtml);
                $checkboxContainer.find(`#${id}`).trigger("change");

                if (!$checkboxContainer.data("change-registered")) {
                  $checkboxContainer.on(
                    "change",
                    "input[type='checkbox']",
                    function () {
                      const seleccionadas = $checkboxContainer
                        .find("input:checked")
                        .map(function () {
                          return $(this).val().trim();
                        })
                        .get();

                      const $texto = $wrapper.find(".texto-intermedio");
                      const actualTexto = $texto.text().trim();
                      const partes = actualTexto
                        .split(",")
                        .map((p) => p.trim())
                        .filter((p) => p !== "");

                      const todasLasOpciones = $checkboxContainer
                        .find("input[type='checkbox']")
                        .map(function () {
                          return $(this).val().trim();
                        })
                        .get();

                      const notasManual = partes.filter(
                        (n) => !todasLasOpciones.includes(n)
                      );
                      const combinado = [...notasManual, ...seleccionadas].join(
                        ", "
                      );
                      $texto.text(combinado);

                      $checkboxContainer.data("seleccionadas", seleccionadas);
                    }
                  );

                  $checkboxContainer.data("change-registered", true);
                }
              }
            }
          });

          // Limpiar campo de nota manual
          $clickedWrapper.find(".nota_manual_text").val("").focus();
          $clickedWrapper.find(".nota-new").hide();
        } else {
          mostrarAlerta("Error al guardar nota", "error");
        }
      },
      error: function () {
        mostrarAlerta("Error al conectar con el servidor", "error");
      },
    });
  });

  $(document).on("click", ".agregar-nota-manual", function () {
    const $wrapper = $(this).closest(".po-item-wrapper");
    const nota = $wrapper.find(".nota_manual_text").val().trim();

    if (nota !== "") {
      const $texto = $wrapper.find(".texto-intermedio");
      const actual = $texto.text().trim();

      const combinado = actual ? actual + ", " + nota : nota;

      $texto.text(combinado);
      $wrapper.find(".nota_manual_text").val("").focus();
    }
  });

  $(document)
    .on("click", ".order-card", function () {
      // Selección única (si quieres multiselección, comenta el siguiente bloque)
      $(".order-card.is-selected")
        .removeClass("is-selected")
        .attr("aria-pressed", "false");

      $(this).addClass("is-selected").attr("aria-pressed", "true");

      // Dispara evento con id_pedido
      var id = $(this).data("order-id");
      $(document).trigger("pedido:select", { id_pedido: id });
    })
    .on("keydown", ".order-card", function (e) {
      if (e.key === "Enter" || e.key === " ") {
        e.preventDefault();
        $(this).trigger("click");
      }
    });

  // Escuchar el evento en cualquier parte
  $(document).on("pedido:select", function (e, data) {
    // data.id_pedido disponible aquí
    console.log("Seleccionado pedido id:", data.id_pedido);
    getPedido(data.id_pedido);

    // TODO: abrir modal, cargar detalle, etc.
  });

  $(document).on("click", ".cantidad .up", function () {
    var $count = $(this).prev();
    var count = parseInt($count.text());

    // --- Hard Stock Validation ---
    const $wrapper = $(this).closest(".po-item-wrapper");
    const item = $wrapper.data("item");

    if (item && item.Stock && item.Stock.crt_stock == 1 && item.Stock.ingredientes) {
      let maxStock = 0;
      try {
        // Re-fetch latest product data just in case
        const actual = Productos.find(p => p.id_pres === item.id_pres) || item;

        const ingredientes = JSON.parse(actual.Stock.ingredientes);
        const principal = ingredientes.find(i => i.principal === "si" || ingredientes.length === 1);

        if (principal) {
          if (actual.Stock.receta == 1) {
            if (parseFloat(principal.cant) > 0) {
              maxStock = Math.floor(parseFloat(principal.stock_actual) / parseFloat(principal.cant));
            }
          } else {
            maxStock = Math.floor(parseFloat(principal.stock_actual));
          }
        }

        // Calculate current total in cart (sum of all lines for this product)
        let currentInCart = 0;
        $(".po-item-wrapper").each(function () {
          const i = $(this).data("item");
          if (i && i.id_pres === item.id_pres) {
            const qty = parseInt($(this).find(".cantidad span, .cantidad .qty").not(".up, .down").text()) || 0;
            currentInCart += qty;
          }
        });

        if (currentInCart + 1 > maxStock) {
          mostrarAlerta("warning", "Stock insuficiente", `Solo quedan ${maxStock} unidades disponibles.`);
          return; // Block increment
        }

      } catch (e) { console.error("Stock check error:", e); }
    }
    // -----------------------------

    $count.text(count + 1);
    actualizarTotalesDesdeLista();
  });

  $(document).on("click", ".cantidad .down", function () {
    var $count = $(this).next();
    var count = parseInt($count.text());
    if (count > 1) {
      $count.text(count - 1);
    }
    actualizarTotalesDesdeLista();
  });

  $(document).on("click", ".agregar-precio", function (e) {
    e.stopPropagation();

    const $btn = $(this);
    const precio = $btn.data("precio");
    const id_pres = $btn.data("id_pres");
    const nombre_precio = $btn.data("price-name");

    const productoBase = Productos.find((p) => p.id_pres == id_pres);

    if (!productoBase) {
      console.warn("Producto no encontrado para id_pres:", id_pres);
      return;
    }

    const producto = {
      ...productoBase,
      pro_cos: precio,
      id_pres: id_pres,
      nombre_precio: nombre_precio,
      cantidad: 1,
    };

    const $wrapper = $btn.closest(".card-menu-wrapper");

    //const $card = $btn.closest(".card-menu-wrapper").find(".card-menu");

    if (
      producto.Stock &&
      producto.Stock.crt_stock == 1 &&
      producto.Stock.ingredientes
    ) {
      if (tieneStockDisponible(producto)) {
        agregarProducto(producto);
        actualizarStockVisual($wrapper[0], producto);
        actualizarBadgeDelProducto(producto.id_pres); // ðŸ”¥ fuerza re-render del badge
      } else {
        mostrarAlerta(
          "warning",
          "Sin stock disponible",
          "No hay stock suficiente para agregar este producto."
        );
      }
    } else {
      agregarProducto(producto);
    }

    $btn.closest(".card-menu-wrapper").find(".content").slideUp("fast");
  });

  // Unifica el flujo de "PEDIDO" y evita handlers duplicados al recargar vistas/parciales.
  $(document)
    .off("click.ventaRapidaPedido", "#btn_registrar_pedido")
    .on("click.ventaRapidaPedido", "#btn_registrar_pedido", function (e) {
      e.preventDefault();
      guardarPedido();
    });

  $("#buscar_cliente_pedido").autocomplete({
    delay: 4,
    autoFocus: true,
    appendTo: "#modal-pedidos",
    source: function (request, response) {
      $.ajax({
        url: $("#url").val() + "venta/buscar_cliente",
        type: "post",
        dataType: "json",
        data: {
          cadena: request.term,
          tipo_cliente: $("#cliente_pedido_tipo").val(),
        },
        success: function (data) {
          console.log(data);

          // Si no hay data, devolvemos un arreglo vacío.
          if (!data || data.length === 0) {
            $("#cliente_pedido_id").val(0); // Aquí asignas 0 si no hay resultados
            response([]);
            return;
          }

          // Si data no es un arreglo, lo envolvemos en uno.
          if (!Array.isArray(data)) {
            data = [data];
          }

          // Mapear los items. Se valida la existencia de propiedades y se normaliza el nombre.
          var items = $.map(data, function (item) {
            if (!item) return; // Evita errores si item es null

            // Determina el prefijo según la existencia y valor de 'ruc' o el tipo de cliente.
            // Puedes ajustar la lógica si la validación depende de otras propiedades.
            var tipo_cli =
              typeof item.ruc !== "undefined" && item.ruc
                ? $("#tribAcr").val()
                : $("#diAcr").val();

            // Normalizamos el nombre: Si 'nombre' no existe, se intenta 'nombres', luego 'razonSocial'
            var nombre = item.nombre || item.nombres || item.razonSocial || "";

            return {
              id: item.id_cliente || "",
              dni: item.dni || "",
              ruc: item.ruc || "",
              tipo: item.tipo_cliente || "",
              nombres: nombre,
              fecha_n: item.fecha_nac || "",
              label:
                tipo_cli +
                ": " +
                (item.dni || "") +
                (item.ruc || "") +
                " | " +
                nombre,
              value:
                tipo_cli +
                ": " +
                (item.dni || "") +
                (item.ruc || "") +
                " | " +
                nombre,
            };
          });

          response(items);
        },
      });
    },
    select: function (e, ui) {
      $("#cliente_pedido_id").val(ui.item.id);

      if (ui.item.tipo == 1) {
        $("#cliente_pedido_doc").val(ui.item.dni || "");
      } else {
        $("#cliente_pedido_doc").val(ui.item.ruc || "");
      }

      var nombre = ui.item.nombres || ui.item.razonSocial || "";
      $("#cliente_pedido_nombres").val(nombre);

      $(this).blur();

      $(".opcion-cliente-pedido").html(
        '<a class="input-group-prepend" href="javascript:void(0)" ' +
        'onclick="editar_cliente(' +
        ui.item.id +
        ');" data-original-title="Editar cliente" data-toggle="tooltip" ' +
        'data-placement="top">' +
        '<span class="input-group-text bg-header"><small><i class="fas fa-user text-info"></i></small></span>' +
        "</a>"
      );
    },
  });

  // Stock fresco cada vez que se abre el modal de venta rápida
  $("#modal-pedidos").on("show.bs.modal", function () {
    listarCategorias().then(function () {
      refrescarTodosLosBadgesVisibles();
    });
  });

  // --------- Eventos dentro del modal ---------
  // Búsqueda de carta
  $("#input-buscar-carta").on(
    "input",
    debounce(function () {
      renderProductosUI(filterProductosUI());
    }, 150)
  );

  // Cambiar vista grid/list
  // (por convención, el primer botón es cuadrícula, el segundo es lista)

  $(".change-mode button").on("click", function () {
    // marcar solo este botón como activo

    const idCategoriaSeleccionada = $(
      ".list-categories .card-category.selected"
    ).data("id");
    $(this)
      .addClass("btn-primary")
      .removeClass("btn-secondary")
      .siblings()
      .removeClass("btn-primary")
      .addClass("btn-secondary");

    // ver qué modo se pidió

    modoListaProductos = $(this).find(".fa-th").length ? "grid" : "list";

    listarProductos(idCategoriaSeleccionada, modoListaProductos);
  });

  // Mostrar/ocultar aside derecho en móvil
  $("#ver_seleccionados").on("click", function () {
    $(".modal-order-right").show();
  });
  //   $("#btn_close_aside").on("click", function () {
  //     $(".modal-order-right").hide();
  //   });

  $("#pago_efe, #pago_tar, #pago_yape, #pago_plin, #pago_tran").on(
    "input",
    calcularPagos
  );

  $(".venta_por_consumo").on("click", function (event) {
    if ($(this).is(":checked")) {
      $("#venta_por_consumo").val("1");
      $("#venta_por_consumo_concepto").focus();
      $("#venta_por_consumo_concepto").select();
      $("#static-list-pedidos").show();
      $("#list-pedidos").hide();
    } else {
      $("#venta_por_consumo").val("0");
      $("#static-list-pedidos").hide();
      $("#list-pedidos").show();
    }
  });

  $(".comision_tarjeta_venta").on("click", function (event) {
    console.log("Comision Tarjeta Clicked");

    let tipoPagoActual = getTipoPagoActual();
    let comision_tarjeta = 0;
    let total_tarjeta = 0;
    let porcentaje_comision_tarjeta = getPorcentajeComisionTarjetaConfig();

    let subtotal = parseMontoSeguro($(".SubtotalPedido").first().text());
    let descuento = parseMontoSeguro($(".totalDescuento").first().text());
    let delivery = parseMontoSeguro($(".totalDelivery").first().text());
    let total = getTotalPedidoActual();

    console.log(porcentaje_comision_tarjeta);

    if ($(this).is(":checked")) {
      if (tipoPagoActual !== 2) {
        const $tipoPago = $("#tipo_pago");
        const $optTarjeta = $tipoPago.find("option[label='2']").first();
        if ($optTarjeta.length) {
          $tipoPago.val($optTarjeta.val());
        } else {
          $tipoPago.prop("selectedIndex", 1);
        }
        $tipoPago.trigger("change");
        tipoPagoActual = getTipoPagoActual();
      }

      if (
        isNaN(porcentaje_comision_tarjeta) ||
        porcentaje_comision_tarjeta <= 0
      ) {
        swal.fire({
          title: "Advertencia",
          text: "Ingrese un valor v\u00e1lido para la comisi\u00f3n de tarjeta o configure el porcentaje",
          icon: "warning",
          confirmButtonColor: "#34d16e",
          confirmButtonText: "Aceptar",
          allowOutsideClick: false,
          showCancelButton: false,
          showConfirmButton: true,
        });

        return;
      }

      porcentaje_comision_tarjeta = porcentaje_comision_tarjeta / 100;

      comision_tarjeta = subtotal * porcentaje_comision_tarjeta;
      total_tarjeta = subtotal - descuento + delivery + comision_tarjeta;

      console.log("total:", total);

      $(".comisionTarjeta").text(formatNumber(comision_tarjeta));
      $(".SubtotalPedido").text(formatNumber(subtotal));
      $(".totalDescuento").text(formatNumber(descuento));
      $(".totalDelivery").text(formatNumber(delivery));
      $(".totalPedidoMenosTarjeta").text(formatNumber(total_tarjeta));

      $(".view_comision_tarjeta").show();
      $("#tipo_pago").prop("selectedIndex", 1).trigger("change");
    } else {
      console.log("total:", total);

      total_tarjeta = subtotal - descuento + delivery;

      $("#tipo_pago").prop("selectedIndex", 0).trigger("change");
      $(".view_comision_tarjeta").hide();
      $(".comisionTarjeta").text(formatNumber(0));
      $(".SubtotalPedido").text(formatNumber(subtotal));
      $(".totalDescuento").text(formatNumber(descuento));
      $(".totalDelivery").text(formatNumber(delivery));
      $(".totalPedidoMenosTarjeta").text(formatNumber(total_tarjeta));
    }
  });

  $("#btnDividirCuenta").on("click", () => {
    selectionMode ? exitSplitMode() : enterSplitMode();
  });

  /* ===== Click en producto: +1 y wrap a 0 ===== */
  $(document).on("click", ".po-item", function (e) {
    if (!selectionMode) return;
    e.preventDefault();
    e.stopPropagation();

    const $wrap = $(this).closest(".po-item-wrapper");
    const item = $wrap.data("item") || {};
    const id = $wrap.data("wrapper-id") || item.wrapperId || $wrap.index();
    const max = getMaxQty($wrap, item);

    const currentSel = splitSelection.get(id)?.qty || 0;
    const next = (currentSel + 1) % (max + 1); // si pasa el max, vuelve a 0

    const rawUnit = (
      item.pro_cos ??
      $wrap.find(".price").text() ??
      ""
    ).toString();
    const unit =
      Number(rawUnit.replace(/[^\d.,-]/g, "").replace(",", ".")) || 0;
    const subtotal = next * unit;
    $wrap.find(".price").text(subtotal.toFixed(2));

    splitSelection.set(id, { qty: next, item, unit, subtotal });

    console.log(splitSelection);

    setQtyBadge($wrap, next, max);
    setSelectedVisual($wrap, next); // pinta celeste si next > 0, quita si 0

    let totalSel = 0;
    let total = 0;
    let delivery = 0;
    let descuento = 0;
    let comision = 0;
    let tipo_pago;

    for (const v of splitSelection.values())
      totalSel += (v.qty || 0) * (v.unit || 0);

    delivery = parseFloat($(".totalDelivery").first().text()) || 0;
    descuento = parseFloat($(".totalDescuento").first().text()) || 0;
    comision = getComisionTarjetaActual();
    tipo_pago = getTipoPagoActual();

    total = totalSel - descuento + delivery + comision;

    console.log(totalSel);

    $(".SubtotalPedido").text(`${formatNumber(totalSel)}`);
    $(".totalPedidoMenosTarjeta").text(`${formatNumber(total)}`);
    if (tipo_pago == 1 || tipo_pago == 3) {
      $("#pago_efe").val(`${formatNumber(total)}`);
      actualizarVuelto();
    }

    //$(".split-total").text(`S/ ${totalSel.toFixed(2)}`);
  });

  $(document).on("click", ".po-item .remove-item", function (e) {
    e.stopPropagation();
    var $wrapper = $(this).closest(".po-item-wrapper");
    var prod = $wrapper.data("item");

    if (prod) {
      if (!prod.isNew) {
        anularPedido(
          PedidoSeleccionado.id_pedido,
          prod.id_pres,
          prod.cantidad,
          prod.pro_nom,
          prod.pro_pre,
          prod.fecha_pedido,
          prod.estado_pedido,
          $wrapper, // Pasar el elemento para eliminarlo después
          prod // Pasar los datos del producto
        );
      } else {
        //reponerStockVisual(prod);
        $wrapper
          .find(".demo-checkbox")
          .removeData("initialized")
          .removeData("seleccionadas");
        $wrapper.remove();
        actualizarTotalesDesdeLista();
        actualizarContadorPedidos();
      }
    }
  });
});

function anularPedido(
  id_pedido,
  id_pres,
  cant_ped,
  prod_nom,
  prod_pre,
  fecha_pedido,
  estado_pedido,
  $wrapperElement = null,
  prodData = null
) {
  $("#modal-pedidos").modal("hide");

  const tipo_pedido = 2;

  setTimeout(() => {
    const html = `
      <div>
        Se anulará el siguiente pedido:<br>
        <strong class="text-danger">${cant_ped} UNI</strong>
        ${prod_nom} <span class="label label-warning">${prod_pre}</span>
      </div>
      <div class="mt-3">
        <input
          id="codigo_seguridad"
          class="text-center w-50"
          type="password"
          placeholder="Código de seguridad"
          autocomplete="off"
        >
      </div>
      <div class="mt-3">
        <span class="text-success" style="font-size:17px;">
          ¿Está Usted de Acuerdo?
        </span>
      </div>
    `;

    Swal.fire({
      title: "Necesitamos de tu Confirmación",
      html,
      icon: "warning",
      showCancelButton: true,
      confirmButtonText: "Sí, anular",
      cancelButtonText: "No",
      focusConfirm: false,
      allowOutsideClick: false,
      showLoaderOnConfirm: true,
      willOpen: () => {
        setTimeout(() => {
          $("#codigo_seguridad").focus().select();
        }, 100);
      },
      preConfirm: () => {
        const code = $("#codigo_seguridad").val().trim();
        if (!code) {
          Swal.showValidationMessage(
            "Por favor ingresa el código de seguridad"
          );
          return false;
        }
        return new Promise((resolve, reject) => {
          $.ajax({
            url: $("#url").val() + "venta/pedido_delete",
            type: "POST",
            dataType: "json",
            data: {
              id_pedido,
              id_pres,
              fecha_pedido,
              estado_pedido,
              tipo_pedido,
              codigo_seguridad: code,
            },
          })
            .done((response) => resolve(response))
            .fail(() => {
              Swal.showValidationMessage(
                "Problemas con la conexión a internet"
              );
              reject();
            });
        });
      },
    }).then((response) => {
      if (response.isDismissed) {
        setTimeout(() => {
          if ($("#rol_usr").val() == 5) {
            $("#modal-pedidos").modal("show");
          } else {
            $("#modal-pedidos").modal("show");
          }
        }, 200);
        return; // El producto permanece visible
      }

      const resp = response.value;

      if (!resp) {
        console.log("Operación cancelada o sin respuesta");

        setTimeout(() => {
          if ($("#rol_usr").val() == 5) {
            $("#modal-pedidos").modal("show");
          } else {
            $("#modal-pedidos").modal("show");
          }
        }, 200);
        return; // El producto permanece visible
      }

      const codigoArr = resp.Codigo;
      const productoArr = resp.Producto;

      if (!Array.isArray(codigoArr) || !codigoArr.length) {
        Swal.fire("Error", "Respuesta inesperada del servidor", "error").then(
          () => {
            setTimeout(() => {
              if ($("#rol_usr").val() == 5) {
                $("#modal-pedidos").modal("show");
              } else {
                $("#modal-pedidos").modal("show");
              }
            }, 200);
          }
        );
        return; // El producto permanece visible
      }

      const cod = codigoArr[0].cod;
      if (cod === "0") {
        Swal.fire("Error", "El código ingresado es incorrecto", "error").then(
          () => {
            setTimeout(() => {
              if ($("#rol_usr").val() == 5) {
                $("#modal-pedidos").modal("show");
              } else {
                $("#modal-pedidos").modal("show");
              }
            }, 200);
          }
        );
        return; // El producto permanece visible
      }

      if (cod === "2") {
        Swal.fire(
          "Error",
          "El pedido está en preparación o ya preparado",
          "error"
        ).then(() => {
          setTimeout(() => {
            if ($("#rol_usr").val() == 5) {
              $("#modal-pedidos").modal("show");
            } else {
              $("#modal-pedidos").modal("show");
            }
          }, 200);
        });
        return; // El producto permanece visible
      }

      if ($wrapperElement && $wrapperElement.length && prodData) {
        reponerStockVisual(prodData);
        $wrapperElement
          .find(".demo-checkbox")
          .removeData("initialized")
          .removeData("seleccionadas");
        $wrapperElement.remove();
        actualizarTotalesDesdeLista();
        actualizarContadorPedidos();
      }

      const porImpresora = {};
      productoArr.forEach((item) => {
        const imp = item.nombre_imp;
        if (!porImpresora[imp]) porImpresora[imp] = [];
        porImpresora[imp].push(item);
      });

      Object.entries(porImpresora).forEach(([nombre_imp, items]) => {
        const pedidoPrint = {
          pedido_tipo: $("#codtipoped").val(),
          pedido_numero: $(".pedido-numero").text().trim().toUpperCase(),
          pedido_cliente: $(".pedido-cliente").text().trim(),
          pedido_mozo: $("#nombre_mozo").val(),
          correlativo_imp: correlativo_imp(),
          nombre_imp,
          nombre_pc: $("#pc_name").val(),
          codigo_anulacion: 1,
          items,
        };
        const dataEncoded = encodeURIComponent(JSON.stringify(pedidoPrint));
        const isLocal = $("#print_com").val() === "1";
        const url = isLocal
          ? `http://${$(
            "#pc_ip"
          ).val()}/imprimir/comanda.php?data=${dataEncoded}`
          : `${$("#url").val()}venta/impresion_comanda/?data=${dataEncoded}`;
        const features = isLocal
          ? "_blank"
          : "_blank,top=500,left=500,width=400,height=400";
        window.open(url, "_blank", features);
      });

      // Actualizar lista de pedidos

      // Mostrar mensaje de éxito
      Swal.fire(
        "¡Anulado!",
        "El pedido ha sido anulado correctamente.",
        "success"
      );
    });
  }, 400); // Esperar a que los modales se cierren completamente
}

function calcularPagos() {
  actualizarVuelto();
}

function reponerStockVisual(product) {
  var qty = parseFloat(product.cantidad) || 1;
  actualizarStockRuntime(product, qty, 'sumar');
}

function actualizarPrecioDescuentos() {
  let total = 0;
  const tipo_descuento = Number($("#tipo_descuento_select").val() || 0);
  const comision_delivery = parseMontoSeguro($("#comision_delivery").val());
  const subtotal = parseMontoSeguro($(".SubtotalPedido").text());
  const montoIngresado = parseMontoSeguro($("#descuento_monto_fijo").val());
  const monto_descuento = tipo_descuento === 1 ? subtotal : Math.min(montoIngresado, subtotal);
  const personalSeleccionado = parseInt($("#personal_descuento").val(), 10) || 0;
  const motivo = ($("#descuento_motivo").val() || "").trim();
  const tipoDocumento = Number($('input:radio[name="tipo_doc"]:checked').val() || 0);

  if (tipo_descuento === 1 && (tipoDocumento === 1 || tipoDocumento === 2)) {
    mostrarAlerta(
      "warning",
      "Atención",
      "No se puede aplicar cortesía con boleta o factura."
    );
    return;
  }

  if (tipo_descuento === 2 && monto_descuento <= 0) {
    mostrarAlerta("warning", "Atención", "Ingrese un monto de descuento válido.");
    return;
  }

  if (tipo_descuento === 3) {
    if (personalSeleccionado <= 0) {
      mostrarAlerta("warning", "Atención", "Seleccione el personal para crédito.");
      return;
    }
    if (monto_descuento <= 0) {
      mostrarAlerta("warning", "Atención", "Ingrese un monto de crédito válido.");
      return;
    }
  }

  $("#descuento_tipo_hidden").val(String(tipo_descuento));
  $("#descuento_monto_hidden").val(monto_descuento.toFixed(2));
  $("#descuento_motivo_hidden").val(tipo_descuento === 0 ? "" : motivo);
  $("#descuento_personal_hidden").val(
    tipo_descuento === 3 ? String(personalSeleccionado) : "0"
  );

  if (tipo_descuento === 1) {
    total = comision_delivery;
    $(".SubtotalPedido").text(`${formatNumber(0)}`);
    $("#descuento_porcentaje").val("100");
    $("#descuento_monto_fijo").val(formatNumber(monto_descuento));
  } else {
    if (tipo_descuento === 0) {
      $(".SubtotalPedido").text(`${formatNumber(subtotal)}`);
    }
    total = subtotal - monto_descuento + comision_delivery;
  }

  $(".totalDescuento").text(formatNumber(monto_descuento));
  $(".totalDelivery").text(formatNumber(comision_delivery));
  $("#pago_efe").val(formatNumber(total));
  $(".totalPedidoMenosTarjeta").text(formatNumber(total));
  actualizarVuelto();

  const dialog = document.querySelector(".dialogBtn");
  dialog.close();
}

function listarPersonal() {
  var personal = $("#personal_descuento");

  $.ajax({
    url: $("#url").val() + "venta/Personal",
    type: "POST",
    dataType: "json",
    success: function (data) {
      personal.find("option").remove();
      $(data).each(function (i, v) {
        // indice, valor
        personal.append(
          '<option value="' +
          v.id_usu +
          '">' +
          v.nombres +
          " " +
          v.ape_paterno +
          " " +
          v.ape_materno +
          "</option>"
        );
      });
    },
  });
}

var anular_pedido = function (id_pedido) {
  var html_confirm =
    '<div>Se procederá a anular este pedido</div><br>\
    <div><span class="text-success" style="font-size: 17px;">¿Está Usted de Acuerdo?</span></div>';
  Swal.fire({
    title: "Necesitamos de tu Confirmación",
    html: html_confirm,
    icon: "warning",
    showCancelButton: true,
    confirmButtonColor: "#34d16e",
    confirmButtonText: "Si, Adelante!",
    cancelButtonText: "No!",
    showLoaderOnConfirm: true,
    preConfirm: function () {
      return new Promise(function (resolve) {
        $.ajax({
          url: $("#url").val() + "venta/anular_pedido",
          type: "POST",
          data: {
            id_pedido: id_pedido,
            tipo_pedido: 2,
          },
          dataType: "json",
        })
          .done(function (response) {
            mostrarAlerta(
              "success",
              "Pedido Cancelado",
              "El pedido se cancelo correctamente."
            );

            fin_venta();

            resolve();
          })
          .fail(function () {
            Swal.fire(
              "Oops...",
              "Problemas con la conexión a internet!",
              "error"
            );
          });
      });
    },
    allowOutsideClick: false,
  });
};

function iniciarModalPedido() {
  exitSplitMode();
  $("#cliente_pedido_id").val(1);
  $("#buscar_cliente_pedido").val("DNI: 00000000 | PUBLICO EN GENERAL");
  $("#tipo_pago").prop("selectedIndex", 0).trigger("change");

  // focus:false evita que Bootstrap bloquee el foco de inputs en overlays externos (SweetAlert)
  $("#modal-pedidos").modal({ show: true, focus: false });

  // FORCE PHASE 1 FOR NEW ORDERS
  // If PedidoSeleccionado is an array (empty or new items), it's a new order.
  if (Array.isArray(PedidoSeleccionado)) {
    activateOptionsPedido(0);

    // Double enforcement
    $("#btn_registrar_pedido").removeClass("d-none").css("display", "");

    $("#btnCobrar").addClass("d-none").css("display", "none");
    $("#btn_entregado").addClass("d-none").css("display", "none");

    $("#btn_anular_venta").addClass("d-none").css("display", "none");
    $("#btnDividirCuenta").addClass("d-none").css("display", "none");
    $("#openDialog").addClass("d-none").css("display", "none");
  }
}

var limpiar_pagos_a = function () {
  $("#pago_efe").val("0.00");
  $("#pago_tar").val("0.00");
  $("#pago_yape").val("0.00");
  $("#pago_plin").val("0.00");
  $("#pago_tran").val("0.00");
  $("#vuelto").text("0.00");
};

function limpiar_resumen_pago_rapido() {
  $(".SubtotalPedido").text("0.00");
  $(".totalDescuento").text("0.00");
  $(".totalDelivery").text("0.00");
  $(".totalPedidoMenosTarjeta").text("0.00");
  $(".comisionTarjeta").text("0.00");
  $("#total_venta").val("0.00");
  $("#cod_voucher_new").val("");
  $("#btnCobrar").prop("disabled", false);
  limpiar_pagos_a();
}

function actualizarStockVisual(wrapperEl, item) {
  var qty = parseFloat(item.cantidad) || 1;
  actualizarStockRuntime(item, qty, 'restar');
}

function extraerDataDetalle() {
  var productos = [];
  var total = 0;
  var pedidoExistente =
    PedidoSeleccionado &&
    PedidoSeleccionado.id_pedido &&
    parseInt(PedidoSeleccionado.id_pedido, 10) > 0;

  $(".po-items .po-item-wrapper").each(function () {
    var prod = $(this).data("item");

    // En pedidos existentes solo enviamos nuevos items para evitar duplicados.
    // En pedidos nuevos, aceptamos todos los items visibles.
    if (pedidoExistente && !prod.isNew) {
      return;
    }

    var precio = parseFloat(prod.pro_cos) || 0;
    prod.quantity =
      parseInt($(this).find(".cantidad span").eq(1).text(), 10) || 1;
    var comentarios = $(this).find(".texto-intermedio").text().trim();
    prod.comentarios = comentarios;
    total += precio * prod.quantity;

    productos.push(prod);
  });

  return {
    cod_ped: PedidoSeleccionado.id_pedido ? PedidoSeleccionado.id_pedido : "0",
    codtipoped: 2,
    igv: (total * 0.1).toFixed(2),
    items: convertirItems(productos),
    subtotal: (total - total * 0.1).toFixed(2),
    total: total.toFixed(2),
  };
}

function convertirItems(itemsOriginales) {
  return itemsOriginales.map(function (item, index) {
    var area_id = parseInt(item.id_areap, 10);
    var cantidad = item.quantity;
    var comentario = item.comentarios || "";
    var id = index;
    var nombre_imp =
      item.Impresora && item.Impresora.nombre ? item.Impresora.nombre : "";
    var nombreprecio = item.nombre_precio;
    var precio = item.pro_cos;
    var presentacion = item.pro_pre;
    var producto = item.pro_nom;
    var producto_id = parseInt(item.id_pres, 10);
    var total = (parseFloat(precio) * cantidad).toFixed(2);

    return {
      area_id: area_id,
      cantidad: cantidad,
      comentario: comentario,
      id: id,
      nombre_imp: nombre_imp,
      nombreprecio: nombreprecio,
      precio: precio,
      presentacion: presentacion,
      producto: producto,
      producto_id: producto_id,
      total: total,
    };
  });
}

function dataPedido() {
  return {
    id_mozo: $("#select_mozo option:selected").text(),
    nomb_cliente: ($("#buscar_cliente_pedido").val() || "")
      .trim()
      .replace(/^[^|]*\|\s*/, ""),
    nro_personas: 1,
    cliente_id: $("#cliente_pedido_id").val(),
    id_repartidor: 0,
    tipo_entrega: 1,
    pedido_programado: 0,
    telefono_cliente: "0000",
    direccion_cliente: "-",
    referencia_cliente: "-",
    id_tdoc: 1,
    num_cliente: "00000000",
    canal: "1",
  };
}

let isSubmitting = false;

function guardarPedido() {
  const $btnMaster = $("#btnAccionMaster");
  const $btnPedido = $("#btn_registrar_pedido");

  if (isSubmitting) return;
  isSubmitting = true;

  // 1) Desactivar los disparadores de guardado para evitar doble submit
  $btnMaster.prop("disabled", true);
  $btnPedido.prop("disabled", true);

  let detalle = extraerDataDetalle();
  let pedido = dataPedido();
  let tipo_pedido = "pc2";

  if (!detalle.items || detalle.items.length === 0) {
    mostrarAlerta(
      "warning",
      "Sin productos",
      "Debe agregar productos al pedido."
    );
    isSubmitting = false;
    $btnMaster.prop("disabled", false);
    $btnPedido.prop("disabled", false);
    return;
  }

  $.ajax({
    dataType: "JSON",
    type: "POST",
    data: {
      codtipoped: tipo_pedido,
      pedido: pedido,
      detalle: detalle,
      canal: "venta_rapida",
    },
    url: $("#url").val() + "venta/pedido_create",
    success: function (data) {
      console.log("Respuesta del servidor:", data);

      if (data.status == "error") {
        console.error("Error al guardar pedido:", data);
        return;
      }

      $("#modal-super-test").modal("hide");
      vaciarListaProductos();

      getPedidos();
      getPedido(data.pedido_id);

      let falloImpresion = false;
      if ($("#impresion_automatica_comanda").val() == 1) {
        try {
          imprimirComanda(pedido, 2, detalle.items, data.pedido_id);
        } catch (e) {
          console.error("Error al imprimir comanda:", e);
          falloImpresion = true;
          mostrarAlerta(
            "warning",
            "Pedido creado",
            "El pedido se guardó, pero hubo un problema al imprimir la comanda."
          );
        }
      }

      if (!falloImpresion) {
        mostrarAlerta(
          "success",
          "Pedido creado",
          "El pedido se creó correctamente."
        );
      }
    },
    error: function (xhr, status, error) {
      console.error("Error al guardar pedido:", error);
    },
    complete: function () {
      isSubmitting = false;
      $btnMaster.prop("disabled", false);
      $btnPedido.prop("disabled", false);
    },
  });
}

// function get_json_pedidos() {
//   const id_pres_array = [];
//   const precios_array = [];
//   const cantidades_array = [];

//   $(".po-items .po-item-wrapper").each(function () {
//     const $w = $(this);
//     const data = $w.data("item") || {};

//     // ID de la presentación
//     const id_pres = parseInt(data.id_pres ?? 0);

//     // Precio unitario: lo guardas en data.pro_cos, si no lo leemos del DOM
//     const precio =
//       parseFloat(
//         (data.pro_cos ?? "") ||
//           $w
//             .find(".price")
//             .text()
//             .replace(/[^\d.,-]/g, "")
//             .replace(",", ".")
//       ) || 0;

//     // Cantidad, depende del modo selección
//     let cantidad = 0;
//     if (window.selectionMode) {
//       // En modo selección, buscamos el texto tipo "2/5" en .selection-counter
//       const counterText = $w.find(".selection-counter").text().trim(); // Ej: "2/3"
//       const match = counterText.match(/^(\d+)\//);
//       cantidad = match ? parseInt(match[1]) : 0;
//     } else {
//       // En modo normal: cantidad completa
//       const qtyText = $w.find(".cantidad span").eq(1).text().trim(); // span central
//       cantidad = parseInt(qtyText) || parseInt(data.cantidad ?? 0) || 0;
//     }

//     id_pres_array.push(Number.isFinite(id_pres) ? id_pres : 0);
//     precios_array.push(Number.isFinite(precio) ? precio : 0);
//     cantidades_array.push(Number.isFinite(cantidad) ? cantidad : 0);
//   });

//   return {
//     id_pres: id_pres_array,
//     precios: precios_array,
//     cantidades: cantidades_array,
//   };
// }

function get_json_pedidos() {
  const id_pres_array = [];
  const precios_array = [];
  const cantidades_array = [];

  $(".po-items .po-item-wrapper").each(function () {
    const $w = $(this);
    const data = $w.data("item") || {};

    // ID de la presentación
    const id_pres = parseInt(data.id_pres ?? 0);

    // Precio unitario (data.pro_cos o DOM)
    const precio =
      parseFloat(
        (data.pro_cos ?? "") ||
        $w
          .find(".price")
          .text()
          .replace(/[^\d.,-]/g, "")
          .replace(",", ".")
      ) || 0;

    // ==== CANTIDAD (adaptado al modo seleccionar con badge en el mismo span) ====
    let cantidad = 0;

    // span central [down][qty][up] o .qty si existe
    const $qtySpan = $w.find(".cantidad .qty").length
      ? $w.find(".cantidad .qty")
      : $w.find(".cantidad span").eq(1);

    const txt = ($qtySpan.text() || "").trim(); // "2/5" o "3"

    if (window.selectionMode) {
      // Si hay selección en memoria, úsala
      const wrapperId = $w.data("wrapper-id") || data.wrapperId || $w.index();
      const entry =
        window.splitSelection && typeof window.splitSelection.get === "function"
          ? window.splitSelection.get(wrapperId)
          : null;

      if (entry && Number.isFinite(entry.qty)) {
        cantidad = entry.qty;
      } else {
        // Fallback: leer del span "sel/max" o número simple
        const m = txt.match(/^(\d+)\s*(?:\/\s*\d+)?$/);
        cantidad = m ? parseInt(m[1], 10) : 0;
      }
    } else {
      // Modo normal: número del span o data.cantidad
      const m = txt.match(/^(\d+)\s*(?:\/\s*\d+)?$/);
      cantidad = m ? parseInt(m[1], 10) : parseInt(data.cantidad ?? 0, 10) || 0;
    }
    // ==== FIN CANTIDAD ====

    id_pres_array.push(Number.isFinite(id_pres) ? id_pres : 0);
    precios_array.push(Number.isFinite(precio) ? precio : 0);
    cantidades_array.push(Number.isFinite(cantidad) ? cantidad : 0);
  });

  return {
    id_pres: id_pres_array,
    precios: precios_array,
    cantidades: cantidades_array,
  };
}

function procesarData() {
  if (!PedidoSeleccionado && PedidoSeleccionado.length < 0) {
    mostrarAlerta(
      "warning",
      "Pedido no seleccionado",
      "Seleccione un pedido para continuar"
    );
  }

  var current_invoices = parseInt($("#current_invoices").val());
  var limits_invoices = parseInt($("#limits_invoices").val());
  var locked_invoices = parseInt($("#locked_invoices").val());

  const clienteId = $("#cliente_pedido_id").val() || 0;
  const clienteDoc = $("#cliente_pedido_doc").val().trim();
  const descuentoTipo = $("#descuento_tipo_hidden").val() || 0;
  const tipoPago = getTipoPagoActual();
  const totalPedido = getTotalPedidoActual();
  const pagoEfe = Number($("#pago_efe").val());
  const tipoDocumento = $("input[name=tipo_doc]:checked").val();
  const tipo_descuento = $("#tipo_descuento_select").val();
  const descuentoTipoNum = Number(descuentoTipo || tipo_descuento || 0);
  const descuentoMonto = parseMontoSeguro(
    $("#descuento_monto_hidden").val() || $("#descuento_monto_fijo").val()
  );
  const descuentoPersonal = parseInt(
    $("#descuento_personal_hidden").val() || $("#personal_descuento").val(),
    10
  ) || 0;
  const comisionTarjetaEnviar =
    tipoPago === 2 && $(".comision_tarjeta_venta").is(":checked")
      ? parseMontoSeguro($(".comisionTarjeta").text())
      : 0;

  const total = Number(
    $(".totalPagar .text span")
      .text()
      .replace(/[^\d.,]/g, "")
  );

  const detalles = get_json_pedidos();

  if (tipoDocumento == undefined || tipoDocumento === "undefined") {
    mostrarAlerta("error", "Advertencia", "Seleccione un tipo de documento");
    return;
  }

  if (tipoDocumento == 2 && clienteDoc.length !== 11) {
    mostrarAlerta(
      "warning",
      "Advertencia",
      "Ingrese un RUC valido para su factura"
    );
    return;
  }

  if (clienteId === "") {
    mostrarAlerta(
      "warning",
      "Advertencia",
      "Ingrese un cliente para el comprobante de pago"
    );
    return;
  }

  if (descuentoTipo !== "1" && tipoPago === 1 && totalPedido > pagoEfe) {
    mostrarAlerta(
      "warning",
      "Advertencia",
      "Ingrese un monto mayor o igual al total"
    );
    return;
  }

  if (descuentoTipoNum === 2 && descuentoMonto <= 0) {
    mostrarAlerta(
      "warning",
      "Advertencia",
      "Debe ingresar un monto válido para el descuento."
    );
    return;
  }

  if (descuentoTipoNum === 3) {
    if (descuentoPersonal <= 0) {
      mostrarAlerta(
        "warning",
        "Advertencia",
        "Debe seleccionar el personal para crédito."
      );
      return;
    }
    if (descuentoMonto <= 0) {
      mostrarAlerta(
        "warning",
        "Advertencia",
        "Debe ingresar un monto válido para crédito personal."
      );
      return;
    }
  }

  if (current_invoices >= limits_invoices && locked_invoices == "1") {
    mostrarAlerta(
      "error",
      "Alcanzó el límite",
      "Alcanzó el límite permitido para la emisión de comprobantes"
    );
    return;
  }

  if (totalPedido == 0 && selectionMode) {
    mostrarAlerta(
      "warning",
      "Pedido Vacio",
      "Debe seleccionar un producto para continuar"
    );
    return;
  }

  const venta = {
    tipo_pedido: PedidoSeleccionado.id_tipo_pedido ?? "2",
    tipo_entrega: PedidoSeleccionado.tipo_entrega ?? 0,
    dividir_cuenta: selectionMode ? 2 : 1,
    id_pedido: parseInt(PedidoSeleccionado.id_pedido) ?? 0,
    cliente_id: clienteId,
    tipo_doc: tipoDocumento,
    tipo_pago: tipoPago,
    pago_efe: $("#pago_efe").val(),
    pago_tar: $("#pago_tar").val(),
    pago_yape: $("#pago_yape").val(),
    pago_plin: 0,
    pago_tran: 0,
    ibcper: 0,
    descuento_tipo: descuentoTipoNum,
    descuento_personal: descuentoPersonal,
    descuento_monto:
      $("#descuento_monto_hidden").val() ||
      $("#descuento_monto_fijo").val() ||
      0,
    descuento_motivo:
      $("#descuento_motivo_hidden").val() || $("#descuento_motivo").val() || "",
    comision_tarjeta: comisionTarjetaEnviar,
    comision_delivery: $("#comision_delivery").val() || 0,
    codigo_operacion: "",
    venta_por_consumo: $(".venta_por_consumo").val() || 0,
    venta_por_consumo_concepto: "POR CONSUMO",
    observacion: $("#observacion").val() || "",
    total: getTotalPedidoActual(),
    idProd: detalles.id_pres,
    cantProd: detalles.cantidades,
    precProd: detalles.precios,
  };

  console.log(venta);
  registrarVenta(venta);
}

function liberarFocusTrapModalPedidos() {
  const $modal = $("#modal-pedidos");
  if (!$modal.length || !$modal.hasClass("show")) {
    return function () {};
  }

  const modalInstance = $modal.data("bs.modal");
  if (!modalInstance) {
    return function () {};
  }

  const originalEnforce =
    typeof modalInstance._enforceFocus === "function"
      ? modalInstance._enforceFocus
      : typeof modalInstance.enforceFocus === "function"
        ? modalInstance.enforceFocus
        : null;

  // Libera temporalmente el atrapado de foco del modal Bootstrap.
  $(document).off("focusin.bs.modal");

  return function restore() {
    if (!originalEnforce || !$modal.hasClass("show")) return;
    try {
      originalEnforce.call(modalInstance);
    } catch (e) {
      // Sin impacto funcional: si no se puede restaurar, el flujo continúa.
    }
  };
}

function registrarVenta(venta) {
  $("#loading-overlay").show(); // antes del $.ajax
  $("#btnCobrar").prop("disabled", true);

  $.ajax({
    dataType: "JSON",
    type: "POST",
    url: $("#url").val() + "venta/RegistrarVenta",
    data: venta,
    success: function (data) {
      console.log(data);

      //limpiarDescuentos();
      var cod_ven = data.replace(/['"]+/g, "");
      var urlticketreparto =
        $("#url").val() + "venta/impresion_reparto/" + cod_ven;
      var tipoDocSeleccionado = Number(
        venta.tipo_doc || $("input[name=tipo_doc]:checked").val() || 0
      );
      var autoImpresionCpeActiva = $("#print_cpe").val() == 1;
      var shouldAutoPrintCpe = autoImpresionCpeActiva && tipoDocSeleccionado !== 3;

      // Construcción del iframe según verpdf
      var Urlpdfiframe, withmodal, cantcolumn;
      if ($("#verpdf").val() == 1) {
        Urlpdfiframe =
          '<div class="col-6 col-md-6 hidden-md-down"><iframe src="' +
          $("#url").val() +
          "informe/venta_all_imp/" +
          cod_ven +
          '#toolbar=0" style="border:none;width: 100%;height: 100%;"></iframe></div>';
        withmodal = 800;
        cantcolumn = 6;
      } else {
        Urlpdfiframe = "";
        withmodal = 400;
        cantcolumn = 12;
      }

      // Construcción de enlaces según print_cpe
      var linkpdf, linkpdff, linkpdfview, linkpdfviewf, linkrep, linkrepp, linkgaveta, linkgavetap;
      if ($("#print_cpe").val() == 1) {
        // imprimir directo
        linkpdf =
          '<a href="' +
          $("#url").val() +
          "informe/venta_all_imp_/" +
          cod_ven +
          '" target="_blank" class="link"><i class="fas fa-print text-muted"></i></a>';
        linkpdff =
          '<a class="link" href="' +
          $("#url").val() +
          "informe/venta_all_imp_/" +
          cod_ven +
          '" target="_blank"><small>Imprimir comprobante</small></a>';
        linkpdfview =
          '<a href="' +
          $("#url").val() +
          "informe/venta_all_imp/" +
          cod_ven +
          '" target="_blank" class="link"><i class="fas fa-file-pdf text-danger"></i></a>';
        linkpdfviewf =
          '<a class="link" href="' +
          $("#url").val() +
          "informe/venta_all_imp/" +
          cod_ven +
          '" target="_blank"><small>Abrir PDF</small></a>';
        linkrep =
          '<a class="link" href="' +
          $("#url").val() +
          "venta/impresion_reparto/" +
          cod_ven +
          '" target="_blank"><i class="fas fa-print text-muted"></i></a>';
        linkrepp =
          '<a class="link" href="' +
          $("#url").val() +
          "venta/impresion_reparto/" +
          cod_ven +
          '" target="_blank"><small>Ticket reparto</small></a>';
        linkgaveta =
          '<a class="link" href="' +
          $("#url").val() +
          'imprimir/gaveta.php" target="_blank"><i class="fas fa-print text-muted"></i></a>';
        linkgavetap =
          '<a class="link" href="' +
          $("#url").val() +
          'imprimir/gaveta.php" target="_blank"><small>GAVETA</small></a>';
      } else {
        console.log("else");

        // vista previa
        linkrep =
          '<a class="link" onclick="printPdf(\'' +
          urlticketreparto +
          '\',true);" href="javascript:void(0)"><i class="fas fa-print text-muted"></i></a>';
        linkrepp =
          '<a class="link" onclick="printPdf(\'' +
          urlticketreparto +
          '\',true);" href="javascript:void(0)"><small>Ticket reparto</small></a>';
        linkpdf =
          '<a href="' +
          $("#url").val() +
          "informe/venta_all_imp_/" +
          cod_ven +
          '" target="_blank" class="link"><i class="fas fa-print text-muted"></i></a>';
        linkpdff =
          '<a class="link" href="' +
          $("#url").val() +
          "informe/venta_all_imp_/" +
          cod_ven +
          '" target="_blank"><small>Imprimir comprobante</small></a>';
        linkpdfview =
          '<a href="' +
          $("#url").val() +
          "informe/venta_all_imp/" +
          cod_ven +
          '" target="_blank" class="link"><i class="fas fa-file-pdf text-danger"></i></a>';
        linkpdfviewf =
          '<a class="link" href="' +
          $("#url").val() +
          "informe/venta_all_imp/" +
          cod_ven +
          '" target="_blank"><small>Abrir PDF</small></a>';
        linkgaveta =
          '<a class="link" href="' +
          $("#url").val() +
          'imprimir/gaveta.php" target="_blank"><i class="fas fa-print text-muted"></i></a>';
        linkgavetap =
          '<a class="link" href="' +
          $("#url").val() +
          'imprimir/gaveta.php" target="_blank"><small>GAVETA</small></a>';
      }

      // Montaje del HTML del modal (tal cual lo tenías)
      var html_confirm;
      if (PedidoSeleccionado.id_tipo_pedido == 3) {
        html_confirm =
          '<div class="row"> <div class="col-' +
          cantcolumn +
          " col-md-" +
          cantcolumn +
          '">' +
          '<div class="text-center p-20"><i class="fas fa-check-circle display-3 text-success"></i>' +
          '<h4 class="m-t-20 font-bold">&iexcl;Venta completada!</h4></div>' +
          '<div class="card-body text-center">' +
          '<div class="row">' +
          '<div class="col-6 text-center">' +
          '<h1 class="font-light m-b-0">' +
          linkpdf +
          "</h1>" +
          linkpdff +
          "</div>" +
          '<div class="col-6 text-center">' +
          '<h1 class="font-light m-b-0">' +
          linkpdfview +
          "</h1>" +
          linkpdfviewf +
          "</div>" +
          '<div class="col-6 text-center">' +
          '<h1 class="font-light m-b-0">' +
          linkgaveta +
          "</h1>" +
          linkgavetap +
          "</div>" +
          '<div class="col-6 text-center">' +
          '<h1 class="font-light m-b-0">' +
          linkrep +
          "</h1>" +
          linkrepp +
          "</div>" +
          "</div>" +
          '<div class="row mt-5">' +
          '<div class="col-12 text-center">' +
          '<span class="mb-2 text-center" style="display: block;">Enviar comprobante por WhatsApp</span>' +
          '<div class="input-group" style="position:relative;z-index:30;">' +
          '<div class="input-group-prepend">' +
          '<span class="input-group-text">N&ordm;</span>' +
          "</div>" +
          '<input type="text" id="numero_cliente" value="51" class="form-control" placeholder="51999999999" inputmode="numeric" autocomplete="tel" autocapitalize="off" spellcheck="false" aria-label="Número de WhatsApp" style="position:relative;z-index:20;pointer-events:auto;">' +
          '<div class="input-group-append">' +
          '<button class="btn btn-success" type="button" id="button-addon2" disabled onclick="clickSendWhatsapp(\'' +
          cod_ven +
          '\');">enviar <i class="fab fa-whatsapp"></i></button>' +
          '<span class="input-group-text wsp-status-dot-wrap"><i id="wsp-status" class="fas fa-circle text-secondary" title="No enviado a&uacute;n"></i></span>' +
          "</div>" +
          "</div>" +
          "</div>" +
          "</div>" +
          "</div>" +
          "</div>" +
          Urlpdfiframe +
          "</div>";
      } else {
        html_confirm =
          '<div class="row"> <div class="col-' +
          cantcolumn +
          " col-md-" +
          cantcolumn +
          '">' +
          '<div class="text-center p-20"><i class="fas fa-check-circle display-3 text-success"></i>' +
          '<h4 class="m-t-20 font-bold">&iexcl;Venta completada!</h4></div>' +
          '<div class="card-body text-center">' +
          '<div class="row">' +
          '<div class="col-12 text-center">' +
          '<h1 class="font-light m-b-0">' +
          linkpdf +
          "</h1>" +
          linkpdff +
          "</div>" +
          '<div class="col-12 text-center">' +
          '<h1 class="font-light m-b-0">' +
          linkpdfview +
          "</h1>" +
          linkpdfviewf +
          "</div>" +
          '<div class="col-12 text-center">' +
          '<h1 class="font-light m-b-0">' +
          linkgaveta +
          "</h1>" +
          linkgavetap +
          "</div>" +
          "</div>" +
          '<div class="row mt-5">' +
          '<div class="col-12 text-center">' +
          '<span class="mb-2 text-center" style="display: block;">Enviar comprobante por WhatsApp</span>' +
          '<div class="input-group" style="position:relative;z-index:30;">' +
          '<div class="input-group-prepend">' +
          '<span class="input-group-text">N&ordm;</span>' +
          "</div>" +
          '<input type="text" id="numero_cliente" value="51" class="form-control" placeholder="51999999999" inputmode="numeric" autocomplete="tel" autocapitalize="off" spellcheck="false" aria-label="Número de WhatsApp" style="position:relative;z-index:20;pointer-events:auto;">' +
          '<div class="input-group-append">' +
          '<button class="btn btn-success" type="button" id="button-addon2" disabled onclick="clickSendWhatsapp(\'' +
          cod_ven +
          '\');">enviar <i class="fab fa-whatsapp"></i></button>' +
          '<span class="input-group-text wsp-status-dot-wrap"><i id="wsp-status" class="fas fa-circle text-secondary" title="No enviado a&uacute;n"></i></span>' +
          "</div>" +
          "</div>" +
          "</div>" +
          "</div>" +
          "</div>" +
          "</div>" +
          Urlpdfiframe +
          "</div>";
      }

      const initWhatsappInputModal = function () {
        const $input = $("#numero_cliente");
        if (!$input.length) return;

        // Fallback robusto para distintas versiones de SweetAlert y estilos heredados.
        const numeroActual = (($input.val() || "51") + "")
          .replace(/\D+/g, "")
          .slice(0, 11);
        const valorNormalizado = numeroActual.length >= 2 ? numeroActual : "51";

        $input
          .prop("readonly", false)
          .prop("disabled", false)
          .removeAttr("readonly")
          .removeAttr("disabled")
          .css({
            pointerEvents: "auto",
            userSelect: "text",
            WebkitUserSelect: "text",
            backgroundColor: "#fff",
          });

        $input.val(valorNormalizado);
        $input.trigger("input");

        $("#button-addon2").prop("disabled", valorNormalizado.length !== 11);
        updateWspStatusDot("idle");
        showWspInlineFeedback("clear", "");

        // Evita que el visor PDF capture clics encima del formulario de WhatsApp.
        $(".swal2-popup iframe").css("pointer-events", "none");

        setTimeout(function () {
          const input = $input.get(0);
          if (!input) return;
          input.focus();
          const pos = valorNormalizado.length;
          if (typeof input.setSelectionRange === "function") {
            input.setSelectionRange(pos, pos);
          }
        }, 60);
      };

      const restoreFocusTrap = liberarFocusTrapModalPedidos();

      Swal.fire({
        html: html_confirm,
        width: withmodal,
        footer:
          '<div><a class="btn btn-orange" href="#" onclick="fin_venta(); Swal.close();">Continuar <i class="fas fa-arrow-right"></i></a></div>',
        allowOutsideClick: false,
        allowEscapeKey: false,
        showCancelButton: false,
        showConfirmButton: false,
        didOpen: initWhatsappInputModal,
        onOpen: initWhatsappInputModal,
        didClose: restoreFocusTrap,
        onClose: restoreFocusTrap,
      });
      setTimeout(initWhatsappInputModal, 120);

      if (shouldAutoPrintCpe) {
        window.open($("#url").val() + "informe/venta_all_imp_/" + cod_ven, "_blank");
      }
      $("#loading-overlay").hide();
      $(".venta_por_consumo").prop("checked", false).triggerHandler("click");
      $("#btnCobrar").prop("disabled", false);
    },
    error: function (xhr, status, error) {
      console.error("Error al guardar pedido:", error);
      $("#btnCobrar").prop("disabled", false);
      $("#loading-overlay").hide();
    },
  });
}

function money(n) {
  return "S/ " + Number(n || 0).toFixed(2);
}

// function timeAgo(ts){
//   const m = Math.floor((Date.now() - ts)/60000);
//   if (m<=0) return 'ahora'; if (m===1) return 'hace 1 min';
//   if (m<60) return `hace ${m} min`;
//   const h = Math.floor(m/60); return h===1 ? 'hace 1 h' : `hace ${h} h`;
// }

function fin_venta() {
  console.log("fin_venta");
  PedidoSeleccionado = [];
  selectionMode = false;
  vaciarListaProductos();
  limpiar_resumen_pago_rapido();
  getPedidos();
  $("#modal-pedidos").modal("hide");
  $("#comision_tarjeta_venta").prop("checked", false);
  activateOptionsPedido(0);
}

const timeAgo = (iso) => {
  const dt = new Date(iso.replace(" ", "T"));
  if (isNaN(dt)) return "-";
  const diff = (Date.now() - dt.getTime()) / 1000;
  if (diff < 60) return "hace segundos";
  if (diff < 3600) return `hace ${Math.floor(diff / 60)} min`;
  if (diff < 86400) return `hace ${Math.floor(diff / 3600)} h`;
  return dt.toLocaleString("es-PE");
};

function debounce(fn, wait) {
  let t;
  return (...a) => {
    clearTimeout(t);
    t = setTimeout(() => fn(...a), wait);
  };
}

// function showToast(message, variant = 'dark') {
//   const $t = $('#toast');
//   $t.removeClass('bg-dark bg-success bg-danger bg-info text-white border-0')
//     .addClass('bg-' + variant + ' text-white border-0');
//   $('#toast-body').text(message);
//   $t.toast('show');
// }

function showToast(message, icon = "info") {
  Swal.fire({
    toast: true,
    position: "top-end",
    icon,
    title: message,
    showConfirmButton: false,
    timer: 3000,
    timerProgressBar: true,
    background: "#f0f0f0",
    customClass: {
      popup: "shadow rounded-lg",
    },
  });
}

function activateOptionsPedido(flag, estado_pedido = "b") {
  const grupoB = $(".sub-total, .total");
  const $masterBtn = $("#btnAccionMaster");

  // Helper to config master button
  const setMaster = (text, iconClass, btnClass, action) => {
    $masterBtn.find("span").text(text);
    $masterBtn.find("i").attr("class", iconClass);
    $masterBtn.removeClass("btn-primary btn-success-modern btn-danger")
      .addClass(btnClass);
    $masterBtn.data("action", action);

    if (!action) $masterBtn.addClass("d-none");
    else $masterBtn.removeClass("d-none");
  };

  $("#botones_pedido").removeClass("hide-force");

  // Ensure legacy buttons are always hidden
  $("#btn_registrar_pedido").addClass("d-none");
  $("#btnCobrar").addClass("d-none");
  $("#btn_entregado").addClass("d-none");

  if (flag === 0) {
    // FASE 1: NUEVO PEDIDO -> PEDIDO
    $("#content_pagos").css("display", "none");

    // Show container but hide specific payment/doc sections, keeping Client/Mozo visible
    $(".tipo_documento").css("display", "");
    $(".tipo_documento .btn-group, .tipo_documento .controls-row").css("display", "none");

    $masterBtn.removeClass("d-none");

    setMaster("PEDIDO", "fas fa-save mr-2 fa-lg", "btn-primary", "#btn_registrar_pedido");

    $("#btn_anular_venta").addClass("d-none");
    $("#btnDividirCuenta").addClass("d-none");
    $("#openDialog").addClass("d-none");

    grupoB.css("display", "");
  } else if (flag === 1) {
    // FASE 2 & 3: PEDIDO EXISTENTE
    $("#content_pagos").css("display", "");

    // Show container but HIDE specific payment/doc sections by default (enable only for Cobrar)
    $(".tipo_documento").css("display", "");
    $(".tipo_documento .btn-group, .tipo_documento .controls-row").css("display", "none");

    grupoB.css("display", "none");

    if (estado_pedido == "c") {
      // FASE 3: PAGADO -> ENTREGADO
      setMaster("ENTREGADO", "fas fa-box-open mr-2 fa-lg", "btn-success-modern", "#btn_entregado");

      $("#btn_anular_venta").addClass("d-none");
      $("#btnDividirCuenta").addClass("d-none");
      $("#openDialog").addClass("d-none");
    } else if (estado_pedido == "b") {
      // FASE 2: EN PREPARACION -> COBRAR
      $(".tipo_documento .btn-group, .tipo_documento .controls-row").css("display", ""); // SHOW ONLY HERE
      setMaster("COBRAR", "fas fa-check-circle mr-2 fa-lg", "btn-success-modern", "#btnCobrar");

      $("#btn_anular_venta").removeClass("d-none").css("display", "flex").prop("disabled", false);
      $("#btnDividirCuenta").removeClass("d-none").css("display", "flex").prop("disabled", false);
      $("#openDialog").removeClass("d-none").css("display", "flex").prop("disabled", false);
    } else if (estado_pedido == "dirty") {
      // FASE INTERMEDIA: CAMBIOS SIN GUARDAR -> FORZAR "PEDIDO"
      setMaster("PEDIDO", "fas fa-save mr-2 fa-lg", "btn-primary", "#btn_registrar_pedido");

      // Hide secondary actions to force save
      $("#btn_anular_venta").addClass("d-none").css("display", "none");
      $("#btnDividirCuenta").addClass("d-none").css("display", "none");
      $("#openDialog").addClass("d-none").css("display", "none");
    } else if (estado_pedido == "d") {
      // FINALIZADO -> OCULTAR TODO
      $("#botones_pedido").addClass("hide-force");
      $masterBtn.addClass("d-none");
    }
  }
}

// Master Button Listener (Proxy Clicker)
// Ensure this listener is attached only once by using .off()
$(document).off("click", "#btnAccionMaster").on("click", "#btnAccionMaster", function (e) {
  e.preventDefault();

  // Anti-Double Click
  const $btn = $(this);
  if ($btn.prop("disabled")) return;

  $btn.prop("disabled", true);
  setTimeout(() => {
    $btn.prop("disabled", false);
  }, 2000); // 2 second lockout

  const actionSelector = $(this).data("action");
  if (actionSelector && $(actionSelector).length) {
    // console.log("Master Button proxying click to:", actionSelector);
    $(actionSelector).trigger("click");
  }
});

function vaciarListaProductos() {
  splitSelection.clear();
  $(".po-items").empty();
  subtotal = 0;
  igv = 0;
  total = 0;

  $(".sub-total div:eq(0) span:eq(1)").text("S/0.00");
  $(".sub-total div:eq(1) span:eq(1)").text("S/0.00");
  $(".total span:eq(1)").text("S/0.00");
  limpiar_resumen_pago_rapido();
}

// Compatibilidad con flujo de impresión de venta/venta_orden.
// En Venta Rápida no siempre está cargado venta_all.js (donde también existe esta función).
function correlativo_imp() {
  var contador_impresion = 0;
  $.ajax({
    async: false,
    type: "POST",
    dataType: "JSON",
    url: $("#url").val() + "venta/contador_comanda",
    success: function (data) {
      if (typeof data === "number") {
        contador_impresion = data;
      } else if (Array.isArray(data)) {
        contador_impresion = data.length;
      } else if (data && typeof data.length !== "undefined") {
        contador_impresion = Number(data.length) || 0;
      } else if (data && typeof data.contador !== "undefined") {
        contador_impresion = Number(data.contador) || 0;
      }
    },
    error: function (jqXHR, textStatus, errorThrown) {
      console.error("Error correlativo_imp:", errorThrown || textStatus);
      contador_impresion = 0;
    },
  });
  return ("000000" + (Number(contador_impresion) || 0)).slice(-6);
}

function imprimirComanda(pedido, idTipoPedido, detalles, codAnulacion = 0) {
  function buildPrintUrl(payload) {
    const serialized = encodeURIComponent(JSON.stringify(payload));
    const printCom = $("#print_com").val() === "1";
    const pcIp = $("#pc_ip").val();
    const baseUrl = $("#url").val();

    if (printCom) {
      return {
        url: `http://${pcIp}/imprimir/comanda.php?data=${serialized}`,
        features: "_blank",
      };
    } else {
      return {
        url: `${baseUrl}venta/impresion_comanda/?data=${serialized}`,
        features: "top=500,left=500,width=400,height=400,_blank",
      };
    }
  }

  function openPrintWindow({ url, features }) {
    window.open(url, "_blank", features);
  }

  const pedidoCliente = idTipoPedido != 1 ? pedido.nomb_cliente : "";
  const pedidoNumero = pedido.numero || "";

  const gruposPorArea = detalles.reduce((acc, item) => {
    const area = item.area_id;
    (acc[area] = acc[area] || []).push(item);
    return acc;
  }, {});

  Object.values(gruposPorArea).forEach((itemsDeArea) => {
    const impresora = itemsDeArea[0].nombre_imp; // Se asume la misma impresora para toda el área
    const pedidoMozo = $("#select_mozo option:selected").text();
    const datoUsuario = $("#dato_usuario").val();
    const correlativo = correlativo_imp();
    const nombrePc = $("#pc_name").val();
    const direccion_comanda =
      $("input[name='tipo_entrega_modal']:checked").val() || "";
    const direccion_cliente = $("#direccion_cliente_modal").val() || "";

    const payload = {
      pedido_tipo: idTipoPedido,
      pedido_numero: pedidoNumero,
      pedido_cliente: pedidoCliente,
      pedido_mozo: pedidoMozo,
      direccion_cliente: direccion_cliente,
      direccion_comanda: direccion_comanda,
      dato_usuario: datoUsuario,
      precio_comanda: 1,
      mostrar_precio_comanda: $("#mostrar_precio_comanda").val() || "0",
      correlativo_imp: correlativo,
      nombre_imp: impresora,
      nombre_pc: nombrePc,
      codigo_anulacion: codAnulacion,
      items: itemsDeArea,
    };

    console.log("Imprimiendo comanda:", payload);

    const { url, features } = buildPrintUrl(payload);
    openPrintWindow({ url, features });
  });
}

async function getPedidos() {
  console.log("getPedidos");

  const base = $("#url").val() || "";
  const endpoint = base + "venta_rapida/mostrador_list_c";

  try {
    const res = await fetch(endpoint, {
      method: "POST",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
      },
      body: new URLSearchParams({ estado: "b" }),
    });
    const json = await res.json();

    Pedidos = json.data;

    console.log("es movil" + esDispositivoMovil());
    renderPedidosJQ(Pedidos);

    if (PedidoSeleccionado.length) {
      console.log("es movil" + esDispositivoMovil());
      renderPedidosJQ(Pedidos);
    }

    console.log("aasdsadsada");
  } catch (e) {
    console.error("[mostrador_list_b_fetch] error:", e);
    throw e;
  }
}

async function getPedido(id_pedido) {
  const base = $("#url").val() || "";
  const endpoint = base + "venta/listarPedidosDetalle";

  try {
    const res = await fetch(endpoint, {
      method: "POST",
      headers: {
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
      },
      body: new URLSearchParams({ cod_atencion: 2, id_pedido: id_pedido }),
    });
    const json = await res.json();
    console.log("get pedido respuesta:", json);

    PedidoSeleccionado = json;

    const arregloExtraido = json.Detalle.map((item) => {
      const {
        Producto,
        cant, // en tu JSON la clave es "cant"
        precio,
        id_pres,
        id_pedido,
      } = item;

      const { fecha_pedido, estado_pedido } = json; // vienen del objeto raíz

      const total = parseFloat(cant) * parseFloat(precio);
      const pro_img = "default.png";

      return {
        ...Producto, // trae pro_nom, pro_pre
        id_pedido,
        fecha_pedido,
        estado_pedido,
        cantidad: cant, // aquí renombramos "cant" a "cantidad"
        id_pres,
        pro_cos: precio,
        pro_img,
        total,
      };
    });

    limpiarDescuentos();
    vaciarListaProductos();

    arregloExtraido.forEach((producto) => {
      agregarProducto(producto, false, id_pedido);
    });

    activateOptionsPedido(1, PedidoSeleccionado.estado_pedido);
    iniciarModalPedido();
  } catch (e) {
    console.error("[get pedido] error:", e);
    throw e;
  }
}

function limpiarDescuentos() {
  $("#tipo_descuento_select").prop("selectedIndex", 0).trigger("change");
  $("#descuento_porcentaje").val("");
  $("#descuento_monto_fijo").val("");
  $("#descuento_monto_hidden").val("0.00");
  $("#descuento_tipo_hidden").val("0");
  $("#descuento_motivo_hidden").val("");
  $("#descuento_personal_hidden").val("0");
  $("#personal_descuento").val("");
  $("#impuesto_bolsa").val("");
  $("#comision_delivery").val("");
  $(".totalDescuento").text("0.00");
  $(".totalDelivery").text("0.00");
  $("#observacion").val("");
}

function tieneStockDisponible(item) {
  var actualizado = Productos.find(function(p) { return p.id_pres === item.id_pres; });
  if (actualizado) item = actualizado;
  if (!item.Stock || item.Stock.crt_stock != 1) return true;
  // StockRuntime ya descuenta lo que está en el carrito → basta con >= 1 unidad
  return getStockVendible(item) >= 1;
}

function listarCategorias() {
  const base = $("#url").val() || "";
  const tipo = $("#codtipoped").val();
  if (!base || !tipo) {
    console.warn("Faltan #url o #codtipoped para listarCategorias");
    return $.Deferred().reject("Faltan params").promise();
  }
  return $.ajax({
    url: base + "venta/listarCategorias",
    type: "POST",
    dataType: "json",
    data: { codtipoped: tipo },
  })
    .done(function (data) {
      // Normaliza en globales
      Categorias = Array.isArray(data) ? data : [];
      Productos = [];
      Categorias.forEach((cat) => {
        (cat.productos || []).forEach((p) => {
          p.id_catg = cat.id_catg;
          Productos.push(p);
        });
      });
      buildStockRuntime(Productos); // reconstruye el runtime desde datos frescos del servidor

      // Hooks opcionales del proyecto
      if (typeof listarProdsMasVend === "function") listarProdsMasVend();
      if (typeof generarCategorias === "function")
        generarCategorias(Categorias);

      console.log(Productos);
    })
    .fail(function (xhr, status, error) {
      console.error("Error al obtener categorías:", error);
    });
}

var listarProductos = function (id_catg, tipe_view = "grid") {
  const productosFiltrados = Productos.filter(
    (producto) => producto.id_catg == id_catg
  );

  generarProductos(productosFiltrados, tipe_view);
};

function generarProductos(items, vista = "grid") {
  const url = $("#url").val();
  const container = $(".section-list");
  let html = "";

  if (items.length === 0) {
    html = `
      <div style="display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;min-height:400px;text-align:center;">
        <div style="margin-bottom:10px;">
          <svg xmlns="http://www.w3.org/2000/svg" width="120" height="120" viewBox="0 0 24 24" fill="none">
            <path d="..." fill="#aaa"/>
          </svg>
        </div>
        <p style="color:#aaa;">Parece que esta categoría aún está vacía</p>
      </div>
    `;
  } else {
    html = items
      .map(function (item) {
        let preciosHtml = "";
        let tienePrecios = false;
        const imageUrl = construirUrlImagenProducto(item.pro_img);

        if (item.precios) {
          try {
            const preciosArray = JSON.parse(item.precios);
            if (preciosArray.length > 0) {
              tienePrecios = true;
              preciosHtml = `
              <div class="content" style="display:none;">
                <div class="modal-content animated bounceInTop" style="padding:2px 4px;display:flex;flex-direction:row;flex-wrap:wrap;gap:.5rem;justify-content:space-evenly">
            `;

              preciosHtml += `
              <div style="display:flex;flex-direction:column;align-items:center;gap:.3rem">
                <span>Precio base</span>
                <button class="btn btn-outline-primary btn-sm agregar-precio"
                  data-precio="${item.pro_cos}"
                  data-id_pres="${item.id_pres}"
                  data-price-name="Precio base"
                  data-producto='${JSON.stringify(item)}'>
                  ${item.pro_cos}
                </button>
              </div>
            `;

              preciosArray.forEach((precio) => {
                preciosHtml += `
                <div style="display:flex;flex-direction:column;align-items:center;gap:.3rem">
                  <span>${precio.nombre}</span>
                  <button class="btn btn-secondary btn-sm agregar-precio"
                    data-precio="${precio.precio}"
                    data-id_pres="${precio.id_pres}"
                    data-price-name="${precio.nombre}"
                    data-producto='${JSON.stringify(item)}'>
                    ${precio.precio}
                  </button>
                </div>
              `;
              });

              preciosHtml += `</div></div>`;
            }
          } catch (e) {
            console.warn("Error al parsear precios:", e);
          }
        }

        // HTML para vista tipo lista
        if (vista === "list") {
          return `
          <div class="card-menu-wrapper" style="border-bottom: 1px solid #ccc; padding: 10px; display: flex; align-items: center; gap: 10px; cursor: pointer;">
            <img class="js-product-img" src="${imageUrl}" alt="" style="width: 50px; height: 50px; object-fit: cover; border-radius: 4px;">
            <div style="flex-grow: 1;">
              <div style="font-weight: bold;">${item.pro_pre}</div>
              <div style="color: #888;">Precio: ${item.pro_cos}</div>
            </div>
            <div class="stock-container-list">
              ${renderStockBadgeList(item)}
            </div>
            ${preciosHtml}
          </div>
        `;
        } else {
          // HTML para vista tipo grid (tarjeta)
          return `
          <div class="card-menu-wrapper">
            <div class="card-menu">
              <div class="card-menu-header" style="position: relative;">
                <img class="js-product-img" src="${imageUrl}" alt="">
                ${renderStockBadge(item)}
              </div>
              <div class="menu-name">${item.pro_pre}</div>
              <div class="menu-category prices-list menu-price-pill" title="Ver mas precios">
                <span class="price">${item.pro_cos}</span>
              </div>
            </div>
            ${preciosHtml}
          </div>
        `;
        }
      })
      .join("");
  }

  // Limpiar y aplicar clase de vista (list o grid)
  container
    .removeClass("list-view grid-view")
    .addClass(vista === "list" ? "list-view" : "grid-view")
    .html(html);

  validarImagenesProductosEnSegundoPlano(container);

  // Eventos por tarjeta
  container.find(".card-menu-wrapper").each(function (index) {
    $(this).data("item", items[index]);
  });

  container.find(".card-menu-wrapper").on("click", function () {
    const item = $(this).data("item");
    if (item.precios) {
      try {
        const preciosArray = JSON.parse(item.precios);
        if (preciosArray.length > 0) {
          $(this).find(".content").slideToggle("fast");
          return;
        }
      } catch (e) {
        console.warn("Error al parsear precios:", e);
      }
    }

    if (item.Stock && item.Stock.crt_stock == 1 && item.Stock.ingredientes) {
      if (tieneStockDisponible(item)) {
        item.cantidad = 1;
        agregarProducto(item);
        actualizarStockVisual(this, item);
      } else {
        mostrarAlerta(
          "warning",
          "Sin stock disponible",
          "No hay stock suficiente para agregar este producto."
        );
      }
    } else {
      item.cantidad = 1;
      agregarProducto(item);
    }
  });
}

let _productCounter = 0;

function agregarProducto(product, esNuevo = true) {

  console.log(product);


  if (
    PedidoSeleccionado.estado_pedido &&
    PedidoSeleccionado.estado_pedido == "d" &&
    esNuevo
  ) {
    return;
  }
  const item = { ...product };

  item.isNew = esNuevo;
  item.wrapperId = `po-${++_productCounter}`;

  item.nombre_precio = item.nombre_precio || "Principal";

  let total = parseFloat(item.pro_cos) * parseFloat(item.cantidad || 1);

  const container = $(".po-items");
  const newItemHtml = `
    <div class="po-item-wrapper${esNuevo ? " new-item" : ""}"
         data-wrapper-id="${item.wrapperId}" data-igv="${item.pro_imp}">
      <button type="button" class="po-item collapsible">
        <!-- Flex Container for optimizing space -->
        <div class="d-flex justify-content-between align-items-start w-100">
            
            <!-- LEFT COLUMN: Name and Actions -->
            <div class="d-flex flex-column text-left" style="flex: 1; padding-right: 10px;">
                <div class="name mb-1">
                    ${item.pro_pre}
                    <span class="r-order-type-label" style="font-size: 0.8rem; color: #888; margin-left: 5px;">
                        ${item.pro_nom}
                    </span>
                </div>
                
                <div class="actions d-flex align-items-center">
                    <span class="edit_precio" title="Editar pedido">
                        <i class="fas fa-pencil-alt"></i>
                    </span>
                    <span class="comments" title="Agregar comentario">
                        <i class="fas fa-comment-alt"></i>
                    </span>
                    <span class="remove-item" title="Quitar de la lista">
                        <i class="fas fa-trash"></i>
                    </span>
                     <div class="texto-intermedio" style="margin-left: 5px; font-weight: bold; color: #555; font-size: 0.8rem;"></div>
                </div>
            </div>

            <!-- RIGHT COLUMN: Price and Quantity -->
            <div class="d-flex flex-column align-items-end">
                <div class="price mb-2" style="font-size: 1rem; font-weight: 700;">${formatNumber(total)}</div>
                
                <div class="cantidad">
                    <span class="down" ${!esNuevo ? 'style="opacity: 0.3; pointer-events: none;"' : ''}>-</span>
                    <span style="${!esNuevo ? 'font-weight:bold;' : ''}">${item.cantidad}</span>
                    <span class="up" ${!esNuevo ? 'style="opacity: 0.3; pointer-events: none;"' : ''}>+</span>
                </div>
            </div>

        </div>
      </button>

      <div class="content" style="padding: 0; margin: 0;">
        <div class="modal-content animated bounceInTop" style="padding: .5rem;">
          <div class="modal-body floating-labels p-2">

            <div class="nota-list animated fadeIn mb-2">
              <div class="demo-checkbox row g-2"></div>
            </div>

            <div class="nota-new text-center text-muted small mb-2"
                 style="line-height: 1.2;">
              <i class="mdi mdi-alert-circle" style="font-size: 1.5rem;"></i><br>
              No tiene elementos.<br>
              Agregue una nota <code style="cursor: pointer;">'NUEVA'</code>
            </div>

            <div class="nota-manual-wrapper d-flex align-items-center mt-2"
                 style="gap: .4rem;">
              <input type="text"
                     class="nota_manual_text form-control form-control-sm
                            border border-dark rounded"
                     placeholder="Escribir nota manual..." />
              <button type="button"
                      class="btn btn-warning btn-sm agregar-nota-manual"
                      title="Agregar nota">
                <i class="fas fa-plus"></i>
              </button>
              <button type="button"
                      class="btn btn-success btn-sm guardar-nota-manual"
                      title="Guardar nota en BD">
                <i class="fas fa-save"></i>
              </button>
            </div>

            <input type="hidden" id="notapadre"/>
            <h6 class="card-subtitle notlist p-0 m-0 small"></h6>
            <input type="hidden" id="cod_add"/>
            <input type="hidden" id="cod_pres_add"/>
            <input type="hidden" id="cod_prod_add"/>

          </div>
        </div>
      </div>
    </div>
  `;

  const newItem = $(newItemHtml).data("item", item);
  container.prepend(newItem);

  actualizarTotalesDesdeLista();
  actualizarContadorPedidos();
  showToast(`${item.pro_pre} agregado`, "success");
  if (PedidoSeleccionado && PedidoSeleccionado.id_pedido && item.isNew) {
    console.log("actualizando pedido seleccionado...");
    console.log(PedidoSeleccionado);
    $("#btn_registrar_pedido").show();
    $("#btn_cobrar").hide();
  }
}

function toNumber(x, def = 0) {
  const n = Number(
    String(x ?? "")
      .replace(/[^\d.,-]/g, "")
      .replace(",", ".")
  );
  return Number.isFinite(n) ? n : def;
}
function getQtySpan($wrap) {
  // Usa .qty si existe; si no, span central [down][qty][up]
  const $q = $wrap.find(".cantidad .qty");
  if ($q.length) return $q;
  return $wrap.find(".cantidad span").eq(1);
}
function getMaxQty($wrap, item) {
  // Prioriza item.cantidad; si no, lee el DOM; default 1
  let max = toNumber(item?.cantidad, NaN);
  if (!Number.isFinite(max)) {
    const $qty = getQtySpan($wrap);
    max = toNumber($qty.text(), 1);
  }
  return Math.max(0, max);
}
function setQtyBadge($wrap, selectedQty, maxQty) {
  const $qty = getQtySpan($wrap);
  if ($qty.data("origText") === undefined) {
    $qty.data("origText", $qty.text());
  }
  $qty.text(`${selectedQty}/${maxQty}`);
  $qty.toggleClass("complete", selectedQty === maxQty && maxQty > 0);
}

function setSelectedVisual($wrap, selectedQty) {
  $wrap.toggleClass("split-selected", selectedQty > 0);
}
function restoreQtyText($wrap) {
  const $qty = getQtySpan($wrap);
  const orig = $qty.data("origText");
  if (orig !== undefined) {
    $qty.text(orig);
    $qty.removeClass("complete");
    $qty.removeData("origText");
  }
}

// function enterSplitMode() {
//   if (selectionMode) return;
//   selectionMode = true;
//   $("body").addClass("split-mode");

//   $(".SubtotalPedido").text(`${formatNumber(0)}`);
//   $(".totalPedidoMenosTarjeta").text(`${formatNumber(0)}`);
//   $("#pago_efe").val(0);

//   $(".po-item-wrapper").each(function () {
//     const $wrap = $(this);
//     const item = $wrap.data("item") || {};
//     const max = getMaxQty($wrap, item);

//     const id = $wrap.data("wrapper-id") || item.wrapperId || $wrap.index();
//     const currentSel = splitSelection.get(id)?.qty || 0;

//     setQtyBadge($wrap, currentSel, max);
//     setSelectedVisual($wrap, currentSel); // <<< pinta si ya hay selección
//   });
// }

function enterSplitMode() {
  if (selectionMode) return;
  selectionMode = true;
  $("body").addClass("split-mode");

  $(".po-item-wrapper").each(function () {
    const $wrap = $(this);
    const item = $wrap.data("item") || {};
    const $qty = $wrap.find(".cantidad .qty").length
      ? $wrap.find(".cantidad .qty")
      : $wrap.find(".cantidad span").eq(1);

    // badge "sel/max" (lo que ya haces)
    const max = getMaxQty($wrap, item);
    const id = $wrap.data("wrapper-id") || item.wrapperId || $wrap.index();
    const sel =
      window.splitSelection && window.splitSelection.get
        ? window.splitSelection.get(id)?.qty || 0
        : 0;
    if ($qty.data("origText") === undefined) $qty.data("origText", $qty.text());
    $qty.text(`${sel}/${max}`).toggleClass("complete", sel === max && max > 0);

    // === NUEVO: capturar precio original y unitario, y poner 0.00 ===
    const $price = $wrap.find(".price");
    if ($price.data("origPrice") === undefined) {
      $price.data("origPrice", $price.text()); // para restaurar al salir
    }
    const rawUnit = (item.pro_cos ?? $price.text() ?? "").toString();
    const unit =
      Number(rawUnit.replace(/[^\d.,-]/g, "").replace(",", ".")) || 0;
    $wrap.data("unitPrice", unit); // guardamos el precio unitario
    $price.text("0.00"); // mostramos subtotal inicial 0.00
    // ===========================================

    // color si ya hay selección
    $wrap.toggleClass("split-selected", sel > 0);
    $(".SubtotalPedido").text(`${formatNumber(0)}`);
    $(".totalPedidoMenosTarjeta").text(`${formatNumber(0)}`);
    $("#pago_efe").val(0);
  });
}

// function exitSplitMode() {
//   if (!selectionMode) return;
//   selectionMode = false;
//   $("body").removeClass("split-mode");

//   // Restaura textos originales y quita el color
//   $(".po-item-wrapper").each(function () {
//     const $wrap = $(this);
//     restoreQtyText($wrap);
//     $wrap.removeClass("split-selected"); // <<< quita highlight al salir
//   });

//   // Si NO quieres limpiar lo seleccionado, comenta la siguiente línea:
//   // splitSelection.clear();
// }

function exitSplitMode() {
  if (!selectionMode) return;
  selectionMode = false;
  $("body").removeClass("split-mode");

  $(".po-item-wrapper").each(function () {
    const $wrap = $(this);

    // restaurar cantidad original (si ya lo tienes con restoreQtyText, úsalo)
    const $qty = $wrap.find(".cantidad .qty").length
      ? $wrap.find(".cantidad .qty")
      : $wrap.find(".cantidad span").eq(1);
    const orig = $qty.data("origText");
    if (orig !== undefined) {
      $qty.text(orig).removeClass("complete").removeData("origText");
    }

    // === NUEVO: restaurar precio original y limpiar unitario ===
    const $price = $wrap.find(".price");
    const origPrice = $price.data("origPrice");
    if (origPrice !== undefined) {
      $price.text(origPrice).removeData("origPrice"); // volver a como estaba
    }
    $wrap.removeData("unitPrice"); // limpiar cache
    // ===============================================

    $wrap.removeClass("split-selected");
    $wrap.find(".texto-intermedio").text("");
  });

  actualizarTotalesDesdeLista();

  // splitSelection.clear(); // opcional
}

// function actualizarTotalesDesdeLista() {
//   let subtotal = 0;

//   $(".po-item").each(function () {
//     const item = $(this);
//     const precio = parseFloat(item.find(".price").text()) || 0;
//     const cantidad = parseInt(item.find(".cantidad span").eq(1).text()) || 0;
//     const igv = item.find("data-igv").text() || 0;

//     console.log(igv);

//     if (PedidoSeleccionado) {
//       subtotal += precio;
//       return;
//     }

//     subtotal += cantidad * precio;
//   });

//   const igv = 0.0;
//   const total = subtotal + igv;

//   // Actualizar los valores en pantalla
//   $(".sub-total div:eq(0) span:eq(1)").text("S/" + subtotal.toFixed(2));
//   $(".sub-total div:eq(1) span:eq(1)").text("S/" + igv.toFixed(2));
//   $(".total span:eq(1)").text("S/" + total.toFixed(2));

//   if (PedidoSeleccionado) {
//     $(".totalPedidoMenosTarjeta").text(formatNumber(total));
//     $(".SubtotalPedido").text(formatNumber(total));
//     $("#pago_efe").val(total.toFixed(2));
//     $(".totalDescuento").text(formatNumber(0));
//     $(".totalDelivery").text(formatNumber(0));
//   }
// }

function actualizarTotalesDesdeLista() {
  let subtotal = 0;
  let igvTotal = 0.0;
  let igvActive = false;
  const porcentajeIgv = $("#igv").val() / 100; // 18% IGV

  // Recorre cada item completo (el wrapper)
  $(".po-item-wrapper").each(function () {
    const wrap = $(this);

    // Lee precio y cantidad desde el wrapper
    const precio = Number(String(wrap.find(".price").text()).replace(/[^\d.-]/g, "")) || 0;
    const cantidad = Number(wrap.find(".cantidad span").eq(1).text()) || 0;

    igvActive = wrap.attr("data-igv") == 1;   // ej. "1", "0" o "0.18"

    if (PedidoSeleccionado) {
      subtotal += precio;
    } else {
      // si .price es unitario, usa cantidad * precio; si es total de línea, solo suma precio
      subtotal += cantidad * precio; // ajusta según cómo renders .price
    }

  });

  console.log(porcentajeIgv);

  if (igvActive) {
    igvTotal = subtotal * porcentajeIgv; // 18% IGV
    subtotal = subtotal - igvTotal; // ajustar subtotal si es con IGV incluido
  }

  const total = subtotal + igvTotal;

  $(".sub-total div:eq(0) span:eq(1)").text("S/" + subtotal.toFixed(2));
  $(".sub-total div:eq(1) span:eq(1)").text("S/" + igvTotal.toFixed(2));
  $(".total span:eq(1)").text("S/" + total.toFixed(2));

  if (PedidoSeleccionado) {
    $(".totalPedidoMenosTarjeta").text(formatNumber(total));
    $(".SubtotalPedido").text(formatNumber(total));
    $("#pago_efe").val(total.toFixed(2));
    $(".totalDescuento").text(formatNumber(0));
    $(".totalDelivery").text(formatNumber(0));

    // CHECK FOR DIRTY STATE (Unsaved Changes)
    let hasNewItems = false;
    $(".po-item-wrapper").each(function () {
      if ($(this).data("item").isNew) hasNewItems = true;
    });

    if (hasNewItems) {
      // Change button to "PEDIDO" (Dirty State)
      activateOptionsPedido(1, 'dirty');
    } else {
      // Revert to original state (e.g. COBRAR) if all saved
      // Need to check if PedidoSeleccionado.estado is up to date or passed manually
      // Assuming PedidoSeleccionado holds the current committed state
      activateOptionsPedido(1, PedidoSeleccionado.estado_pedido || PedidoSeleccionado.estado || 'b');
    }
  }
  toggleDynamicTotals();
}

function toggleDynamicTotals() {
  // 1. Get values using regex to clean currency symbols
  const descuento = parseFloat($(".totalDescuento").text().replace(/[^0-9.-]/g, '')) || 0;
  const delivery = parseFloat($(".totalDelivery").text().replace(/[^0-9.-]/g, '')) || 0;
  // Comision might have inline style display:none, so we check value
  const comision = getComisionTarjetaActual();

  // 2. Toggle visibility
  if (descuento > 0.009) {
    $("#row-descuento").removeClass("d-none");
  } else {
    $("#row-descuento").addClass("d-none");
  }

  if (delivery > 0.009) {
    $("#row-delivery").removeClass("d-none");
  } else {
    $("#row-delivery").addClass("d-none");
  }

  // Comision uses both class and style, so we leverage jQuery methods that handle style
  if (comision > 0.009) {
    $("#row-comision").removeClass("d-none").show();
    $("#row-comision").css("display", "block"); // force block if it was flex item? No, parent is flex row.
    // If parent is flex, 'show' might set it to block. We want it to just be visible.
    // safe approach: remove d-none, remove style display:none
    $("#row-comision").removeAttr("style");
  } else {
    $("#row-comision").addClass("d-none").hide();
  }
}


function actualizarContadorPedidos() {
  const count = $(".po-items .po-item-wrapper").length;
  $("#ver_seleccionados").text(`Ver seleccionados (${count})`);
}

function renderStockBadgeList(item) {
  var actualizado = Productos.find(function(p) { return p.id_pres === item.id_pres; });
  if (actualizado) item = actualizado;
  if (!item.Stock || item.Stock.crt_stock != 1 || !item.Stock.ingredientes) return '';
  var stock = getStockVendible(item);
  if (stock === null) return '';
  return '<span class="stock-badge-list" style="display:inline-block;background:#00afe9;color:#333;font-size:14px;padding:2px 6px;border-radius:4px;">Stock: ' + stock + '</span>';
}

function renderStockBadge(item) {
  var actualizado = Productos.find(function(p) { return p.id_pres === item.id_pres; });
  if (actualizado) item = actualizado;
  if (!item.Stock || item.Stock.crt_stock != 1 || !item.Stock.ingredientes) return '';
  var stock = getStockVendible(item);
  if (stock === null) return '';
  return '<div class="stock-badge" style="position:absolute;bottom:5px;right:5px;background-color:rgba(0,0,0,0.7);color:white;font-size:16px;padding:2px 6px;border-radius:4px;">Stock: ' + stock + '</div>';
}

const statusMeta = {
  b: {
    label: "En preparación",
    badgeStyle: "background-color: #fff3cd; color: #856404; border: 1px solid #ffeeba; padding: 0.35em 0.65em; font-weight: 600; border-radius: 20px;",
    borderLeft: "5px solid #ffc107"
  },
  d: {
    label: "Entregado",
    badgeStyle: "background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; padding: 0.35em 0.65em; font-weight: 600; border-radius: 20px;",
    borderLeft: "5px solid #28a745"
  },
  c: {
    label: "Pagado",
    badgeStyle: "background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; padding: 0.35em 0.65em; font-weight: 600; border-radius: 20px;", // verde
    borderLeft: "5px solid #28a745"
  }
};

function buildPedidoCardJQ(p) {
  var estadoCfg = statusMeta[p.estado] || {
    label: "-",
    badgeStyle: "background-color: #e2e3e5; color: #383d41; border-radius: 20px;",
    borderLeft: "5px solid #6c757d"
  };

  var cliente = p.nomb_cliente && p.nomb_cliente.trim() !== "" ? p.nomb_cliente : "Público General";
  // Capitalize name
  cliente = cliente.toLowerCase().replace(/(?:^|\s)\S/g, function (a) { return a.toUpperCase(); });

  var $wrapper = $("<div/>", {
    class: "order-card", // Retain only base class, let CSS Grid handle layout
    "data-order-id": p.id_pedido,
    role: "button",
    tabindex: 0,
    "aria-pressed": "false",
    style: "cursor: pointer; outline: none;"
  });

  // Dynamic Border Color
  // Default gray, but if 'Pagado' (c), use Green (#28a745)
  // If 'En preparacion' (b), keep default or maybe Yellow? Let's keep default border but add badge.
  // Actually user asked for "tarjetita de color verde" for Paid.
  var borderColor = p.estado === 'c' ? '#28a745' : '#cbd5e1';
  var borderStyle = p.estado === 'c' ? 'border: 2px solid #28a745 !important;' : 'border: 1px solid #cbd5e1 !important;';

  // Falta Pagar Indicator
  // Only for 'b' (En preparación)
  var faltaPagarHtml = "";
  if (p.estado === 'b') {
    faltaPagarHtml = `<span class="badge badge-danger ml-2" style="font-size: 0.75rem; padding: 0.35em 0.6em;">Falta Pagar</span>`;
  }

  var html = `
    <div class="card h-100 shadow-sm" style="overflow: hidden; transition: transform 0.2s; border-radius: 12px; ${borderStyle} box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1), 0 2px 4px -1px rgba(0,0,0,0.06) !important;">
      <div style="${estadoCfg.borderLeft}; height: 100%; position: absolute; left: 0; top: 0;"></div>
      <div class="card-body pl-4"> <!-- Added padding-left to clear the border -->
        
        <div class="d-flex justify-content-between align-items-center mb-3">
          <div>
            <h6 class="mb-0 font-weight-bold" style="font-size: 1.1rem; color: #2c3e50;">#${p.nro_pedido}</h6>
            <div class="text-muted small">
               <i class="far fa-clock mr-1"></i>${timeAgo(p.fecha_pedido)}
            </div>
          </div>
          <div class="text-right">
             <span style="${estadoCfg.badgeStyle}">${estadoCfg.label}</span>
             <div class="mt-1">${faltaPagarHtml}</div>
          </div>
        </div>

        <div class="mb-2 d-flex align-items-center">
           <div class="mr-3 text-center" style="width: 30px;">
                <i class="fas fa-user-circle text-muted" style="font-size: 1.5rem;"></i>
           </div>
           <div>
              <div class="small text-muted" style="line-height: 1;">Cliente</div>
              <div class="font-weight-bold" style="color: #34495e;">${cliente}</div>
           </div>
        </div>

         <div class="mb-3 d-flex align-items-center">
           <div class="mr-3 text-center" style="width: 30px;">
                <i class="fas fa-utensils text-muted" style="font-size: 1.2rem;"></i>
           </div>
           <div>
              <div class="small text-muted" style="line-height: 1;">Canal</div>
              <div style="font-weight: 500;">${p.canal}</div>
           </div>
        </div>

        <hr class="my-2" style="border-top: 1px dashed #e9ecef;"/>

        <div class="d-flex justify-content-between align-items-center mt-2">
          <div class="text-muted small"><i class="far fa-calendar-alt mr-1"></i>${p.fecha}</div>
          <div class="fs-5 font-weight-bold text-dark" style="font-size: 1.5rem;">${money(p.total)}</div>
        </div>

      </div>
    </div > `;

  $wrapper.html(html);

  // Add hover effect
  $wrapper.find('.card').on('mouseenter', function () {
    $(this).css('transform', 'translateY(-3px)');
    $(this).css('box-shadow', '0 8px 16px rgba(0,0,0,0.1) !important');
  }).on('mouseleave', function () {
    $(this).css('transform', 'translateY(0)');
    $(this).css('box-shadow', '0 4px 12px rgba(0,0,0,0.05) !important');
  });

  return $wrapper;
}

function renderPedidosJQ(data) {
  var $prep = $("#list-preparacion").empty();
  var $listo = $("#list-listo").empty();

  let countPrep = 0;
  let countListo = 0;

  // Custom Sort: "Pagado" (c) items go to the BOTTOM. "En preparación" (b) stay at TOP.
  // Secondary sort by ID desc (or whatever default was) is preserved if we use a stable sort or explicit comparison
  data.sort((a, b) => {
    // If a is 'c' and b is NOT 'c', a goes after b (return 1)
    if (a.estado === 'c' && b.estado !== 'c') return 1;
    // If a is NOT 'c' and b is 'c', a goes before b (return -1)
    if (a.estado !== 'c' && b.estado === 'c') return -1;
    return 0; // Keep relative order otherwise
  });

  data.forEach(function (p) {
    var $card = buildPedidoCardJQ(p);

    if (p.estado === "b" || p.estado === "c") {
      $prep.append($card);
      countPrep++;
    } else if (p.estado === "d") {
      $listo.append($card);
      countListo++;
    }
  });

  $("#count-preparacion").text(countPrep);
  $("#count-listo").text(countListo);
}

var pedidoAccion = function (
  tipo_pedido,
  cod_accion,
  estado_pedido,
  id_pedido
) {
  /* cod_accion
        1 = enviar delivery, 2 = entregado delivery, 3 = entregado mostrador
    */
  if (cod_accion == 1) {
    var accion = "PREPARADO";
  } else if (cod_accion == 2 || cod_accion == 3) {
    var accion = "ENTREGADO";
  }
  var html_confirm =
    '<div><br>\
        <div style="width: 100% !important; float: none !important;">\
            <table class="table m-b-0">\
                <tr><td class="text-left">Pedido: </td><td class="text-right">' +
    $(".pedido-numero").text() +
    '</td></tr>\
            </table>\
        </div><br>\
        Ingrese código de vaucher</div>\
        <form><input class="form-control text-center w-100" type="text" id="codigo_vaucher" autocomplete="off"/></form><br>\
        <div><span class="text-success" style="font-size: 17px;">¿Está Usted de Acuerdo?</span></div>';

  Swal.fire({
    title: "Necesitamos de tu Confirmación",
    html: html_confirm,
    icon: "warning",
    showCancelButton: true,
    confirmButtonColor: "#34d16e",
    confirmButtonText: "Si, Adelante!",
    cancelButtonText: "No!",
    showLoaderOnConfirm: true,
    preConfirm: function () {
      return new Promise(function (resolve) {
        $.ajax({
          url: $("#url").val() + "venta/pedidoAccion",
          type: "POST",
          data: {
            tipo_pedido: tipo_pedido,
            cod_accion: cod_accion,
            id_pedido: id_pedido,
            codigo_operacion: $("#codigo_vaucher").val(),
          },
          dataType: "json",
        })
          .done(function (response) {
            Swal.fire({
              title: "Proceso Terminado",
              text: "El pedido ha sido " + accion,
              icon: "success",
              confirmButtonColor: "#34d16e",
              confirmButtonText: "Aceptar",
            });
            fin_venta();
          })
          .fail(function () {
            Swal.fire(
              "Oops...",
              "Problemas con la conexión a internet!",
              "error"
            );
          });
      });
    },
    allowOutsideClick: false,
  });
};

function generarCategorias(categorias) {
  var container = $(".list-categories");

  let categoryHTML = "";

  if (!categorias || categorias.length === 0) {
    categoryHTML += '<p class="text-muted">No hay categorías disponibles.</p>';
  } else {
    // Favoritos (fijo)
    categoryHTML += `
    <div class="card-category selected" data-id="favoritos">
        <span class="icon"><i class="far fa-heart"></i></span>
        <span class="title">Favoritos</span>
        <span class="close" onclick="removeCategory(this)">&#x2716;</span>
        <span class="badge">0</span>
    </div>
    `;

    // Categorías dinámicas
    categoryHTML += categorias
      .map((categoria) => {
        // Filtra productos con el mismo id_catg (comparando como string)
        const cantidad = Productos.filter(
          (p) => p.id_catg === String(categoria.id_catg)
        ).length;

        return `
        <div class="card-category" data-id="${categoria.id_catg}">
          <span class="icon"><i class="fas fa-th"></i></span>
          <span class="title">${categoria.descripcion}</span>
          <span class="badge">${cantidad}</span>
        </div>
    `;
      })
      .join("");
  }

  // Insertar en el DOM
  container.html(categoryHTML);

  // Asignar eventos de selección
  $(".card-category").on("click", function (e) {
    $(".card-category").removeClass("selected");
    $(this).addClass("selected");

    var id = $(this).data("id");
    id == "favoritos"
      ? listarProdsMasVend()
      : listarProductos(id, modoListaProductos);
  });
}

function mostrarAlerta(icon, title, text) {
  Swal.fire({
    title: title,
    text: text,
    icon: icon,
    confirmButtonColor: "#34d16e",
    confirmButtonText: "Aceptar",
    allowOutsideClick: false,
    showCancelButton: false,
    showConfirmButton: true,
  }).then(function (result) {
    return false;
  });
}

function closeModalOrder() {
  console.log("Closing modal order");

  if (esDispositivoMovil()) {
    $(".modal-order-right").css("display", "none");
  }
}

function esDispositivoMovil() {
  return /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
    navigator.userAgent
  );
}

function filterProductosUI() {
  const q = ($("#input-buscar-carta").val() || "").toLowerCase();
  return Productos.filter((p) => {
    const txt = `${p.nombre || p.name || ""} ${p.descripcion || ""
      } `.toLowerCase();
    return !q || txt.includes(q);
  });
}

/* ---------- Carrito ---------- */
function cartAdd(prod) {
  const it = PedidosState.cart.find((x) => String(x.id) === String(prod.id));
  if (it) it.qty += 1;
  else PedidosState.cart.push(Object.assign({ qty: 1 }, prod));
  renderCart(true);
}
function cartInc(id) {
  const it = PedidosState.cart.find((x) => String(x.id) === String(id));
  if (it) {
    it.qty++;
    renderCart();
  }
}
function cartDec(id) {
  const it = PedidosState.cart.find((x) => String(x.id) === String(id));
  if (!it) return;
  it.qty--;
  if (it.qty <= 0) cartRemove(id);
  else renderCart();
}
function cartRemove(id) {
  PedidosState.cart = PedidosState.cart.filter(
    (x) => String(x.id) !== String(id)
  );
  renderCart();
}

function renderCart(highlightLast = false) {
  const $items = $(".po-items");
  if (!$items.length) return;
  $items.empty();

  if (!PedidosState.cart.length) {
    $items.append('<div class="empty-items text-muted">sin productos</div>');
  } else {
    PedidosState.cart.forEach((it, idx) => {
      const row = $(`
    <div class="po-item-wrapper ${highlightLast && idx === PedidosState.cart.length - 1
          ? "new-item"
          : ""
        } ">
  <div class="po-item">
            <div class="img">${it.img
          ? `<img src="${it.img}" alt="${it.name}">`
          : '<span class="text-muted small">IMG</span>'
        }</div>
            <div class="description">
              <div class="info">
                <strong>${it.name}</strong>
                <small class="price">${money(it.price)}</small>
              </div>
              <div class="actions">
                <div class="quantity">
                  <button type="button" class="btn btn-sm btn-link p-0 minus">-</button>
                  <span class="px-2">${it.qty}</span>
                  <button type="button" class="btn btn-sm btn-link p-0 plus">+</button>
                </div>
                <button type="button" class="btn btn-sm btn-outline-danger remove">Quitar</button>
              </div>
            </div>
          </div>
        </div>
  `);
      row.find(".plus").on("click", () => cartInc(it.id));
      row.find(".minus").on("click", () => cartDec(it.id));
      row.find(".remove").on("click", () => cartRemove(it.id));
      $items.append(row);
    });
  }

  const subtotal = PedidosState.cart.reduce(
    (s, it) => s + it.price * it.qty,
    0
  );
  const igv = subtotal * PedidosState.igv;
  const total = subtotal + igv;

  const $sub = $(".sub-total").empty();
  const $tot = $(".total").empty();
  $sub.append(`
  <div><span>Subtotal</span><span>${money(subtotal)}</span></div>
    <div><span>IGV ${Math.round(PedidosState.igv * 100)}%</span><span>${money(
    igv
  )}</span></div>
`);
  $tot.append(`<span>Total</span><span>${money(total)}</span>`);
}

function updateWspStatusDot(state) {
  const $dot = $("#wsp-status");
  if (!$dot.length) return;

  $dot.removeClass("text-secondary text-info text-success text-danger");
  if (state === "sending") {
    $dot.addClass("text-info").attr("title", "Enviando...");
  } else if (state === "success") {
    $dot.addClass("text-success").attr("title", "Enviado correctamente");
  } else if (state === "error") {
    $dot.addClass("text-danger").attr("title", "Error al enviar");
  } else {
    $dot.addClass("text-secondary").attr("title", "No enviado aún");
  }
}

function showWspInlineFeedback(type, message) {
  const $input = $("#numero_cliente");
  if (!$input.length) return;

  let $container = $input.closest(".col-12");
  if (!$container.length) {
    $container = $input.closest(".input-group").parent();
  }
  if (!$container.length) return;

  let $feedback = $container.find("#wsp-feedback");
  if (!$feedback.length) {
    $feedback = $(
      '<div id="wsp-feedback" class="wsp-feedback d-none mt-2" aria-live="polite"></div>'
    );
    $container.append($feedback);
  }

  if (type === "clear") {
    $feedback
      .addClass("d-none")
      .removeClass("wsp-feedback-success wsp-feedback-error wsp-feedback-info")
      .empty();
    return;
  }

  const classMap = {
    success: "wsp-feedback-success",
    error: "wsp-feedback-error",
    info: "wsp-feedback-info",
  };

  const iconMap = {
    success: "fas fa-check-circle",
    error: "fas fa-exclamation-circle",
    info: "fas fa-spinner fa-spin",
  };

  $feedback
    .removeClass("d-none wsp-feedback-success wsp-feedback-error wsp-feedback-info")
    .addClass(classMap[type] || "wsp-feedback-info")
    .html(
      '<i class="' +
        (iconMap[type] || iconMap.info) +
        '"></i><span>' +
        message +
        "</span>"
    );
}

function clickSendWhatsapp(id_venta) {
  const $input = $("#numero_cliente");
  const number = ($input.val() || "").replace(/\D+/g, "").slice(0, 11);
  $input.val(number);

  if (number.length !== 11) {
    updateWspStatusDot("error");
    showWspInlineFeedback(
      "error",
      "Ingresa un número válido de 11 dígitos (ej: 51999999999)."
    );
    $("#button-addon2").prop("disabled", true);
    return;
  }

  var Urls = $("#url").val() + "comprobante/ticket/" + btoa(id_venta);
  const textos = { 1: "Boleta", 2: "Factura", 3: "Nota de venta" };
  var activo = $('input[name="tipo_doc"]:checked').val();
  var tipoText = textos[activo] || "Desconocido";

  const $btn = $("#button-addon2");
  if (!$btn.length) return;

  const originalHtml = $btn.data("original-html") || $btn.html();
  $btn.data("original-html", originalHtml);

  $btn
    .prop("disabled", true)
    .html('<i class="fas fa-spinner fa-spin mr-1"></i>enviando');
  updateWspStatusDot("sending");
  showWspInlineFeedback("info", "Enviando comprobante por WhatsApp...");

  $.ajax({
    url: $("#url").val() + "whatsapp/get_send_wsp",
    type: "POST",
    dataType: "json",
    data: {
      number: number,
      media: Urls,
      filename: tipoText + ".pdf",
    },
    success: function (data) {
      if (!data || !data.ok) {
        const msg = (data && data.message) || "No se pudo enviar el mensaje";
        updateWspStatusDot("error");
        showWspInlineFeedback("error", msg);
        return;
      }

      updateWspStatusDot("success");
      showWspInlineFeedback(
        "success",
        "Comprobante enviado por WhatsApp correctamente."
      );
    },
    error: function () {
      updateWspStatusDot("error");
      showWspInlineFeedback(
        "error",
        "No se pudo enviar el mensaje. Intenta de nuevo."
      );
    },
    complete: function () {
      const numeroLen = ($("#numero_cliente").val() || "")
        .replace(/\D+/g, "")
        .slice(0, 11).length;
      $btn.html(originalHtml).prop("disabled", numeroLen !== 11);
    },
  });
}

/* ---------- Ready: aquí está el $(function(){}) ---------- */
