import { useMemo, useState } from 'react';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import {
  bsDesdeUsd,
  etiquetaReferencia,
  faltaReferencia,
  formatBs,
  necesitaReferencia,
  type OpcionGrupo,
  type Restaurante,
} from '@gustito/shared';
import { supabase } from '../lib/supabase';
import { useAuth } from '../lib/auth';
import { subirComprobante } from '../lib/storage';
import {
  DatosFactura,
  SIN_DATOS_FISCALES,
  guardarDatosFiscales,
  hayDatosFiscales,
  useFacturaActiva,
  type DatosFiscales,
} from '../components/DatosFactura';

type Prod = {
  id: string;
  nombre: string;
  precio_usd: number;
  categoria_id: string | null;
  disponible: boolean;
  orden: number;
  opciones: OpcionGrupo[] | null;
};
type Cat = { id: string; nombre: string; orden: number; grupo?: string | null };
type TipoEntrega = 'pickup' | 'mesa' | 'delivery';
type Metodo = 'efectivo' | 'pago_movil' | 'transferencia' | 'zelle' | 'punto_venta';

// Cada linea es independiente (uid propio): el mismo producto puede ir varias
// veces con contornos distintos, igual que en la tienda del comensal.
type Linea = {
  uid: string;
  producto_id: string;
  nombre: string;
  precio_usd: number; // precio final por unidad (base + extras de opciones)
  cantidad: number;
  opciones: string[]; // nombres elegidos: el servidor revalida el precio con esto
  // Cada eleccion con su grupo. Sin esto el servidor no sabe cual de los grupos
  // cobrar: el mismo nombre puede ser gratis en "incluida" y costar en "otra".
  opcionesSel: { g: string; o: string }[];
  texto: string; // resumen visible ("Proteína: Carne mechada · Extras: Queso")
};

const usd = (n: number) => `$${Number(n).toFixed(2)}`;
const OTROS = '__otros';

// Precio a mostrar en la tarjeta (mismo criterio de la tienda del comensal):
// si el precio depende de una opcion obligatoria (ej. tamano de la sopa, sabor
// de la empanada, peso de la carne), muestra "Desde $X" con la mas barata en
// vez del base $0.
function precioTarjeta(p: Prod): { texto: string; desde: boolean } {
  let min = p.precio_usd;
  let varia = false;
  for (const g of p.opciones ?? []) {
    if (!g.obligatorio) continue;
    const extras = (g.opciones ?? []).map((o) => o.precio_extra || 0);
    if (!extras.length) continue;
    const menor = Math.min(...extras);
    min += menor;
    if (Math.max(...extras) > menor || menor > 0) varia = true;
  }
  if (min > 0 && (varia || p.precio_usd === 0)) return { texto: usd(min), desde: true };
  return { texto: usd(p.precio_usd), desde: false };
}

function nuevoUid(): string {
  try {
    return crypto.randomUUID();
  } catch {
    return 'l' + Math.random().toString(36).slice(2) + Date.now().toString(36);
  }
}

const METODOS: { v: Metodo; label: string }[] = [
  { v: 'efectivo', label: 'Efectivo' },
  { v: 'pago_movil', label: 'Pago Móvil' },
  { v: 'transferencia', label: 'Transferencia' },
  { v: 'zelle', label: 'Zelle' },
  { v: 'punto_venta', label: 'Punto de venta' },
];
const ENTREGAS: { v: TipoEntrega; label: string }[] = [
  { v: 'pickup', label: 'Mostrador' },
  { v: 'mesa', label: 'Mesa' },
  { v: 'delivery', label: 'Delivery' },
];

export default function PuntoDeVenta({
  restaurante,
  marca,
  txtMarca,
  acento,
  onClose,
  mesaInicial,
}: {
  restaurante: Restaurante;
  marca: string;
  txtMarca: string;
  acento: string;
  onClose: () => void;
  mesaInicial?: string;
}) {
  const qc = useQueryClient();
  const { perfil } = useAuth();
  const [q, setQ] = useState('');
  const [catSel, setCatSel] = useState<string | null>(null);
  const [lineas, setLineas] = useState<Linea[]>([]);
  const [prodAbierto, setProdAbierto] = useState<Prod | null>(null);
  const [nombre, setNombre] = useState('');
  const [telefono, setTelefono] = useState('');
  const [tipo, setTipo] = useState<TipoEntrega>(mesaInicial || perfil?.rol === 'staff' ? 'mesa' : 'pickup');
  const [mesa, setMesa] = useState(mesaInicial ?? '');
  const [comensalId, setComensalId] = useState('');
  const [paraLlevar, setParaLlevar] = useState(false);
  const [tiempoMin, setTiempoMin] = useState('');
  const [direccion, setDireccion] = useState('');
  const [repartidor, setRepartidor] = useState('');
  const [metodo, setMetodo] = useState<Metodo>('efectivo');
  const [referencia, setReferencia] = useState('');
  const [comprobante, setComprobante] = useState<File | null>(null);
  const [fiscal, setFiscal] = useState<DatosFiscales>(SIN_DATOS_FISCALES);
  const [enviando, setEnviando] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [exito, setExito] = useState<string | null>(null);
  const [hoja, setHoja] = useState(false); // hoja de cobro que sube en el telefono
  const [confirmSalir, setConfirmSalir] = useState(false);

  const { data } = useQuery({
    queryKey: ['pos-menu', restaurante.id],
    queryFn: async () => {
      const [cats, prods] = await Promise.all([
        supabase.from('categorias').select('id,nombre,orden,grupo').eq('restaurante_id', restaurante.id).order('orden'),
        supabase
          .from('productos')
          .select('id,nombre,precio_usd,categoria_id,disponible,orden,opciones')
          .eq('restaurante_id', restaurante.id)
          // La caja vende LA MISMA carta que ve el cliente: lo que el negocio
          // saco del menu (archivado) no se le puede seguir vendiendo a nadie.
          .eq('archivado', false)
          .eq('disponible', true)
          .order('orden'),
      ]);
      // Mismo orden que ve el cliente en la tienda: primero la comida, despues
      // las bebidas y de ultimo los adicionales. Sin esto la caja abria con los
      // refrescos arriba y las arepas enterradas.
      const peso = (g?: string | null) => (g === 'bebida' ? 1 : g === 'adicional' ? 2 : 0);
      const lista = ((cats.data ?? []) as unknown as Cat[])
        .slice()
        .sort((a, b) => peso(a.grupo) - peso(b.grupo) || (a.orden ?? 0) - (b.orden ?? 0));
      return {
        cats: lista,
        prods: (prods.data ?? []) as unknown as Prod[],
      };
    },
  });

  // Cuenta activa de la mesa elegida: para avisar si YA la atiende otro mesero
  // (el candado real vive en la BD: una sola cuenta activa por mesa).
  const mesaLimpia = mesa.trim();
  const cuentaMesaQ = useQuery({
    queryKey: ['pos-cuenta-mesa', restaurante.id, mesaLimpia],
    enabled: tipo === 'mesa' && mesaLimpia.length > 0,
    staleTime: 5000,
    queryFn: async () => {
      const { data, error } = await supabase
        .from('cuentas_mesa')
        .select('id, mesero_id, mesero_nombre')
        .eq('restaurante_id', restaurante.id)
        .eq('mesa', mesaLimpia)
        .neq('estado', 'cerrada')
        .maybeSingle();
      if (error) throw error;
      return (data as { id: string; mesero_id: string | null; mesero_nombre: string | null } | null) ?? null;
    },
  });
  const cuentaMesa = tipo === 'mesa' && mesaLimpia ? (cuentaMesaQ.data ?? null) : null;
  const mesaAjena = !!(cuentaMesa?.mesero_id && perfil?.id && cuentaMesa.mesero_id !== perfil.id);

  // Personas registradas de la mesa (si se abrio en modo "cada quien lo suyo"):
  // sirven para el "¿para quién?" y amarrar el pedido a esa persona.
  const comensalesMesaQ = useQuery({
    queryKey: ['pos-comensales', cuentaMesa?.id],
    enabled: tipo === 'mesa' && !!cuentaMesa?.id,
    queryFn: async () => {
      const { data, error } = await supabase
        .from('comensales_mesa')
        .select('id,nombre')
        .eq('cuenta_id', cuentaMesa!.id)
        .order('orden');
      if (error) throw error;
      return (data as { id: string; nombre: string }[]) ?? [];
    },
  });
  const comensales = comensalesMesaQ.data ?? [];

  // Repartidores para asignar de una vez en ventas delivery (mismo cache que Pedidos).
  const repartidoresQ = useQuery({
    queryKey: ['repartidores', restaurante.id],
    queryFn: async () => {
      const { data, error } = await supabase.rpc('mis_repartidores');
      if (error) throw error;
      return (data as unknown as { repartidor_id: string; nombre: string | null; vehiculo: string | null; estado: string }[]) ?? [];
    },
    enabled: tipo === 'delivery',
  });
  const repartidores = repartidoresQ.data ?? [];

  // useMemo en cadena: sin el, `?? []` y el filtro fabrican arrays nuevos en
  // cada render y el useMemo de grupos recalcula de gratis en cada tecla.
  const prods = useMemo(() => data?.prods ?? [], [data]);
  const cats = useMemo(() => data?.cats ?? [], [data]);

  const visibles = useMemo(
    () => prods.filter((p) => !q.trim() || p.nombre.toLowerCase().includes(q.trim().toLowerCase())),
    [prods, q],
  );
  const grupos = useMemo(() => {
    const g: { id: string; cat: string; items: Prod[] }[] = [];
    for (const c of cats) {
      const items = visibles.filter((p) => p.categoria_id === c.id);
      if (items.length) g.push({ id: c.id, cat: c.nombre, items });
    }
    const sinCat = visibles.filter((p) => !p.categoria_id || !cats.some((c) => c.id === p.categoria_id));
    if (sinCat.length) g.push({ id: OTROS, cat: 'Otros', items: sinCat });
    return g;
  }, [cats, visibles]);

  const gruposVisibles = catSel ? grupos.filter((g) => g.id === catSel) : grupos;

  const total = lineas.reduce((s, l) => s + l.precio_usd * l.cantidad, 0);
  const nItems = lineas.reduce((s, l) => s + l.cantidad, 0);
  // El punto de venta tambien pide su referencia (el lote del datafono): es
  // parte del registro fiscal y sin ella no se cuadra la caja con el banco.
  const esPagoOnline = necesitaReferencia(metodo);
  const faltaRef = tipo !== 'mesa' ? faltaReferencia(metodo, referencia) : null;
  const facturaActiva = useFacturaActiva(restaurante.id);
  const unidadesPorProducto = useMemo(() => {
    const m = new Map<string, number>();
    for (const l of lineas) m.set(l.producto_id, (m.get(l.producto_id) ?? 0) + l.cantidad);
    return m;
  }, [lineas]);

  // Agrega fusionando con una linea identica (mismo producto + misma personalizacion).
  function agregarLineas(nuevas: Omit<Linea, 'uid'>[]) {
    setLineas((prev) => {
      let out = [...prev];
      for (const n of nuevas) {
        const idx = out.findIndex((l) => l.producto_id === n.producto_id && l.texto === n.texto && l.precio_usd === n.precio_usd);
        if (idx >= 0) out = out.map((l, k) => (k === idx ? { ...l, cantidad: l.cantidad + n.cantidad } : l));
        else out = [...out, { ...n, uid: nuevoUid() }];
      }
      return out;
    });
    setExito(null);
  }

  function tocarProducto(p: Prod) {
    if ((p.opciones?.length ?? 0) > 0) {
      setProdAbierto(p); // con opciones: se arma en el selector
      return;
    }
    agregarLineas([{ producto_id: p.id, nombre: p.nombre, precio_usd: p.precio_usd, cantidad: 1, opciones: [], opcionesSel: [], texto: '' }]);
  }

  function setCantidad(uid: string, cant: number) {
    setLineas((prev) => (cant <= 0 ? prev.filter((l) => l.uid !== uid) : prev.map((l) => (l.uid === uid ? { ...l, cantidad: cant } : l))));
    setExito(null);
  }

  function limpiar() {
    setLineas([]);
    setNombre('');
    setTelefono('');
    // Si se entro desde una mesa puntual, el proximo pedido sigue siendo de
    // ESA mesa (la mesera va a tomar varias rondas sin salir de ahi). Sin esto,
    // el numero de mesa quedaba vacio por dentro aunque la pantalla siguiera
    // mostrando "Mesa X", y el siguiente pedido fallaba sin explicacion.
    setMesa(mesaInicial ?? '');
    setComensalId('');
    setParaLlevar(false);
    setFiscal(SIN_DATOS_FISCALES);
    setTiempoMin('');
    setDireccion('');
    setRepartidor('');
    setTipo(mesaInicial ? 'mesa' : perfil?.rol === 'staff' ? 'mesa' : 'pickup');
    setMetodo('efectivo');
    setReferencia('');
    setComprobante(null);
  }

  // "Cerrar" descarta el carrito sin enviarlo (no es un cierre de mesa ni de
  // cuenta). Si ya hay productos agregados, confirma antes de perderlos (con
  // un modal propio, no el confirm() nativo del navegador); si el carrito
  // esta vacio no hay nada que perder, cierra directo.
  function cerrarConAviso() {
    if (lineas.length > 0) {
      setConfirmSalir(true);
      return;
    }
    onClose();
  }

  async function crear() {
    setError(null);
    if (!lineas.length) {
      setError('Agrega al menos un producto.');
      return;
    }
    if (tipo === 'mesa' && !mesa.trim()) {
      setError('Indica el número de mesa.');
      return;
    }
    if (tipo === 'delivery' && direccion.trim().length < 4) {
      setError('Para delivery indica la dirección.');
      return;
    }
    // Mesa atendida por otro mesero: se permite (relevos, descansos) pero
    // avisando. El pedido queda firmado por quien lo toma, eso no se pierde.
    if (
      tipo === 'mesa' &&
      mesaAjena &&
      !confirm(`La mesa ${mesa.trim()} la atiende ${cuentaMesa?.mesero_nombre}. ¿Agregar este pedido a su cuenta igual?`)
    ) {
      return;
    }
    setEnviando(true);
    // Token unico por venta: evita que el anti-duplicado (firma = telefono+items,
    // ventana 3 min) agrupe dos ventas de mostrador identicas como una sola.
    const token = `${Date.now()}-${Math.round(performance.now())}`;
    const items = lineas.map((l) => ({
      producto_id: l.producto_id,
      nombre: l.nombre,
      precio_usd: l.precio_usd,
      cantidad: l.cantidad,
      opciones: l.opciones,
      opciones_sel: l.opcionesSel,
      nota: l.texto || undefined,
      _c: token,
    }));
    const comensalSel = comensales.find((x) => x.id === comensalId);
    const { data: res, error: err } = await supabase.rpc('crear_pedido', {
      p_restaurante_id: restaurante.id,
      p_cliente_nombre: comensalSel?.nombre || nombre.trim() || (tipo === 'mesa' ? 'Sin nombre' : 'Cliente en caja'),
      p_cliente_telefono: telefono.trim(),
      p_tipo_entrega: tipo,
      // En mesa el metodo no se pregunta (se cobra al final, desde Mesas); no
      // dejar un valor decorativo/confuso guardado en el pedido.
      p_metodo_pago: tipo === 'mesa' ? 'efectivo' : metodo,
      p_items: items,
      p_mesa: tipo === 'mesa' ? mesa.trim() : undefined,
      p_direccion: tipo === 'delivery' ? direccion.trim() : undefined,
      p_comensal_id: tipo === 'mesa' && comensalId ? comensalId : undefined,
      p_para_llevar: tipo === 'mesa' ? paraLlevar : undefined,
      p_referencia: tipo !== 'mesa' && esPagoOnline ? referencia.trim() : undefined,
      // Venta de MOSTRADOR: la caja cobra y entrega en el momento, asi que el
      // pedido nace ENTREGADO con el pago confirmado y NO pasa por pedidos
      // activos (la comanda de cocina sale igual, con membrete CAJA).
      p_venta_caja: tipo === 'pickup',
    });
    setEnviando(false);
    if (err) {
      setError(traducir(err.message));
      return;
    }
    const fila = (res as unknown as { pedido_id: string; codigo: string }[])?.[0];
    // Venta delivery con repartidor elegido: se asigna de una vez, sin pasar por Pedidos.
    let asignadoTxt = '';
    if (tipo === 'delivery' && repartidor && fila?.pedido_id) {
      const { error: errAsig } = await supabase.rpc('asignar_repartidor', {
        p_pedido_id: fila.pedido_id,
        p_repartidor_id: repartidor,
      });
      asignadoTxt = errAsig
        ? '. OJO: no se pudo asignar el repartidor, asígnalo desde Pedidos'
        : ` y asignado a ${repartidores.find((r) => r.repartidor_id === repartidor)?.nombre ?? 'repartidor'}`;
    }
    // Tiempo estimado (opcional, solo mesa): la mesera lo pone de una vez al
    // tomar el pedido, para no depender de que el panel entre a Pedidos despues.
    let tiempoTxt = '';
    if (tipo === 'mesa' && tiempoMin.trim() && fila?.pedido_id) {
      const min = parseInt(tiempoMin, 10);
      if (!Number.isNaN(min) && min > 0) {
        const { error: errTiempo } = await supabase.rpc('aceptar_pedido', { p_pedido_id: fila.pedido_id, p_min: min });
        tiempoTxt = errTiempo ? '. OJO: no se pudo guardar el tiempo estimado' : '';
      }
    }
    // Los datos del comprador: el pedido tiene que existir primero (la RPC los
    // guarda contra su id). Va de una vez, antes que nada, porque una venta de
    // mostrador entra a la cola de sellado apenas se crea, y a un documento ya
    // sellado no se le cambian los datos del comprador.
    let fiscalTxt = '';
    if (facturaActiva && hayDatosFiscales(fiscal) && fila?.pedido_id) {
      const problema = await guardarDatosFiscales('pedido', fila.pedido_id, fiscal);
      if (problema) fiscalTxt = `. OJO: no se guardaron los datos de la factura (${problema})`;
    }
    // Foto del comprobante (opcional): el pedido ya existe, recien ahora se
    // puede subir (la ruta de storage usa el pedido_id). Si falla, el pedido
    // ya quedo creado igual, solo avisa para que se reintente aparte.
    let comprobanteTxt = '';
    if (tipo !== 'mesa' && esPagoOnline && comprobante && fila?.pedido_id) {
      try {
        const ruta = await subirComprobante(comprobante, fila.pedido_id);
        const { error: errComp } = await supabase.rpc('registrar_comprobante', {
          p_pedido_id: fila.pedido_id,
          p_referencia: '',
          p_comprobante_url: ruta,
        });
        if (errComp) comprobanteTxt = '. OJO: no se pudo guardar la foto del comprobante';
      } catch {
        comprobanteTxt = '. OJO: no se pudo subir la foto del comprobante';
      }
    }
    qc.invalidateQueries({ queryKey: ['pedidos', restaurante.id] });
    qc.invalidateQueries({ queryKey: ['cocina', restaurante.id] });
    qc.invalidateQueries({ queryKey: ['panel-kpis', restaurante.id] });
    qc.invalidateQueries({ queryKey: ['clientes', restaurante.id] });
    qc.invalidateQueries({ queryKey: ['inventario', restaurante.id] });
    qc.invalidateQueries({ queryKey: ['cuentas-mesa', restaurante.id] });
    qc.invalidateQueries({ queryKey: ['pos-cuenta-mesa', restaurante.id] });
    setExito(
      tipo === 'pickup'
        ? `Venta ${fila?.codigo ?? ''} registrada: cobrada y entregada, la cocina recibe su comanda${comprobanteTxt}${fiscalTxt}. Listo para la próxima venta.`
        : `Pedido ${fila?.codigo ?? ''} creado${asignadoTxt}${tiempoTxt}${comprobanteTxt}${fiscalTxt}. Listo para la próxima venta.`,
    );
    setHoja(false); // vuelve al menu para el proximo pedido
    limpiar();
  }

  return (
    <div className="fixed inset-0 z-50 flex flex-col bg-noche text-white">
      {/* Barra superior */}
      <div className="flex shrink-0 items-center justify-between gap-3 border-b border-white/10 px-4 py-3">
        <div>
          <h2 className="text-lg font-extrabold leading-tight">
            {perfil?.rol === 'staff' ? 'Tomar pedido' : 'Punto de venta'}
          </h2>
          <p className="text-[13px] font-medium text-white/60">
            {perfil?.rol === 'staff' ? 'Lo que pide la mesa' : 'Toma un pedido en caja'}
          </p>
        </div>
        <button onClick={cerrarConAviso} className="rounded-xl border border-white/15 px-4 py-2 text-sm font-bold text-white/85 hover:bg-white/10">
          Cerrar
        </button>
      </div>

      {/* Aviso de exito / error: visible este abierta o no la hoja de cobro */}
      {(error || exito) && (
        <div className="shrink-0 px-4 pt-2">
          {error && <p className="rounded-lg bg-red-500/15 px-3 py-2 text-[13px] font-bold text-red-200 ring-1 ring-red-500/40">{error}</p>}
          {exito && <p className="rounded-lg bg-green-500/15 px-3 py-2 text-[13px] font-bold text-green-200 ring-1 ring-green-500/40">{exito}</p>}
        </div>
      )}

      <div className="relative flex min-h-0 flex-1 flex-col lg:flex-row">
        {/* Menu: en el telefono ocupa toda el area; en pantalla grande es la columna izquierda */}
        <div className="min-h-0 flex-1 overflow-y-auto p-4 pb-28 lg:pb-4">
          {/* Buscador + categoria, fijos arriba mientras se baja por el menu */}
          <div className="sticky top-0 z-10 -mx-4 -mt-4 mb-3 bg-noche px-4 pt-4 pb-3">
            <input
              className="w-full rounded-xl border border-white/15 bg-superficie-2 px-4 py-3 text-[15px] font-medium outline-none placeholder:text-white/45 focus:border-white/35"
              placeholder="Buscar producto"
              value={q}
              onChange={(e) => setQ(e.target.value)}
            />
            {grupos.length > 1 && (
              <div className="relative mt-2">
                <select
                  value={catSel ?? ''}
                  onChange={(e) => setCatSel(e.target.value || null)}
                  className="w-full appearance-none rounded-xl border border-white/15 bg-superficie-2 px-4 py-2.5 pr-10 text-sm font-bold text-white outline-none focus:border-white/35"
                >
                  <option value="">Todas las categorías ({visibles.length})</option>
                  {grupos.map((g) => (
                    <option key={g.id} value={g.id}>
                      {g.cat} ({g.items.length})
                    </option>
                  ))}
                </select>
                <span className="pointer-events-none absolute right-4 top-1/2 -translate-y-1/2 text-white/60">▾</span>
              </div>
            )}
          </div>

          {prods.length === 0 ? (
            <p className="rounded-2xl border border-dashed border-white/20 p-6 text-center text-[15px] font-medium text-white/70">
              No hay productos disponibles. Créalos en Menú.
            </p>
          ) : visibles.length === 0 ? (
            <p className="rounded-2xl border border-dashed border-white/20 p-6 text-center text-[15px] font-medium text-white/70">
              Nada coincide con "{q.trim()}".
            </p>
          ) : (
            <div className="space-y-6">
              {gruposVisibles.map((g) => (
                <div key={g.id}>
                  <div className="mb-2.5 flex items-center gap-2.5">
                    <span className="h-4 w-1 rounded-full" style={{ background: acento }} />
                    <p className="text-[15px] font-extrabold text-white">{g.cat}</p>
                    <span className="text-[13px] font-semibold text-white/50">{g.items.length}</span>
                  </div>
                  <div className="grid grid-cols-2 gap-2 sm:grid-cols-3 xl:grid-cols-4">
                    {g.items.map((p) => {
                      const cant = unidadesPorProducto.get(p.id) ?? 0;
                      const conOpciones = (p.opciones?.length ?? 0) > 0;
                      const pt = precioTarjeta(p);
                      return (
                        <button
                          key={p.id}
                          onClick={() => tocarProducto(p)}
                          className="flex flex-col rounded-xl bg-superficie-2 p-2.5 text-left ring-1 ring-white/15 transition hover:ring-white/30 active:scale-[.98]"
                          style={cant ? { boxShadow: `inset 0 0 0 2px ${acento}` } : undefined}
                        >
                          <span className="line-clamp-2 text-sm font-bold leading-snug text-white">{p.nombre}</span>
                          {conOpciones && (
                            <span
                              className="mt-1.5 inline-flex w-fit rounded-full px-2 py-0.5 text-[10px] font-extrabold uppercase tracking-wide"
                              style={{ background: `${acento}26`, color: acento }}
                            >
                              Se arma al gusto
                            </span>
                          )}
                          <span className="mt-auto flex items-end justify-between pt-2">
                            <span className="text-base font-black tabular-nums" style={{ color: acento }}>
                              {pt.desde && <span className="mr-1 text-[11px] font-extrabold uppercase tracking-wide text-white/60">Desde</span>}
                              {pt.texto}
                            </span>
                            {cant > 0 && (
                              <span className="grid h-7 min-w-7 place-items-center rounded-full px-2 text-sm font-black" style={{ background: marca, color: txtMarca }}>
                                {cant}
                              </span>
                            )}
                          </span>
                        </button>
                      );
                    })}
                  </div>
                </div>
              ))}
            </div>
          )}
        </div>

        {/* Fondo oscuro detras de la hoja (solo telefono, con la hoja abierta) */}
        {hoja && <div className="absolute inset-0 z-20 bg-black/50 lg:hidden" onClick={() => setHoja(false)} />}

        {/* Carrito / cobro: hoja que sube en el telefono, columna fija en pantalla grande */}
        <div
          className={`flex min-h-0 flex-col bg-panel shadow-2xl transition-transform duration-300 ${
            hoja ? 'translate-y-0' : 'translate-y-full'
          } absolute inset-x-0 bottom-0 z-30 max-h-[88vh] rounded-t-2xl border-t border-white/10 lg:static lg:z-auto lg:max-h-none lg:w-[26rem] lg:translate-y-0 lg:rounded-none lg:border-l lg:border-t-0 lg:shadow-none`}
        >
          {/* Cabecera de la hoja (solo telefono) */}
          <div className="flex shrink-0 items-center justify-between border-b border-white/10 px-4 py-3 lg:hidden">
            <div className="flex items-center gap-3">
              <span className="h-1 w-9 rounded-full bg-white/25" />
              <p className="text-base font-extrabold">Tu pedido{nItems ? ` · ${nItems} art.` : ''}</p>
            </div>
            <button onClick={() => setHoja(false)} className="rounded-lg px-3 py-1.5 text-sm font-bold text-white/80 hover:bg-white/10">
              Seguir agregando
            </button>
          </div>

          <div className="min-h-0 flex-1 overflow-y-auto p-4">
            {lineas.length === 0 ? (
              <p className="py-8 text-center text-[15px] font-medium text-white/60">Toca productos para agregarlos.</p>
            ) : (
              <div className="space-y-2">
                {lineas.map((l) => (
                  <div key={l.uid} className="flex items-start gap-2.5 rounded-xl bg-white/[.05] p-2.5 ring-1 ring-white/10">
                    <div className="flex shrink-0 items-center rounded-full bg-white/10">
                      <button className="grid h-9 w-9 place-items-center text-xl leading-none text-white/90" onClick={() => setCantidad(l.uid, l.cantidad - 1)}>−</button>
                      <span className="w-6 text-center text-[15px] font-extrabold tabular-nums">{l.cantidad}</span>
                      <button className="grid h-9 w-9 place-items-center text-xl leading-none text-white/90" onClick={() => setCantidad(l.uid, l.cantidad + 1)}>+</button>
                    </div>
                    <div className="min-w-0 flex-1 pt-0.5">
                      <span className="block truncate text-[15px] font-bold text-white">{l.nombre}</span>
                      {l.texto && <span className="mt-0.5 block text-[13px] font-medium leading-snug text-white/75">{l.texto}</span>}
                    </div>
                    <span className="shrink-0 pt-1 text-[15px] font-extrabold tabular-nums">{usd(l.precio_usd * l.cantidad)}</span>
                  </div>
                ))}
              </div>
            )}

            <div className="mt-4 space-y-3.5">
              <div className="grid grid-cols-2 gap-2">
                <input
                  className="rounded-xl border border-white/15 bg-superficie-2 px-3 py-2.5 text-sm font-medium outline-none placeholder:text-white/45 focus:border-white/35"
                  placeholder={tipo === 'mesa' ? '¿Para quién? (Pedro, silla 3...)' : 'Cliente (opcional)'}
                  value={nombre}
                  onChange={(e) => setNombre(e.target.value)}
                />
                <input
                  className="rounded-xl border border-white/15 bg-superficie-2 px-3 py-2.5 text-sm font-medium outline-none placeholder:text-white/45 focus:border-white/35"
                  placeholder="Teléfono (opcional)"
                  inputMode="tel"
                  value={telefono}
                  onChange={(e) => setTelefono(e.target.value)}
                />
              </div>

              <div>
                {/* Si ya se entro DESDE una mesa puntual (mesaInicial), la entrega
                    queda fija en esa mesa: no tiene sentido ofrecer Mostrador/Delivery
                    ni dejar cambiar el numero por error. Las 3 opciones solo aparecen
                    cuando el punto de venta se abre de forma general (sin mesa). */}
                {!mesaInicial && (
                  <>
                    <p className="mb-1.5 text-[13px] font-bold text-white/80">Entrega</p>
                    <div className="grid grid-cols-3 gap-2">
                      {ENTREGAS.map((e) => (
                        <button
                          key={e.v}
                          onClick={() => setTipo(e.v)}
                          className="rounded-xl py-2.5 text-[13px] font-bold ring-1 transition"
                          style={
                            tipo === e.v
                              ? { background: marca, color: txtMarca, ['--tw-ring-color' as string]: 'transparent' }
                              : { color: 'rgba(255,255,255,.85)', ['--tw-ring-color' as string]: 'rgba(255,255,255,.2)' }
                          }
                        >
                          {e.label}
                        </button>
                      ))}
                    </div>
                  </>
                )}
                {tipo === 'mesa' && (
                  <>
                    {mesaInicial ? (
                      <p className="mt-2 rounded-xl bg-superficie-2 px-3 py-2.5 text-sm font-bold text-white">
                        Mesa {mesaInicial}
                      </p>
                    ) : (
                      <input
                        className="mt-2 w-full rounded-xl border border-white/15 bg-superficie-2 px-3 py-2.5 text-sm font-medium outline-none placeholder:text-white/45 focus:border-white/35"
                        placeholder="Número de mesa"
                        value={mesa}
                        onChange={(e) => {
                          setMesa(e.target.value);
                          setComensalId('');
                        }}
                      />
                    )}
                    {cuentaMesa && (
                      <p
                        className={`mt-1.5 rounded-lg px-3 py-2 text-[13px] font-bold ${
                          mesaAjena
                            ? 'bg-amber-500/15 text-amber-200 ring-1 ring-amber-500/40'
                            : 'bg-white/5 text-white/70 ring-1 ring-white/10'
                        }`}
                      >
                        {mesaAjena
                          ? `⚠ Esta mesa la atiende ${cuentaMesa.mesero_nombre}. El pedido se sumará a su cuenta.`
                          : `Mesa con cuenta abierta${cuentaMesa.mesero_nombre ? ` · atiende ${cuentaMesa.mesero_nombre}` : ''}: el pedido se suma a la cuenta.`}
                      </p>
                    )}
                    {comensales.length > 0 && (
                      <div className="mt-2">
                        <p className="mb-1 text-[13px] font-bold text-white/80">¿Para quién?</p>
                        <div className="flex flex-wrap gap-1.5">
                          <button
                            onClick={() => setComensalId('')}
                            className="rounded-lg px-3 py-1.5 text-[13px] font-bold ring-1 transition"
                            style={
                              comensalId === ''
                                ? { background: marca, color: txtMarca, ['--tw-ring-color' as string]: 'transparent' }
                                : { color: 'rgba(255,255,255,.85)', ['--tw-ring-color' as string]: 'rgba(255,255,255,.2)' }
                            }
                          >
                            La mesa
                          </button>
                          {comensales.map((cm) => (
                            <button
                              key={cm.id}
                              onClick={() => setComensalId(cm.id)}
                              className="rounded-lg px-3 py-1.5 text-[13px] font-bold ring-1 transition"
                              style={
                                comensalId === cm.id
                                  ? { background: marca, color: txtMarca, ['--tw-ring-color' as string]: 'transparent' }
                                  : { color: 'rgba(255,255,255,.85)', ['--tw-ring-color' as string]: 'rgba(255,255,255,.2)' }
                              }
                            >
                              {cm.nombre}
                            </button>
                          ))}
                        </div>
                      </div>
                    )}
                    <div className="mt-2">
                      <p className="mb-1 text-[13px] font-bold text-white/80">¿Cómo va este pedido?</p>
                      <div className="grid grid-cols-2 gap-1.5">
                        {[
                          { v: false, label: 'Para comer aquí' },
                          { v: true, label: 'Para llevar' },
                        ].map((o) => (
                          <button
                            key={String(o.v)}
                            onClick={() => setParaLlevar(o.v)}
                            className="rounded-lg px-3 py-1.5 text-[13px] font-bold ring-1 transition"
                            style={
                              paraLlevar === o.v
                                ? { background: marca, color: txtMarca, ['--tw-ring-color' as string]: 'transparent' }
                                : { color: 'rgba(255,255,255,.85)', ['--tw-ring-color' as string]: 'rgba(255,255,255,.2)' }
                            }
                          >
                            {o.label}
                          </button>
                        ))}
                      </div>
                    </div>
                    <div className="mt-2">
                      <p className="mb-1 text-[13px] font-bold text-white/80">Tiempo estimado (opcional)</p>
                      <div className="flex items-center gap-2">
                        <input
                          type="number"
                          min="1"
                          placeholder="min"
                          className="w-20 rounded-xl border border-white/15 bg-superficie-2 px-3 py-2 text-sm font-medium text-white outline-none placeholder:text-white/45 focus:border-white/35"
                          value={tiempoMin}
                          onChange={(e) => setTiempoMin(e.target.value)}
                        />
                        <span className="text-[13px] text-white/60">min · se lo avisamos al cliente de una vez, sin que el panel tenga que ponerlo después</span>
                      </div>
                    </div>
                  </>
                )}
                {tipo === 'delivery' && (
                  <>
                    <input
                      className="mt-2 w-full rounded-xl border border-white/15 bg-superficie-2 px-3 py-2.5 text-sm font-medium outline-none placeholder:text-white/45 focus:border-white/35"
                      placeholder="Dirección de entrega"
                      value={direccion}
                      onChange={(e) => setDireccion(e.target.value)}
                    />
                    <select
                      className="mt-2 w-full rounded-xl border border-white/15 bg-superficie-2 px-3 py-2.5 text-sm font-medium text-white outline-none focus:border-white/35"
                      value={repartidor}
                      onChange={(e) => setRepartidor(e.target.value)}
                    >
                      <option value="">Asignar repartidor (opcional)</option>
                      {repartidores.map((r) => (
                        <option key={r.repartidor_id} value={r.repartidor_id}>
                          {r.nombre ?? 'Repartidor'}
                          {r.vehiculo ? ` · ${r.vehiculo}` : ''} ({r.estado})
                        </option>
                      ))}
                    </select>
                    {repartidoresQ.data && repartidores.length === 0 && (
                      <p className="mt-1 text-xs font-semibold text-white/60">
                        No tienes repartidores registrados. Créalos en la sección Repartidores.
                      </p>
                    )}
                  </>
                )}
              </div>

              <div>
                <p className="mb-1.5 text-[13px] font-bold text-white/80">Pago</p>
                {tipo === 'mesa' ? (
                  <p className="rounded-xl bg-superficie-2 px-3 py-2.5 text-sm text-white/60">
                    Esto se suma a la cuenta de la mesa. Se cobra al final, desde Mesas.
                  </p>
                ) : (
                  <>
                    <select
                      value={metodo}
                      onChange={(e) => setMetodo(e.target.value as Metodo)}
                      className="w-full rounded-xl border border-white/15 bg-superficie-2 px-3 py-2.5 text-sm font-bold text-white outline-none focus:border-white/35"
                    >
                      {METODOS.map((m) => (
                        <option key={m.v} value={m.v}>
                          {m.label}
                        </option>
                      ))}
                    </select>
                    {esPagoOnline && (
                      <>
                        <input
                          className={`mt-2 w-full rounded-xl border bg-superficie-2 px-3 py-2.5 text-sm font-medium outline-none placeholder:text-white/45 focus:border-white/35 ${
                            faltaRef ? 'border-red-500/60' : 'border-white/15'
                          }`}
                          placeholder={etiquetaReferencia(metodo)}
                          value={referencia}
                          onChange={(e) => setReferencia(e.target.value)}
                        />
                        {faltaRef && <p className="mt-1 text-[12px] font-semibold text-red-400">{faltaRef}</p>}
                        <label className="mt-2 flex cursor-pointer items-center justify-between gap-2 rounded-xl border border-dashed border-white/20 bg-superficie-2 px-3 py-2.5 text-sm font-medium text-white/70">
                          <span className="truncate">{comprobante ? comprobante.name : 'Foto del comprobante (opcional)'}</span>
                          <span
                            className="shrink-0 rounded-lg px-2.5 py-1 text-xs font-bold"
                            style={{ background: marca, color: txtMarca }}
                          >
                            {comprobante ? 'Cambiar' : 'Tomar foto'}
                          </span>
                          <input
                            type="file"
                            accept="image/*"
                            className="hidden"
                            onChange={(e) => setComprobante(e.target.files?.[0] ?? null)}
                          />
                        </label>
                      </>
                    )}
                  </>
                )}
                {/* Datos del comprador: no es un interruptor, la venta se sella
                    igual. Solo cambia si sale con sus datos o como Consumidor
                    Final. En mesa no va: eso se pregunta al cobrar, en Mesas. */}
                {facturaActiva && tipo !== 'mesa' && <DatosFactura valor={fiscal} onCambio={setFiscal} />}
              </div>
            </div>
          </div>

          {/* Pie: total + accion */}
          <div className="shrink-0 border-t border-white/10 p-4">
            <div className="mb-3 flex items-baseline justify-between">
              <span className="text-sm font-bold text-white/75">Total {nItems ? `· ${nItems} art.` : ''}</span>
              <span className="text-right">
                <span className="block text-3xl font-black tabular-nums">{usd(total)}</span>
                {restaurante.tasa_bs && restaurante.tasa_bs > 0 && (
                  <span className="block text-[13px] font-bold tabular-nums text-white/65">
                    {formatBs(bsDesdeUsd(total, restaurante.tasa_bs))}
                  </span>
                )}
              </span>
            </div>
            <button
              onClick={crear}
              disabled={enviando || !lineas.length || !!faltaRef}
              className="w-full rounded-xl py-3.5 text-base font-extrabold shadow-lg transition active:scale-[.99] disabled:opacity-50"
              style={{ background: marca, color: txtMarca }}
            >
              {enviando ? 'Creando…' : 'Crear pedido'}
            </button>
          </div>
        </div>

        {/* Barra inferior (solo telefono, con la hoja cerrada): abre la hoja para
            revisar y enviar el pedido. NO cobra nada aqui (el cobro real de la
            mesa es aparte, en Mesas): el texto no debe prometer "cobrar" donde
            solo se revisa y se manda a cocina. */}
        {!hoja && (
          <div className="absolute inset-x-0 bottom-0 z-10 border-t border-white/10 bg-panel/95 p-3 backdrop-blur lg:hidden">
            <button
              onClick={() => setHoja(true)}
              disabled={!lineas.length}
              className="flex w-full items-center justify-between rounded-xl px-4 py-3.5 text-base font-extrabold shadow-lg transition active:scale-[.99] disabled:opacity-60"
              style={{ background: marca, color: txtMarca }}
            >
              <span>{lineas.length ? 'Ver pedido' : 'Toca un producto para empezar'}</span>
              {nItems > 0 && <span className="tabular-nums">{nItems} art · {usd(total)}</span>}
            </button>
          </div>
        )}
      </div>

      {prodAbierto && (
        <PosOpciones
          prod={prodAbierto}
          marca={marca}
          txtMarca={txtMarca}
          acento={acento}
          onAgregar={agregarLineas}
          onCerrar={() => setProdAbierto(null)}
        />
      )}

      {confirmSalir && (
        <div
          className="fixed inset-0 z-[70] flex items-center justify-center bg-black/70 p-4"
          onClick={() => setConfirmSalir(false)}
        >
          <div
            className="w-full max-w-sm rounded-2xl bg-superficie p-5 text-white ring-1 ring-white/15"
            onClick={(e) => e.stopPropagation()}
          >
            <p className="text-lg font-extrabold">¿Seguro que quieres salir?</p>
            <p className="mt-1.5 text-sm text-white/70">Vas a perder el pedido que llevas armado.</p>
            <div className="mt-4 flex gap-2">
              <button
                onClick={() => setConfirmSalir(false)}
                className="flex-1 rounded-xl border border-white/15 py-2.5 text-sm font-bold text-white/85 hover:bg-white/10"
              >
                Seguir aquí
              </button>
              <button
                onClick={() => {
                  setConfirmSalir(false);
                  onClose();
                }}
                className="flex-1 rounded-xl py-2.5 text-sm font-extrabold shadow-lg"
                style={{ background: marca, color: txtMarca }}
              >
                Sí, salir
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

// ── Selector de opciones para caja: mismo modelo de la tienda del comensal ──
// (cantidad por opcion para empanadas; marcar contornos/proteina para arepas)
function PosOpciones({
  prod,
  marca,
  txtMarca,
  acento,
  onAgregar,
  onCerrar,
}: {
  prod: Prod;
  marca: string;
  txtMarca: string;
  acento: string;
  onAgregar: (nuevas: Omit<Linea, 'uid'>[]) => void;
  onCerrar: () => void;
}) {
  // useMemo: para productos sin opciones, `?? []` seria un array nuevo por
  // render y el memo de abajo (extra/elegidas) recalcularia de gratis.
  const grupos = useMemo(() => prod.opciones ?? [], [prod.opciones]);
  const grupoCantidad = grupos.find((g) => g.tipo === 'cantidad');

  // ── Modo cantidad por opcion (ej. empanadas: 3 de queso, 2 de pollo) ──
  const [cantOp, setCantOp] = useState<Record<string, number>>({});
  // ── Modo marcar (ej. arepas: proteina single + contornos multi) ──
  const [sel, setSel] = useState<Record<number, string[]>>({});
  const [cant, setCant] = useState(1);
  const [err, setErr] = useState<string | null>(null);

  const modoCantidad = !!grupoCantidad;

  const { totalCant, unidades } = useMemo(() => {
    if (!grupoCantidad) return { totalCant: 0, unidades: 0 };
    let t = 0;
    let u = 0;
    for (const o of grupoCantidad.opciones) {
      const q = cantOp[o.nombre] ?? 0;
      t += (prod.precio_usd + o.precio_extra) * q;
      u += q;
    }
    return { totalCant: t, unidades: u };
  }, [cantOp, grupoCantidad, prod.precio_usd]);

  const { extra, elegidas, elegidasSel, texto } = useMemo(() => {
    let extra = 0;
    const elegidas: string[] = [];
    const elegidasSel: { g: string; o: string }[] = [];
    const partes: string[] = [];
    grupos.forEach((g, gi) => {
      if (g.tipo === 'cantidad') return;
      const nombres = sel[gi] ?? [];
      if (nombres.length) partes.push(`${g.nombre}: ${nombres.join(', ')}`);
      nombres.forEach((n) => {
        elegidas.push(n);
        elegidasSel.push({ g: g.nombre, o: n });
        const op = g.opciones.find((o) => o.nombre === n);
        if (op) extra += op.precio_extra;
      });
    });
    return { extra, elegidas, elegidasSel, texto: partes.join(' · ') };
  }, [sel, grupos]);

  function toggle(gi: number, g: OpcionGrupo, nombre: string) {
    setErr(null);
    setSel((prev) => {
      const cur = prev[gi] ?? [];
      if (g.tipo === 'single') return { ...prev, [gi]: cur.includes(nombre) ? [] : [nombre] };
      const on = cur.includes(nombre);
      if (on) return { ...prev, [gi]: cur.filter((x) => x !== nombre) };
      if (g.max && cur.length >= g.max) return prev;
      return { ...prev, [gi]: [...cur, nombre] };
    });
  }

  function confirmar() {
    if (modoCantidad && grupoCantidad) {
      if (unidades === 0) {
        setErr('Elige al menos una.');
        return;
      }
      const nuevas = grupoCantidad.opciones
        .filter((o) => (cantOp[o.nombre] ?? 0) > 0)
        .map((o) => ({
          producto_id: prod.id,
          nombre: prod.nombre,
          precio_usd: prod.precio_usd + o.precio_extra,
          cantidad: cantOp[o.nombre],
          opciones: [o.nombre],
          opcionesSel: [{ g: grupoCantidad.nombre, o: o.nombre }],
          texto: o.nombre,
        }));
      onAgregar(nuevas);
      onCerrar();
      return;
    }
    for (let gi = 0; gi < grupos.length; gi++) {
      if (grupos[gi].tipo !== 'cantidad' && grupos[gi].obligatorio && !(sel[gi]?.length)) {
        setErr(`Elige una opción en "${grupos[gi].nombre}"`);
        return;
      }
    }
    onAgregar([
      {
        producto_id: prod.id,
        nombre: prod.nombre,
        precio_usd: prod.precio_usd + extra,
        cantidad: cant,
        opciones: elegidas,
        opcionesSel: elegidasSel,
        texto,
      },
    ]);
    onCerrar();
  }

  const totalPie = modoCantidad ? totalCant : (prod.precio_usd + extra) * cant;
  const puedeConfirmar = modoCantidad ? unidades > 0 : true;

  return (
    <div className="fixed inset-0 z-[60] flex items-end justify-center bg-black/70 sm:items-center" onClick={onCerrar}>
      <div
        className="flex max-h-[92vh] w-full max-w-lg flex-col overflow-hidden rounded-t-2xl bg-superficie text-white ring-1 ring-white/15 sm:rounded-2xl"
        onClick={(e) => e.stopPropagation()}
      >
        <div className="flex items-center justify-between border-b border-white/10 p-4">
          <div className="min-w-0">
            <h3 className="truncate text-lg font-extrabold">{prod.nombre}</h3>
            <p className="text-[13px] font-medium text-white/65">{modoCantidad ? 'Elige cuántas de cada una' : 'Arma el pedido al gusto del cliente'}</p>
          </div>
          <button onClick={onCerrar} className="grid h-9 w-9 shrink-0 place-items-center rounded-full bg-white/10 text-xl leading-none text-white/80 hover:text-white">&times;</button>
        </div>

        <div className="min-h-0 flex-1 overflow-y-auto p-4">
          {modoCantidad && grupoCantidad ? (
            <div>
              <p className="mb-2 text-[15px] font-extrabold">{grupoCantidad.nombre}</p>
              <div className="space-y-2">
                {grupoCantidad.opciones.map((o) => {
                  const q = cantOp[o.nombre] ?? 0;
                  return (
                    <div
                      key={o.nombre}
                      className="flex items-center justify-between rounded-xl bg-superficie-2 px-3.5 py-3 ring-1 ring-white/15"
                      style={q > 0 ? { boxShadow: `inset 0 0 0 2px ${acento}` } : undefined}
                    >
                      <div className="min-w-0">
                        <p className="truncate text-[15px] font-bold text-white">{o.nombre}</p>
                        <p className="text-[13px] font-extrabold" style={{ color: acento }}>{usd(prod.precio_usd + o.precio_extra)} c/u</p>
                      </div>
                      <div className="flex items-center gap-2.5">
                        <button
                          onClick={() => { setErr(null); setCantOp((p) => ({ ...p, [o.nombre]: Math.max(0, (p[o.nombre] ?? 0) - 1) })); }}
                          disabled={q === 0}
                          className="grid h-10 w-10 place-items-center rounded-full bg-white/10 text-xl text-white/90 disabled:opacity-40"
                        >
                          −
                        </button>
                        <span className="w-6 text-center text-base font-extrabold tabular-nums">{q}</span>
                        <button
                          onClick={() => { setErr(null); setCantOp((p) => ({ ...p, [o.nombre]: (p[o.nombre] ?? 0) + 1 })); }}
                          className="grid h-10 w-10 place-items-center rounded-full text-xl"
                          style={{ background: marca, color: txtMarca }}
                        >
                          +
                        </button>
                      </div>
                    </div>
                  );
                })}
              </div>
            </div>
          ) : (
            <div className="space-y-5">
              {grupos.map((g, gi) => {
                if (g.tipo === 'cantidad') return null;
                const cur = sel[gi] ?? [];
                return (
                  <div key={gi}>
                    <div className="mb-2 flex items-center gap-2">
                      <h4 className="text-[15px] font-extrabold">{g.nombre}</h4>
                      {g.obligatorio ? (
                        <span className="rounded-full px-2 py-0.5 text-[11px] font-extrabold" style={{ background: `${acento}26`, color: acento }}>Obligatorio</span>
                      ) : (
                        <span className="text-[12px] font-semibold text-white/50">Opcional</span>
                      )}
                      {g.tipo === 'multi' && g.max ? <span className="text-[12px] font-semibold text-white/50">Hasta {g.max}</span> : null}
                    </div>
                    <div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
                      {g.opciones.map((o) => {
                        const on = cur.includes(o.nombre);
                        return (
                          <button
                            key={o.nombre}
                            type="button"
                            onClick={() => toggle(gi, g, o.nombre)}
                            className="flex items-center justify-between rounded-xl bg-superficie-2 px-3.5 py-3 text-left text-[15px] font-bold ring-1 ring-white/15 transition active:scale-[.99]"
                            style={on ? { boxShadow: `inset 0 0 0 2px ${acento}` } : undefined}
                          >
                            <span className="flex min-w-0 items-center gap-2.5">
                              <span
                                className={`grid h-6 w-6 shrink-0 place-items-center border-2 text-sm font-black ${g.tipo === 'single' ? 'rounded-full' : 'rounded-md'}`}
                                style={on ? { background: marca, borderColor: marca, color: txtMarca } : { borderColor: 'rgba(255,255,255,.3)', color: 'transparent' }}
                              >
                                ✓
                              </span>
                              <span className="truncate text-white">{o.nombre}</span>
                            </span>
                            {o.precio_extra > 0 && <span className="shrink-0 pl-2 text-[13px] font-extrabold" style={{ color: acento }}>+{usd(o.precio_extra)}</span>}
                          </button>
                        );
                      })}
                    </div>
                  </div>
                );
              })}

              <div className="flex items-center justify-between rounded-xl bg-superficie-2 px-3.5 py-3 ring-1 ring-white/15">
                <span className="text-[15px] font-extrabold">¿Cuántos así?</span>
                <div className="flex items-center gap-2.5">
                  <button
                    onClick={() => setCant((c) => Math.max(1, c - 1))}
                    disabled={cant <= 1}
                    className="grid h-10 w-10 place-items-center rounded-full bg-white/10 text-xl text-white/90 disabled:opacity-40"
                  >
                    −
                  </button>
                  <span className="w-6 text-center text-base font-extrabold tabular-nums">{cant}</span>
                  <button
                    onClick={() => setCant((c) => c + 1)}
                    className="grid h-10 w-10 place-items-center rounded-full text-xl"
                    style={{ background: marca, color: txtMarca }}
                  >
                    +
                  </button>
                </div>
              </div>
            </div>
          )}
        </div>

        <div className="border-t border-white/10 p-4">
          {err && <p className="mb-2 rounded-lg bg-red-500/15 px-3 py-2 text-[13px] font-bold text-red-200 ring-1 ring-red-500/40">{err}</p>}
          <button
            onClick={confirmar}
            disabled={!puedeConfirmar}
            className="flex w-full items-center justify-between rounded-xl px-5 py-3.5 text-base font-extrabold shadow-lg transition active:scale-[.99] disabled:opacity-50"
            style={{ background: marca, color: txtMarca }}
          >
            <span>{modoCantidad ? `Agregar ${unidades > 0 ? `${unidades} ` : ''}${unidades === 1 ? 'unidad' : 'unidades'}` : `Agregar ${cant > 1 ? `${cant} ` : ''}al pedido`}</span>
            <span className="tabular-nums">{usd(totalPie)}</span>
          </button>
        </div>
      </div>
    </div>
  );
}

function traducir(msg: string): string {
  if (/cerrado/i.test(msg)) return 'El negocio está cerrado. Toca "Abrir" en el panel para tomar pedidos.';
  if (/carrito/i.test(msg)) return 'Agrega al menos un producto.';
  if (/agotado/i.test(msg)) return msg; // "Producto agotado: X" ya es claro
  return msg;
}
