/* panel-marketplace.jsx — módulos del MARKETPLACE en el panel del restaurante:
   Productos y menú · Fotos del negocio · Perfil público · Métodos de pago ·
   Pedidos del marketplace (Realtime + alerta sonora).
   Sigue el sistema de diseño existente del panel (card/btn/set-field/sw/pill). */
const { useState: mkpS, useEffect: mkpE, useRef: mkpR, useMemo: mkpM } = React;

/* ── Utilidades ──────────────────────────────────────────────────────────── */

/* beep de alerta (WebAudio, dos tonos) — no requiere archivos de audio */
function mkpBeep() {
  try {
    const ctx = window.__treegoMkAudio || (window.__treegoMkAudio = new (window.AudioContext || window.webkitAudioContext)());
    if (ctx.state === "suspended") ctx.resume();
    [[880, 0], [1320, 0.18]].forEach(([f, t]) => {
      const o = ctx.createOscillator(), g = ctx.createGain();
      o.type = "sine"; o.frequency.value = f;
      g.gain.setValueAtTime(0.0001, ctx.currentTime + t);
      g.gain.exponentialRampToValueAtTime(0.22, ctx.currentTime + t + 0.02);
      g.gain.exponentialRampToValueAtTime(0.0001, ctx.currentTime + t + 0.35);
      o.connect(g); g.connect(ctx.destination);
      o.start(ctx.currentTime + t); o.stop(ctx.currentTime + t + 0.4);
    });
  } catch (e) { /* sin audio */ }
}

/* Notificación del navegador (Web Notifications API): avisa aunque el panel
   esté en otra pestaña. Trae los items para el resumen de productos. */
async function mkpNotificarNavegador(p) {
  try {
    if (!("Notification" in window) || Notification.permission !== "granted") return;
    let resumen = "";
    try {
      const { data: its } = await window.treego_db
        .from("items_pedido_marketplace")
        .select("cantidad, nombre_producto")
        .eq("pedido_marketplace_id", p.id);
      resumen = (its || []).map((i) => `${i.cantidad}x ${i.nombre_producto}`).join(", ");
    } catch (e) { /* sin resumen */ }
    const n = new Notification(`🛎️ Nuevo pedido de ${p.cliente_nombre}`, {
      body: `${resumen || "Pedido #" + p.id} · Total ${fmtCOP(p.total)}`,
      icon: "/assets/streego-icon.png?v=2",
      tag: "treego-mk-" + p.id,
    });
    n.onclick = () => { window.focus(); n.close(); };
  } catch (e) { /* la Notification API puede no estar disponible */ }
}

/* Canal Realtime GLOBAL de pedidos del marketplace: suena y avisa aunque el
   restaurante esté en otra sección del panel. Se crea una sola vez por sesión. */
function treegoMkAlertaInit(restId) {
  if (!window.treego_db || !restId || window.__treegoMkPedsChannel) return;
  /* pedir permiso de notificaciones del navegador (una sola vez) */
  try {
    if ("Notification" in window && Notification.permission === "default") {
      Notification.requestPermission();
    }
  } catch (e) { /* sin soporte */ }
  window.__treegoMkPedsChannel = window.treego_db
    .channel(`mk-pedidos-rest-${restId}`)
    .on("postgres_changes", {
      event: "INSERT", schema: "public", table: "pedidos_marketplace",
      filter: `restaurante_id=eq.${restId}`,
    }, (payload) => {
      mkpBeep();
      mkpNotificarNavegador(payload.new);
      window.dispatchEvent(new CustomEvent("treego-mk-nuevo", { detail: payload.new }));
    })
    .on("postgres_changes", {
      event: "UPDATE", schema: "public", table: "pedidos_marketplace",
      filter: `restaurante_id=eq.${restId}`,
    }, () => {
      window.dispatchEvent(new CustomEvent("treego-mk-cambio"));
    })
    .subscribe();
}

/* Perfil público del restaurante: lo crea si no existe (slug único). */
async function mkpAsegurarPerfil(restId) {
  const db = window.treego_db;
  const { data: perfil } = await db.from("perfil_restaurante_publico")
    .select("*").eq("restaurante_id", restId).maybeSingle();
  if (perfil) return perfil;
  const base = mkSlugify((S.rest && S.rest.name) || "restaurante") || "restaurante";
  for (let i = 0; i < 8; i++) {
    const slug = i === 0 ? base : `${base}-${i + 1}`;
    const { data, error } = await db.from("perfil_restaurante_publico")
      .insert({ restaurante_id: restId, slug })
      .select("*").single();
    if (!error && data) return data;
    if (error && error.code !== "23505") {
      console.error("[Treego] No se pudo crear el perfil del marketplace:", error.message);
      return null;
    }
  }
  return null;
}

/* Subida de foto al bucket del marketplace (carpeta: portadas|logos|productos) */
async function mkpSubirFoto(carpeta, restId, file) {
  return window.treegoSubirFoto("marketplace-fotos", `${carpeta}/rest_${restId}`, file);
}

/* Avisos al cliente (correo Resend + WhatsApp preparado): fire-and-forget —
   si fallan no bloquean el flujo del pedido; queda registro en consola.
   enviar-whatsapp no envía nada real hasta configurar WHATSAPP_TOKEN (F6). */
function mkpAvisarCliente(pedidoMkId, accion) {
  try {
    window.treego_db.functions.invoke("notificar-cliente-mk", {
      body: { pedido_mk_id: pedidoMkId, accion },
    }).then(({ error }) => {
      if (error) console.warn("[Treego] correo al cliente no enviado:", error.message || error);
    }).catch((e) => console.warn("[Treego] correo al cliente no enviado:", e));
    window.treego_db.functions.invoke("enviar-whatsapp", {
      body: { pedido_mk_id: pedidoMkId, accion },
    }).catch(() => { /* preparado pero sin conectar (Fase 6) */ });
  } catch (e) { /* sin funciones */ }
}

const MKP_ESTADOS = {
  pendiente:  ["Pendiente",   "pill-warn"],
  confirmado: ["Confirmado",  "pill-brand"],
  preparando: ["Preparando",  "pill-brand"],
  listo:      ["Listo",       "pill-brand"],
  asignado:   ["Repartidor asignado", "pill-brand"],
  en_camino:  ["En camino",   "pill-brand"],
  entregado:  ["Entregado",   "pill-ok"],
  cancelado:  ["Cancelado",   "pill-mut"],
};
const MKP_PAGOS = { efectivo: "Efectivo", transferencia: "Transferencia", nequi: "Nequi", daviplata: "Daviplata" };

/* input de foto reutilizable: valida y previsualiza; sube al guardar */
function MkpFotoInput({ label, actual, alto, onFile }) {
  const inputRef = mkpR(null);
  const [preview, setPreview] = mkpS(null);
  const [err, setErr] = mkpS("");
  const elegir = (e) => {
    const f = e.target.files && e.target.files[0];
    if (!f) return;
    const invalida = window.treegoValidarFoto(f);
    if (invalida) { setErr(invalida); return; }
    setErr("");
    setPreview(URL.createObjectURL(f));
    onFile(f);
  };
  const src = preview || actual;
  return (
    <div className="set-field">
      <label>{label}</label>
      <div onClick={() => inputRef.current && inputRef.current.click()}
        style={{ height: alto || 150, borderRadius: 14, border: "1.5px dashed var(--line-2)",
                 background: "var(--panel-2)", cursor: "pointer", overflow: "hidden",
                 display: "grid", placeItems: "center", position: "relative" }}>
        {src
          ? <img src={src} alt="" style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
          : <div className="muted" style={{ fontSize: 13, display: "flex", alignItems: "center", gap: 8 }}>
              <MkIcon name="upload" /> Haz clic para subir (JPG/PNG, máx. 2 MB)
            </div>}
      </div>
      <input ref={inputRef} type="file" accept="image/jpeg,image/png" style={{ display: "none" }} onChange={elegir} />
      {err && <div className="muted" style={{ color: "var(--red)", fontSize: 12.5, marginTop: 6 }}>{err}</div>}
    </div>
  );
}

/* ═══ 3.1 PRODUCTOS Y MENÚ ═══════════════════════════════════════════════ */

function MkpModalProducto({ restId, producto, categorias, onClose, onSaved, onNuevaCategoria }) {
  const [f, setF] = mkpS(producto || { nombre: "", descripcion: "", precio: "", categoria_id: "", disponible: true });
  const [file, setFile] = mkpS(null);
  const [busy, setBusy] = mkpS(false);
  const [err, setErr] = mkpS("");
  const [nuevaCat, setNuevaCat] = mkpS("");
  const set = (k, v) => setF((s) => ({ ...s, [k]: v }));

  async function guardar() {
    if (busy) return;
    if (!f.nombre.trim()) { setErr("El nombre es obligatorio."); return; }
    const precio = Number(String(f.precio).replace(/[^\d]/g, ""));
    if (!precio) { setErr("El precio es obligatorio."); return; }
    setBusy(true); setErr("");

    let categoriaId = f.categoria_id || null;
    if (categoriaId === "__nueva__") {
      const nombre = nuevaCat.trim();
      if (!nombre) { setErr("Escribe el nombre de la nueva categoría."); setBusy(false); return; }
      const { data: cat, error: catErr } = await window.treego_db.from("categorias_menu")
        .insert({ restaurante_id: restId, nombre, orden: categorias.length })
        .select("*").single();
      if (catErr || !cat) { setErr("No se pudo crear la categoría."); setBusy(false); return; }
      categoriaId = cat.id;
      onNuevaCategoria(cat);
    }

    let imagen_url = f.imagen_url || null;
    if (file) {
      const up = await mkpSubirFoto("productos", restId, file);
      if (up.error) { setErr(up.error); setBusy(false); return; }
      imagen_url = up.url;
    }

    const fila = {
      restaurante_id: restId,
      categoria_id: categoriaId,
      nombre: f.nombre.trim(),
      descripcion: f.descripcion ? f.descripcion.trim() : null,
      precio, imagen_url,
      disponible: !!f.disponible,
    };
    const q = producto && producto.id
      ? window.treego_db.from("productos").update(fila).eq("id", producto.id)
      : window.treego_db.from("productos").insert(fila);
    const { error } = await q;
    setBusy(false);
    if (error) { setErr("No se pudo guardar el producto. Intenta de nuevo."); return; }
    onSaved();
  }

  return (
    <div className="pd-pin-overlay" onClick={onClose}>
      <div className="pd-pin-modal" onClick={(e) => e.stopPropagation()} style={{ maxHeight: "calc(100vh - 40px)", overflowY: "auto" }}>
        <div className="between" style={{ marginBottom: 14 }}>
          <b style={{ fontSize: 17 }}>{producto ? "Editar producto" : "Nuevo producto"}</b>
          <button type="button" className="pd-pin-x" onClick={onClose} aria-label="Cerrar"><span aria-hidden>✕</span></button>
        </div>
        {err && <div className="login-err"><Icon name="flag" style={{ width: 15, height: 15 }} />{err}</div>}

        <MkpFotoInput label="Foto del producto (opcional)" actual={f.imagen_url} onFile={setFile} />

        <div className="set-field">
          <label>Nombre del producto *</label>
          <input value={f.nombre} onChange={(e) => set("nombre", e.target.value)} placeholder="Ej. Pizza Margherita" />
        </div>
        <div className="row" style={{ gap: 14, alignItems: "flex-start" }}>
          <div className="set-field" style={{ flex: 1 }}>
            <label>Categoría del menú</label>
            <select value={f.categoria_id || ""} onChange={(e) => set("categoria_id", e.target.value)}>
              <option value="">Sin categoría</option>
              {categorias.map((c) => <option key={c.id} value={c.id}>{c.nombre}</option>)}
              <option value="__nueva__">+ Crear categoría nueva…</option>
            </select>
          </div>
          <div className="set-field" style={{ flex: 1 }}>
            <label>Precio (COP) *</label>
            <input value={f.precio} onChange={(e) => set("precio", e.target.value)} placeholder="32000" inputMode="numeric" />
          </div>
        </div>
        {f.categoria_id === "__nueva__" && (
          <div className="set-field">
            <label>Nombre de la categoría nueva</label>
            <input value={nuevaCat} onChange={(e) => setNuevaCat(e.target.value)} placeholder="Ej. Pizzas clásicas" />
          </div>
        )}
        <div className="set-field">
          <label>Descripción (opcional)</label>
          <textarea rows="3" value={f.descripcion || ""} onChange={(e) => set("descripcion", e.target.value)}
            placeholder="Ingredientes y detalles que verá el cliente" />
        </div>
        <div className="toggle">
          <div className="tl"><b>Disponible en el menú</b><p>Los productos pausados no se muestran en el marketplace.</p></div>
          <button type="button" className={"sw" + (f.disponible ? " on" : "")} onClick={() => set("disponible", !f.disponible)}></button>
        </div>
        <button className="btn btn-primary full" style={{ marginTop: 16 }} disabled={busy} onClick={guardar}>
          {busy ? "Guardando…" : producto ? "Guardar cambios" : "Agregar producto"}
        </button>
      </div>
    </div>
  );
}

/* vista previa: cómo se ve el producto en el marketplace */
function MkpPreviewProducto({ p, onClose }) {
  return (
    <div className="pd-pin-overlay" onClick={onClose}>
      <div className="pd-pin-modal" onClick={(e) => e.stopPropagation()} style={{ width: "min(420px,100%)" }}>
        <div className="between" style={{ marginBottom: 12 }}>
          <b>Así se ve en el marketplace</b>
          <button type="button" className="pd-pin-x" onClick={onClose} aria-label="Cerrar"><span aria-hidden>✕</span></button>
        </div>
        <div style={{ display: "flex", gap: 13, background: "var(--panel-2)", borderRadius: 14, padding: 12 }}>
          <div style={{ width: 96, height: 96, borderRadius: 12, overflow: "hidden", flex: "none" }}>
            {p.imagen_url ? <img src={p.imagen_url} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
              : <Avatar name={p.nombre} shape="tile" />}
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontWeight: 700, fontSize: 14.5 }}>{p.nombre}</div>
            {p.descripcion && <div className="muted" style={{ fontSize: 12.5, margin: "3px 0" }}>{p.descripcion}</div>}
            <div className="between" style={{ marginTop: 8 }}>
              <b style={{ fontFamily: "var(--font-display)" }}>{fmtCOP(p.precio)}</b>
              <span style={{ width: 32, height: 32, borderRadius: "50%", background: "var(--grad)", color: "#fff", display: "grid", placeItems: "center" }}>
                <Icon name="plus" style={{ width: 15, height: 15 }} />
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

function MkPanelProductos({ restId }) {
  const [productos, setProductos] = mkpS(null);
  const [categorias, setCategorias] = mkpS([]);
  const [modal, setModal] = mkpS(null);       /* null | "nuevo" | producto */
  const [preview, setPreview] = mkpS(null);
  const [nuevaCat, setNuevaCat] = mkpS("");
  const [err, setErr] = mkpS("");

  async function cargar() {
    const [pr, cr] = await Promise.all([
      window.treego_db.from("productos").select("*").eq("restaurante_id", restId).order("orden").order("id"),
      window.treego_db.from("categorias_menu").select("*").eq("restaurante_id", restId).order("orden").order("id"),
    ]);
    setProductos(pr.data || []);
    setCategorias(cr.data || []);
  }
  mkpE(() => { if (window.treego_db && restId) cargar(); }, [restId]);

  const nombreCat = (id) => {
    const c = categorias.find((x) => x.id === id);
    return c ? c.nombre : "Sin categoría";
  };

  async function toggleDisponible(p) {
    await window.treego_db.from("productos").update({ disponible: !p.disponible }).eq("id", p.id);
    cargar();
  }
  async function eliminar(p) {
    if (!window.confirm(`¿Eliminar "${p.nombre}" del menú? Esta acción no se puede deshacer.`)) return;
    const { error } = await window.treego_db.from("productos").delete().eq("id", p.id);
    if (error) setErr("No se pudo eliminar (puede tener pedidos asociados). Puedes pausarlo en su lugar.");
    cargar();
  }

  /* categorías: crear, reordenar (flechas) y activar/desactivar */
  async function crearCategoria() {
    const nombre = nuevaCat.trim();
    if (!nombre) return;
    await window.treego_db.from("categorias_menu")
      .insert({ restaurante_id: restId, nombre, orden: categorias.length });
    setNuevaCat("");
    cargar();
  }
  async function moverCategoria(idx, delta) {
    const j = idx + delta;
    if (j < 0 || j >= categorias.length) return;
    const a = categorias[idx], b = categorias[j];
    await Promise.all([
      window.treego_db.from("categorias_menu").update({ orden: j }).eq("id", a.id),
      window.treego_db.from("categorias_menu").update({ orden: idx }).eq("id", b.id),
    ]);
    cargar();
  }
  async function toggleCategoria(c) {
    await window.treego_db.from("categorias_menu").update({ activa: !c.activa }).eq("id", c.id);
    cargar();
  }

  if (productos === null) return <div className="muted" style={{ padding: 30 }}>Cargando menú…</div>;

  return (
    <div className="fade-in">
      <div className="between" style={{ marginBottom: 18, flexWrap: "wrap", gap: 12 }}>
        <p className="muted" style={{ fontSize: 13.5, margin: 0 }}>
          Agrega, edita o pausa los productos que ven tus clientes en el marketplace.
        </p>
        <button className="btn btn-primary" onClick={() => setModal("nuevo")}><Icon name="plus" />Nuevo producto</button>
      </div>
      {err && <div className="login-err" style={{ marginBottom: 14 }}><Icon name="flag" style={{ width: 15, height: 15 }} />{err}</div>}

      <div className="card card-pad" style={{ marginBottom: 22 }}>
        <div className="eyebrow-s" style={{ marginBottom: 14 }}>{productos.length} productos</div>
        {productos.length === 0 && (
          <p className="muted" style={{ fontSize: 14 }}>Aún no tienes productos. Crea el primero con "Nuevo producto".</p>
        )}
        <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(240px, 1fr))", gap: 16 }}>
          {productos.map((p) => (
            <div key={p.id} className="card" style={{ overflow: "hidden" }}>
              <div style={{ position: "relative", height: 120, background: "var(--panel-2)" }}>
                {p.imagen_url
                  ? <img loading="lazy" src={p.imagen_url} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                  : <Avatar name={p.nombre} shape="tile" />}
                <span className={"pill " + (p.disponible ? "pill-ok" : "pill-mut")}
                  style={{ position: "absolute", top: 8, left: 8 }}>
                  {p.disponible ? "Disponible" : "Pausado"}
                </span>
              </div>
              <div style={{ padding: "12px 14px 14px" }}>
                <div style={{ fontWeight: 700, fontSize: 14.5 }}>{p.nombre}</div>
                <div className="muted" style={{ fontSize: 12.5, margin: "1px 0 9px" }}>{nombreCat(p.categoria_id)}</div>
                <div className="between">
                  <b style={{ fontFamily: "var(--font-display)" }}>{fmtCOP(p.precio)}</b>
                  <div className="row" style={{ gap: 6 }}>
                    <button className="icon-btn" title="Ver cómo se ve" onClick={() => setPreview(p)}><Icon name="eye" style={{ width: 16, height: 16 }} /></button>
                    <button className="icon-btn" title="Editar" onClick={() => setModal(p)}><MkIcon name="edit" style={{ width: 16, height: 16 }} /></button>
                    <button className="icon-btn" title={p.disponible ? "Pausar" : "Activar"} onClick={() => toggleDisponible(p)}>
                      <Icon name={p.disponible ? "eyeoff" : "check"} style={{ width: 16, height: 16 }} />
                    </button>
                    <button className="icon-btn" title="Eliminar" onClick={() => eliminar(p)}><MkIcon name="trash" style={{ width: 16, height: 16 }} /></button>
                  </div>
                </div>
              </div>
            </div>
          ))}
        </div>
      </div>

      <div className="card card-pad">
        <div className="eyebrow-s" style={{ marginBottom: 6 }}>Categorías del menú</div>
        <p className="muted" style={{ fontSize: 13, marginBottom: 14 }}>
          Ordena las secciones como quieres que aparezcan en tu página del marketplace.
        </p>
        {categorias.map((c, i) => (
          <div key={c.id} className="between" style={{ padding: "10px 0", borderBottom: "1px solid var(--line)" }}>
            <div className="row" style={{ gap: 10 }}>
              <div className="row" style={{ gap: 2 }}>
                <button className="icon-btn" title="Subir" disabled={i === 0} style={{ opacity: i === 0 ? 0.3 : 1 }}
                  onClick={() => moverCategoria(i, -1)}><Icon name="arrow" style={{ width: 14, height: 14, transform: "rotate(-90deg)" }} /></button>
                <button className="icon-btn" title="Bajar" disabled={i === categorias.length - 1} style={{ opacity: i === categorias.length - 1 ? 0.3 : 1 }}
                  onClick={() => moverCategoria(i, 1)}><Icon name="arrow" style={{ width: 14, height: 14, transform: "rotate(90deg)" }} /></button>
              </div>
              <b style={{ fontSize: 14, opacity: c.activa ? 1 : 0.5 }}>{c.nombre}</b>
              {!c.activa && <span className="pill pill-mut">Desactivada</span>}
            </div>
            <button type="button" className={"sw" + (c.activa ? " on" : "")} onClick={() => toggleCategoria(c)}></button>
          </div>
        ))}
        <div className="row" style={{ gap: 10, marginTop: 14 }}>
          <input value={nuevaCat} onChange={(e) => setNuevaCat(e.target.value)}
            onKeyDown={(e) => { if (e.key === "Enter") crearCategoria(); }}
            placeholder="Nueva categoría (ej. Bebidas)"
            style={{ flex: 1, background: "var(--panel-2)", border: "1.5px solid var(--line-2)", borderRadius: 10, padding: "10px 13px", color: "var(--ink)", fontSize: 14, outline: "none" }} />
          <button className="btn btn-ghost" onClick={crearCategoria}><Icon name="plus" />Agregar</button>
        </div>
      </div>

      {modal && (
        <MkpModalProducto restId={restId} producto={modal === "nuevo" ? null : modal}
          categorias={categorias.filter((c) => c.activa)}
          onClose={() => setModal(null)}
          onSaved={() => { setModal(null); cargar(); }}
          onNuevaCategoria={() => {}} />
      )}
      {preview && <MkpPreviewProducto p={preview} onClose={() => setPreview(null)} />}
    </div>
  );
}

/* ═══ 3.2 FOTOS DEL NEGOCIO ══════════════════════════════════════════════ */

function MkPanelFotos({ restId }) {
  const [perfil, setPerfil] = mkpS(null);
  const [filePortada, setFilePortada] = mkpS(null);
  const [fileLogo, setFileLogo] = mkpS(null);
  const [busy, setBusy] = mkpS(false);
  const [err, setErr] = mkpS("");
  const [ok, setOk] = mkpS("");

  mkpE(() => {
    if (!window.treego_db || !restId) return;
    mkpAsegurarPerfil(restId).then(setPerfil);
  }, [restId]);

  async function guardar() {
    if (busy || !perfil) return;
    setBusy(true); setErr(""); setOk("");
    const cambios = {};
    if (filePortada) {
      const up = await mkpSubirFoto("portadas", restId, filePortada);
      if (up.error) { setErr(up.error); setBusy(false); return; }
      cambios.foto_portada_url = up.url;
    }
    if (fileLogo) {
      const up = await mkpSubirFoto("logos", restId, fileLogo);
      if (up.error) { setErr(up.error); setBusy(false); return; }
      cambios.logo_url = up.url;
    }
    if (Object.keys(cambios).length) {
      const { error } = await window.treego_db.from("perfil_restaurante_publico")
        .update(cambios).eq("id", perfil.id);
      if (error) { setErr("No se pudieron guardar las fotos."); setBusy(false); return; }
      setPerfil({ ...perfil, ...cambios });
      setFilePortada(null); setFileLogo(null);
      setOk("Fotos guardadas. Ya se ven en tu página del marketplace.");
    }
    setBusy(false);
  }

  if (!perfil) return <div className="muted" style={{ padding: 30 }}>Cargando…</div>;

  const nombre = (S.rest && S.rest.name) || "Tu restaurante";

  return (
    <div className="fade-in" style={{ display: "grid", gridTemplateColumns: "1.2fr .8fr", gap: 22, alignItems: "start" }}>
      <div className="card card-pad">
        <div className="eyebrow-s" style={{ marginBottom: 14 }}>Imágenes del marketplace</div>
        {err && <div className="login-err"><Icon name="flag" style={{ width: 15, height: 15 }} />{err}</div>}
        {ok && <div className="login-err" style={{ background: "var(--green-bg)", borderColor: "transparent", color: "var(--green)" }}><Icon name="check" style={{ width: 15, height: 15 }} />{ok}</div>}
        <MkpFotoInput label="Foto de portada (banner de tu página)" actual={perfil.foto_portada_url} alto={200} onFile={setFilePortada} />
        <MkpFotoInput label="Logo (cuadrado)" actual={perfil.logo_url} alto={150} onFile={setFileLogo} />
        <button className="btn btn-primary" disabled={busy || (!filePortada && !fileLogo)} onClick={guardar}>
          {busy ? "Subiendo…" : "Guardar fotos"}
        </button>
      </div>

      <div className="card card-pad">
        <div className="eyebrow-s" style={{ marginBottom: 14 }}>Vista previa en el marketplace</div>
        <div style={{ border: "1px solid var(--line-2)", borderRadius: 16, overflow: "hidden", maxWidth: 300 }}>
          <div style={{ height: 140, background: "var(--panel-2)", position: "relative" }}>
            {(filePortada || perfil.foto_portada_url)
              ? <img src={filePortada ? URL.createObjectURL(filePortada) : perfil.foto_portada_url} alt=""
                  style={{ width: "100%", height: "100%", objectFit: "cover" }} />
              : <Avatar name={nombre} shape="tile" watermark />}
            <span style={{ position: "absolute", bottom: -18, left: 12, width: 44, height: 44, borderRadius: 12, overflow: "hidden", border: "3px solid var(--panel)" }}>
              {(fileLogo || perfil.logo_url)
                ? <img src={fileLogo ? URL.createObjectURL(fileLogo) : perfil.logo_url} alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
                : <Avatar name={nombre} shape="tile" />}
            </span>
          </div>
          <div style={{ padding: "24px 14px 14px" }}>
            <b style={{ fontFamily: "var(--font-display)", fontSize: 15.5 }}>{nombre}</b>
            <div className="muted" style={{ fontSize: 12.5 }}>
              {(perfil.categorias_cocina || []).join(" · ") || "Categoría de cocina"}
            </div>
          </div>
        </div>
        <p className="muted" style={{ fontSize: 12.5, marginTop: 14 }}>
          Así se verá tu card en el home del marketplace. La portada también encabeza tu página.
        </p>
      </div>
    </div>
  );
}

/* ═══ 3.3 PERFIL PÚBLICO ═════════════════════════════════════════════════ */

const MKP_COCINAS = ["Hamburguesas", "Pizza", "Saludable", "Arepas", "Asiática", "Postres",
  "Café y jugos", "Mexicana", "Panadería", "Italiana", "Colombiana", "Mariscos", "Pollo", "Parrilla"];

function MkPanelPerfil({ restId }) {
  const [perfil, setPerfil] = mkpS(null);
  const [horarios, setHorarios] = mkpS(null); /* [{dia_semana, hora_apertura, hora_cierre, activo}] x7 */
  const [busy, setBusy] = mkpS(false);
  const [err, setErr] = mkpS("");
  const [ok, setOk] = mkpS("");
  const [otraCocina, setOtraCocina] = mkpS("");

  mkpE(() => {
    if (!window.treego_db || !restId) return;
    (async () => {
      const p = await mkpAsegurarPerfil(restId);
      setPerfil(p);
      const { data: hs } = await window.treego_db.from("horarios_marketplace")
        .select("*").eq("restaurante_id", restId).order("dia_semana");
      /* semana completa lunes→domingo (visual), BD usa 0=domingo */
      const porDia = {};
      (hs || []).forEach((h) => { porDia[h.dia_semana] = h; });
      setHorarios([1, 2, 3, 4, 5, 6, 0].map((d) => porDia[d] ||
        ({ dia_semana: d, hora_apertura: "11:00", hora_cierre: "21:00", activo: false })));
    })();
  }, [restId]);

  const set = (k, v) => setPerfil((p) => ({ ...p, [k]: v }));
  const setH = (i, k, v) => setHorarios((hs) => hs.map((h, j) => j === i ? { ...h, [k]: v } : h));

  const toggleCocina = (c) => {
    const cur = perfil.categorias_cocina || [];
    set("categorias_cocina", cur.includes(c) ? cur.filter((x) => x !== c) : [...cur, c].slice(0, 4));
  };

  async function guardar() {
    if (busy || !perfil) return;
    setBusy(true); setErr(""); setOk("");
    const { error } = await window.treego_db.from("perfil_restaurante_publico").update({
      descripcion_publica: perfil.descripcion_publica || null,
      categorias_cocina: perfil.categorias_cocina || [],
      tiempo_entrega_estimado: Number(perfil.tiempo_entrega_estimado) || null,
      pedido_minimo: Number(String(perfil.pedido_minimo || 0).replace(/[^\d]/g, "")) || 0,
    }).eq("id", perfil.id);
    if (error) { setErr("No se pudo guardar el perfil."); setBusy(false); return; }

    /* horarios: se reescriben completos (7 filas máximo) */
    await window.treego_db.from("horarios_marketplace").delete().eq("restaurante_id", restId);
    const filas = horarios.filter((h) => h.activo).map((h) => ({
      restaurante_id: restId, dia_semana: h.dia_semana,
      hora_apertura: h.hora_apertura, hora_cierre: h.hora_cierre, activo: true,
    }));
    if (filas.length) {
      const { error: hErr } = await window.treego_db.from("horarios_marketplace").insert(filas);
      if (hErr) { setErr("Perfil guardado, pero los horarios fallaron. Intenta de nuevo."); setBusy(false); return; }
    }
    setBusy(false);
    setOk("Perfil guardado.");
  }

  async function toggleMarketplace() {
    const nuevo = !perfil.activo_marketplace;
    const { error } = await window.treego_db.from("perfil_restaurante_publico")
      .update({ activo_marketplace: nuevo }).eq("id", perfil.id);
    if (!error) set("activo_marketplace", nuevo);
  }

  if (!perfil || !horarios) return <div className="muted" style={{ padding: 30 }}>Cargando…</div>;

  const urlPublica = "https://treego.com.co/r/" + perfil.slug;
  const DIA_LBL = { 1: "Lunes", 2: "Martes", 3: "Miércoles", 4: "Jueves", 5: "Viernes", 6: "Sábado", 0: "Domingo" };

  return (
    <div className="fade-in" style={{ display: "grid", gridTemplateColumns: "1.2fr .8fr", gap: 22, alignItems: "start" }}>
      <div>
        <div className="card card-pad" style={{ marginBottom: 22 }}>
          <div className="eyebrow-s" style={{ marginBottom: 14 }}>Información pública</div>
          {err && <div className="login-err"><Icon name="flag" style={{ width: 15, height: 15 }} />{err}</div>}
          {ok && <div className="login-err" style={{ background: "var(--green-bg)", borderColor: "transparent", color: "var(--green)" }}><Icon name="check" style={{ width: 15, height: 15 }} />{ok}</div>}

          <div className="set-field">
            <label>Descripción para clientes</label>
            <textarea rows="3" value={perfil.descripcion_publica || ""}
              onChange={(e) => set("descripcion_publica", e.target.value)}
              placeholder="Ej. Cocina italiana de autor, pizzas al horno de piedra y pastas frescas." />
          </div>

          <div className="set-field">
            <label>Categorías de cocina (máx. 4)</label>
            <div className="pd-chips" style={{ flexWrap: "wrap" }}>
              {MKP_COCINAS.map((c) => (
                <button key={c} type="button" className={"pd-chip" + ((perfil.categorias_cocina || []).includes(c) ? " on" : "")}
                  onClick={() => toggleCocina(c)}>{c}</button>
              ))}
            </div>
            <div className="row" style={{ gap: 8, marginTop: 10 }}>
              <input value={otraCocina} onChange={(e) => setOtraCocina(e.target.value)} placeholder="Otra categoría…"
                style={{ flex: 1, background: "var(--panel-2)", border: "1.5px solid var(--line-2)", borderRadius: 10, padding: "9px 12px", color: "var(--ink)", fontSize: 13.5, outline: "none" }} />
              <button className="btn btn-ghost" style={{ padding: "10px 16px" }} type="button"
                onClick={() => { if (otraCocina.trim()) { toggleCocina(otraCocina.trim()); setOtraCocina(""); } }}>
                <Icon name="plus" />
              </button>
            </div>
          </div>

          <div className="row" style={{ gap: 14, alignItems: "flex-start" }}>
            <div className="set-field" style={{ flex: 1 }}>
              <label>Tiempo de entrega estimado (min)</label>
              <input value={perfil.tiempo_entrega_estimado || ""} onChange={(e) => set("tiempo_entrega_estimado", e.target.value)}
                placeholder="35" inputMode="numeric" />
            </div>
            <div className="set-field" style={{ flex: 1 }}>
              <label>Pedido mínimo (COP)</label>
              <input value={perfil.pedido_minimo || ""} onChange={(e) => set("pedido_minimo", e.target.value)}
                placeholder="0 = sin mínimo" inputMode="numeric" />
            </div>
          </div>

          <div className="eyebrow-s" style={{ margin: "10px 0 12px" }}>Horarios de atención</div>
          {horarios.map((h, i) => (
            <div key={h.dia_semana} className="between" style={{ padding: "8px 0", borderBottom: "1px solid var(--line)", gap: 12 }}>
              <b style={{ fontSize: 13.5, width: 84, opacity: h.activo ? 1 : 0.45 }}>{DIA_LBL[h.dia_semana]}</b>
              <div className="row" style={{ gap: 8, opacity: h.activo ? 1 : 0.35 }}>
                <input type="time" value={h.hora_apertura} disabled={!h.activo}
                  onChange={(e) => setH(i, "hora_apertura", e.target.value)}
                  style={{ background: "var(--panel-2)", border: "1.5px solid var(--line-2)", borderRadius: 8, padding: "6px 8px", color: "var(--ink)", fontSize: 13 }} />
                <span className="muted">a</span>
                <input type="time" value={h.hora_cierre} disabled={!h.activo}
                  onChange={(e) => setH(i, "hora_cierre", e.target.value)}
                  style={{ background: "var(--panel-2)", border: "1.5px solid var(--line-2)", borderRadius: 8, padding: "6px 8px", color: "var(--ink)", fontSize: 13 }} />
              </div>
              <button type="button" className={"sw" + (h.activo ? " on" : "")} onClick={() => setH(i, "activo", !h.activo)}></button>
            </div>
          ))}

          <button className="btn btn-primary" style={{ marginTop: 18 }} disabled={busy} onClick={guardar}>
            {busy ? "Guardando…" : "Guardar perfil"}
          </button>
        </div>
      </div>

      <div>
        <div className="card card-pad" style={{ marginBottom: 22, border: perfil.activo_marketplace ? "1.5px solid var(--g2)" : undefined }}>
          <div className="between">
            <div>
              <b style={{ fontSize: 15.5 }}>Aparecer en Treego Marketplace</b>
              <p className="muted" style={{ fontSize: 12.5, marginTop: 4 }}>
                {perfil.activo_marketplace
                  ? "Tu restaurante está visible y recibe pedidos en línea."
                  : "Actívalo cuando tu menú, fotos y métodos de pago estén listos."}
              </p>
            </div>
            <button type="button" className={"sw" + (perfil.activo_marketplace ? " on" : "")}
              onClick={toggleMarketplace} style={{ transform: "scale(1.25)", transformOrigin: "right center" }}></button>
          </div>
        </div>

        <div className="card card-pad">
          <div className="eyebrow-s" style={{ marginBottom: 10 }}>Tu página pública</div>
          <div className="row" style={{ gap: 8, flexWrap: "wrap" }}>
            <code style={{ fontFamily: "var(--font-mono)", fontSize: 12.5, background: "var(--panel-2)", borderRadius: 8, padding: "8px 10px", wordBreak: "break-all" }}>{urlPublica}</code>
            <button className="btn btn-ghost" style={{ padding: "9px 14px" }}
              onClick={() => { navigator.clipboard && navigator.clipboard.writeText(urlPublica); }}>
              <MkIcon name="copy" style={{ width: 14, height: 14 }} />Copiar
            </button>
          </div>
          <p className="muted" style={{ fontSize: 12.5, marginTop: 12 }}>
            El enlace se genera automáticamente a partir del nombre de tu restaurante.
            Compártelo en tus redes: tus clientes piden ahí directamente.
          </p>
          <a className="btn btn-ghost" style={{ marginTop: 8, textDecoration: "none" }} href={"/r/" + perfil.slug} target="_blank" rel="noopener">
            <Icon name="eye" />Ver mi página
          </a>
        </div>
      </div>
    </div>
  );
}

/* ═══ 3.4 MÉTODOS DE PAGO ════════════════════════════════════════════════ */

const MKP_TIPOS_PAGO = [
  ["efectivo", "Efectivo", "El repartidor cobra al entregar"],
  ["transferencia", "Transferencia bancaria", "El cliente ve tu cuenta y transfiere"],
  ["nequi", "Nequi", "El cliente ve tu número Nequi"],
  ["daviplata", "Daviplata", "El cliente ve tu número Daviplata"],
];

function MkPanelPagos({ restId }) {
  const [metodos, setMetodos] = mkpS(null);
  const [modal, setModal] = mkpS(false);
  const [f, setF] = mkpS({ tipo: "efectivo", nombre_titular: "", numero_cuenta: "", banco: "" });
  const [busy, setBusy] = mkpS(false);
  const [err, setErr] = mkpS("");

  async function cargar() {
    const { data } = await window.treego_db.from("metodos_pago_restaurante")
      .select("*").eq("restaurante_id", restId).order("id");
    setMetodos(data || []);
  }
  mkpE(() => { if (window.treego_db && restId) cargar(); }, [restId]);

  async function agregar() {
    if (busy) return;
    const esEfectivo = f.tipo === "efectivo";
    if (!esEfectivo && (!f.nombre_titular.trim() || !f.numero_cuenta.trim())) {
      setErr("Titular y número de cuenta/teléfono son obligatorios para este método.");
      return;
    }
    setBusy(true); setErr("");
    const { error } = await window.treego_db.from("metodos_pago_restaurante").insert({
      restaurante_id: restId, tipo: f.tipo,
      nombre_titular: esEfectivo ? null : f.nombre_titular.trim(),
      numero_cuenta: esEfectivo ? null : f.numero_cuenta.trim(),
      banco: f.tipo === "transferencia" ? (f.banco.trim() || null) : null,
      activo: true,
    });
    setBusy(false);
    if (error) { setErr("No se pudo guardar el método de pago."); return; }
    setModal(false);
    setF({ tipo: "efectivo", nombre_titular: "", numero_cuenta: "", banco: "" });
    cargar();
  }

  async function toggle(m) {
    await window.treego_db.from("metodos_pago_restaurante").update({ activo: !m.activo }).eq("id", m.id);
    cargar();
  }
  async function eliminar(m) {
    if (!window.confirm("¿Eliminar este método de pago?")) return;
    await window.treego_db.from("metodos_pago_restaurante").delete().eq("id", m.id);
    cargar();
  }

  if (metodos === null) return <div className="muted" style={{ padding: 30 }}>Cargando…</div>;

  const lblTipo = (t) => (MKP_TIPOS_PAGO.find((x) => x[0] === t) || [t, t])[1];

  return (
    <div className="fade-in">
      <div className="between" style={{ marginBottom: 18, flexWrap: "wrap", gap: 12 }}>
        <p className="muted" style={{ fontSize: 13.5, margin: 0 }}>
          Estos métodos se mostrarán al cliente en el checkout. Para transferencias,
          el cliente verá los datos para hacer el pago.
        </p>
        <button className="btn btn-primary" onClick={() => setModal(true)}><Icon name="plus" />Agregar método</button>
      </div>

      <div className="card card-pad">
        {metodos.length === 0 && (
          <p className="muted" style={{ fontSize: 14 }}>
            Sin métodos de pago aún. Agrega al menos uno — sin métodos activos tus
            clientes no podrán completar el checkout.
          </p>
        )}
        {metodos.map((m) => (
          <div key={m.id} className="between" style={{ padding: "13px 0", borderBottom: "1px solid var(--line)", gap: 12 }}>
            <div>
              <div className="row" style={{ gap: 8 }}>
                <b style={{ fontSize: 14.5 }}>{lblTipo(m.tipo)}</b>
                <span className={"pill " + (m.activo ? "pill-ok" : "pill-mut")}>{m.activo ? "Activo" : "Inactivo"}</span>
              </div>
              {m.tipo !== "efectivo" && (
                <div className="muted" style={{ fontSize: 12.5, marginTop: 3 }}>
                  {m.nombre_titular} · {m.numero_cuenta}{m.banco ? " · " + m.banco : ""}
                </div>
              )}
            </div>
            <div className="row" style={{ gap: 8 }}>
              <button type="button" className={"sw" + (m.activo ? " on" : "")} onClick={() => toggle(m)}></button>
              <button className="icon-btn" title="Eliminar" onClick={() => eliminar(m)}><MkIcon name="trash" style={{ width: 16, height: 16 }} /></button>
            </div>
          </div>
        ))}
      </div>

      {modal && (
        <div className="pd-pin-overlay" onClick={() => setModal(false)}>
          <div className="pd-pin-modal" onClick={(e) => e.stopPropagation()}>
            <div className="between" style={{ marginBottom: 14 }}>
              <b style={{ fontSize: 17 }}>Agregar método de pago</b>
              <button type="button" className="pd-pin-x" onClick={() => setModal(false)} aria-label="Cerrar"><span aria-hidden>✕</span></button>
            </div>
            {err && <div className="login-err"><Icon name="flag" style={{ width: 15, height: 15 }} />{err}</div>}
            <div className="set-field">
              <label>Tipo</label>
              <select value={f.tipo} onChange={(e) => setF((s) => ({ ...s, tipo: e.target.value }))}>
                {MKP_TIPOS_PAGO.map(([v, l, d]) => <option key={v} value={v}>{l} — {d}</option>)}
              </select>
            </div>
            {f.tipo !== "efectivo" && (
              <React.Fragment>
                <div className="set-field">
                  <label>Nombre del titular *</label>
                  <input value={f.nombre_titular} onChange={(e) => setF((s) => ({ ...s, nombre_titular: e.target.value }))} placeholder="Como aparece en la cuenta" />
                </div>
                <div className="set-field">
                  <label>{f.tipo === "transferencia" ? "Número de cuenta *" : "Número de teléfono *"}</label>
                  <input value={f.numero_cuenta} onChange={(e) => setF((s) => ({ ...s, numero_cuenta: e.target.value }))}
                    placeholder={f.tipo === "transferencia" ? "000-000000-00" : "300 000 0000"} inputMode="numeric" />
                </div>
                {f.tipo === "transferencia" && (
                  <div className="set-field">
                    <label>Banco</label>
                    <input value={f.banco} onChange={(e) => setF((s) => ({ ...s, banco: e.target.value }))} placeholder="Ej. Bancolombia" />
                  </div>
                )}
              </React.Fragment>
            )}
            <button className="btn btn-primary full" disabled={busy} onClick={agregar}>
              {busy ? "Guardando…" : "Agregar método"}
            </button>
          </div>
        </div>
      )}
    </div>
  );
}

/* ═══ 3.5 PEDIDOS DEL MARKETPLACE ════════════════════════════════════════ */

/* modo:
   · undefined  → vista completa (cola + historial 48 h) — la usa el arnés de pruebas
   · "integrado" → SOLO la cola de cocina (pendiente/confirmado/preparando/listo),
     embebida arriba de la sección "Pedidos"; el seguimiento de los ya asignados
     vive en la lista unificada de pedidos (con su chip Marketplace). */
function MkPanelPedidosMk({ restId, usuario, modo }) {
  const [pedidos, setPedidos] = mkpS(null);
  const [items, setItems] = mkpS({});          /* pedidoId -> items[] */
  const [rechazo, setRechazo] = mkpS(null);    /* pedido en proceso de rechazo */
  const [motivo, setMotivo] = mkpS("");
  const [busyId, setBusyId] = mkpS(null);
  const [err, setErr] = mkpS("");
  const [flash, setFlash] = mkpS(null);        /* id del pedido recién llegado */

  async function cargar() {
    const desde = new Date(Date.now() - 48 * 3600e3).toISOString();
    const { data: peds } = await window.treego_db.from("pedidos_marketplace")
      .select("*").eq("restaurante_id", restId)
      .gte("created_at", desde)
      .order("created_at", { ascending: false });
    const lista = peds || [];
    setPedidos(lista);
    if (lista.length) {
      const { data: its } = await window.treego_db.from("items_pedido_marketplace")
        .select("*").in("pedido_marketplace_id", lista.map((p) => p.id));
      const porPedido = {};
      (its || []).forEach((it) => {
        (porPedido[it.pedido_marketplace_id] = porPedido[it.pedido_marketplace_id] || []).push(it);
      });
      setItems(porPedido);
    }
  }

  mkpE(() => {
    if (!window.treego_db || !restId) return;
    cargar();
    const onNuevo = (e) => { cargar(); if (e.detail) { setFlash(e.detail.id); setTimeout(() => setFlash(null), 6000); } };
    const onCambio = () => cargar();
    window.addEventListener("treego-mk-nuevo", onNuevo);
    window.addEventListener("treego-mk-cambio", onCambio);
    return () => {
      window.removeEventListener("treego-mk-nuevo", onNuevo);
      window.removeEventListener("treego-mk-cambio", onCambio);
    };
  }, [restId]);

  /* Confirmar: crea el pedido de domicilio REAL con la misma estructura que
     "Pedir domiciliario" (direcciones → pedidos → pedido_eventos) para que el
     algoritmo asigne repartidor; luego vincula pedido_domicilio_id (el trigger
     de la BD conecta el token de rastreo del cliente). */
  async function confirmar(p) {
    if (busyId) return;
    setBusyId(p.id); setErr("");
    try {
      const db = window.treego_db;

      /* 1. zona por coordenadas (tarifa especial/analítica) — tolera fallo */
      let zona = null;
      if (p.cliente_lat != null && p.cliente_lng != null) {
        try {
          const { data: zres } = await db.rpc("detectar_zona", { lat: Number(p.cliente_lat), lng: Number(p.cliente_lng) });
          if (zres && zres.length) zona = zres[0];
        } catch (e) { /* sin zona */ }
      }

      /* 2. dirección del cliente */
      const { data: dir, error: dirErr } = await db.from("direcciones").insert({
        direccion: p.cliente_direccion,
        municipio: p.cliente_municipio || "Cajicá",
        barrio: zona ? zona.barrio : null,
        tipo_inmueble: "casa",
        detalle: null,
        latitud: p.cliente_lat, longitud: p.cliente_lng,
      }).select("id").single();
      if (dirErr || !dir) throw new Error("dirección: " + (dirErr && dirErr.message));

      /* 3. distancia restaurante→cliente para la tarifa/tipo de zona */
      let distKm = null;
      if (S.rest && S.rest.lat != null && p.cliente_lat != null) {
        distKm = Math.round(TreegoTarifa.haversineKm(
          { lat: S.rest.lat, lng: S.rest.lng },
          { lat: Number(p.cliente_lat), lng: Number(p.cliente_lng) }) * 100) / 100;
      }

      const itemsTxt = (items[p.id] || []).map((it) => `${it.cantidad}x ${it.nombre_producto}`).join(", ");
      const cobro = p.metodo_pago === "efectivo"
        ? `COBRAR ${fmtCOP(p.total)} EN EFECTIVO al entregar.`
        : `Ya pagado por ${MKP_PAGOS[p.metodo_pago] || p.metodo_pago} (verificado por el restaurante).`;

      /* 4. pedido real (mismo shape que panel-pedir.jsx) */
      const { data: ped, error: pedErr } = await db.from("pedidos").insert({
        restaurante_id: restId,
        direccion_id: dir.id,
        zona_id: zona ? zona.zona_id : null,
        nombre_cliente: p.cliente_nombre,
        telefono_cliente: p.cliente_telefono,
        valor_pedido: p.subtotal,
        valor_envio: p.valor_domicilio,
        distancia_km: distKm,
        tipo_zona: distKm != null && distKm <= TreegoTarifa.BASE_KM ? "urbana" : "rural",
        metodo_pago: p.metodo_pago === "efectivo" ? "efectivo" : "pagado",
        notas: `Marketplace #${p.id} · ${itemsTxt}. ${cobro}${p.notas ? " Notas del cliente: " + p.notas : ""}`,
        estado_actual: "creado",   /* dispara trg_autoasignar_pedido (asignación automática) */
        origen: "marketplace",
        fecha_creacion: new Date().toISOString(),
      }).select("id").single();
      if (pedErr || !ped) throw new Error("pedido: " + (pedErr && pedErr.message));

      /* 5. evento de trazabilidad */
      await db.from("pedido_eventos").insert({
        pedido_id: ped.id,
        usuario_id: usuario ? usuario.id : null,
        tipo_evento: "pedido_creado",
        fecha_evento: new Date().toISOString(),
      });

      /* 6. vincular y confirmar (el trigger conecta el rastreo del cliente) */
      const { error: upErr } = await db.from("pedidos_marketplace")
        .update({ estado: "confirmado", pedido_domicilio_id: ped.id }).eq("id", p.id);
      if (upErr) throw new Error("vínculo: " + upErr.message);

      /* correo "pedido confirmado" + link de rastreo (y WhatsApp preparado) */
      mkpAvisarCliente(p.id, "confirmado");

      if (S.plan) S.plan.used += 1;
      cargar();
    } catch (e) {
      console.error("[Treego] Confirmar pedido marketplace falló:", e);
      setErr("No se pudo confirmar el pedido. Revisa e intenta de nuevo.");
    }
    setBusyId(null);
  }

  async function marcarListo(p) {
    if (busyId) return;
    setBusyId(p.id);
    await window.treego_db.from("pedidos_marketplace").update({ estado: "listo" }).eq("id", p.id);
    setBusyId(null);
    cargar();
  }

  /* Rechazar (pendiente) y Cancelar (ya confirmado): si existe pedido de
     domicilio real se cancela con la RPC cancelar_pedido — misma regla de
     etapa que ya existe (solo hasta que el repartidor esté en el restaurante). */
  async function rechazar() {
    if (!rechazo || busyId) return;
    const motivoTxt = motivo.trim() || "Cancelado por el restaurante";
    setBusyId(rechazo.id); setErr("");
    if (rechazo.pedido_domicilio_id) {
      const { data, error } = await window.treego_db
        .rpc("cancelar_pedido", { p_pedido_id: rechazo.pedido_domicilio_id, p_motivo: motivoTxt });
      const r = data && data.length ? data[0] : null;
      if (error || !r || !r.ok) {
        setErr((r && r.motivo) || "No se pudo cancelar el domicilio asociado.");
        setBusyId(null); setRechazo(null);
        cargar();
        return;
      }
    }
    await window.treego_db.from("pedidos_marketplace")
      .update({ estado: "cancelado", motivo_cancelacion: motivoTxt })
      .eq("id", rechazo.id);
    mkpAvisarCliente(rechazo.id, "cancelado");
    setBusyId(null); setRechazo(null); setMotivo("");
    cargar();
  }

  const integrado = modo === "integrado";
  if (pedidos === null) {
    return integrado ? null : <div className="muted" style={{ padding: 30 }}>Cargando pedidos…</div>;
  }

  const EN_COCINA = ["confirmado", "preparando", "listo"];
  const pendientes = pedidos.filter((p) => p.estado === "pendiente");
  const resto = integrado
    ? pedidos.filter((p) => EN_COCINA.includes(p.estado))
    : pedidos.filter((p) => p.estado !== "pendiente");

  /* integrado y sin nada accionable → no ocupar espacio en la vista Pedidos */
  if (integrado && pendientes.length === 0 && resto.length === 0 && !err) return null;

  const CardPedido = ({ p }) => {
    const [lbl, cls] = MKP_ESTADOS[p.estado] || [p.estado, "pill-mut"];
    const its = items[p.id] || [];
    const hora = new Date(p.created_at).toLocaleTimeString("es-CO", { hour: "numeric", minute: "2-digit" });
    return (
      <div className="card card-pad" style={{
        marginBottom: 14,
        border: p.estado === "pendiente" ? "1.5px solid var(--g2)" : undefined,
        boxShadow: flash === p.id ? "0 0 0 3px rgba(var(--color-primary-rgb),.35)" : undefined,
        transition: "box-shadow .4s",
      }}>
        <div className="between" style={{ flexWrap: "wrap", gap: 10 }}>
          <div className="row" style={{ gap: 10 }}>
            <b style={{ fontFamily: "var(--font-display)", fontSize: 16 }}>Pedido #{p.id}</b>
            <span className={"pill " + cls}>{lbl}</span>
            <span className="muted" style={{ fontSize: 12.5 }}>{hora}</span>
          </div>
          <b style={{ fontFamily: "var(--font-display)", fontSize: 16 }}>{fmtCOP(p.total)}</b>
        </div>

        <div style={{ display: "grid", gridTemplateColumns: "1.1fr .9fr", gap: 16, marginTop: 12 }}>
          <div>
            <div className="eyebrow-s" style={{ marginBottom: 6 }}>Productos</div>
            {its.map((it) => (
              <div key={it.id} className="between" style={{ fontSize: 13.5, padding: "3px 0" }}>
                <span><b>{it.cantidad}x</b> {it.nombre_producto}{it.notas_item ? <span className="muted"> · {it.notas_item}</span> : null}</span>
                <span className="muted">{fmtCOP(it.subtotal)}</span>
              </div>
            ))}
            <div className="between" style={{ fontSize: 13, marginTop: 6, paddingTop: 6, borderTop: "1px dashed var(--line)" }}>
              <span className="muted">Subtotal {fmtCOP(p.subtotal)} · Domicilio {fmtCOP(p.valor_domicilio)}</span>
            </div>
          </div>
          <div>
            <div className="eyebrow-s" style={{ marginBottom: 6 }}>Cliente y entrega</div>
            <div style={{ fontSize: 13.5 }}><b>{p.cliente_nombre}</b> · {p.cliente_telefono}</div>
            <div className="muted" style={{ fontSize: 13, marginTop: 2 }}>{p.cliente_direccion}</div>
            <div style={{ fontSize: 13, marginTop: 6 }}>
              Pago: <b>{MKP_PAGOS[p.metodo_pago] || p.metodo_pago}</b>
              {p.metodo_pago !== "efectivo" && p.comprobante_pago_url && (
                <React.Fragment> · <a href={p.comprobante_pago_url} target="_blank" rel="noopener" style={{ color: "var(--g1)" }}>Ver comprobante</a></React.Fragment>
              )}
              {p.metodo_pago !== "efectivo" && !p.comprobante_pago_url && (
                <span className="muted"> · sin comprobante adjunto</span>
              )}
            </div>
            {p.notas && <div className="muted" style={{ fontSize: 12.5, marginTop: 6 }}>Notas: {p.notas}</div>}
            {p.estado === "cancelado" && p.motivo_cancelacion && (
              <div className="muted" style={{ fontSize: 12.5, marginTop: 6 }}>Motivo: {p.motivo_cancelacion}</div>
            )}
          </div>
        </div>

        {["pendiente", "confirmado", "preparando", "listo", "asignado"].includes(p.estado) && (
          <div className="row" style={{ gap: 10, marginTop: 14, flexWrap: "wrap" }}>
            {p.estado === "pendiente" && (
              <React.Fragment>
                <button className="btn btn-primary" disabled={busyId === p.id} onClick={() => confirmar(p)}>
                  <Icon name="check" />{busyId === p.id ? "Confirmando…" : "Confirmar y preparar"}
                </button>
                <button className="btn btn-ghost" disabled={busyId === p.id} onClick={() => { setRechazo(p); setMotivo(""); }}>
                  Rechazar
                </button>
              </React.Fragment>
            )}
            {(p.estado === "confirmado" || p.estado === "preparando") && (
              <button className="btn btn-primary" disabled={busyId === p.id} onClick={() => marcarListo(p)}>
                <Icon name="pkg" />{busyId === p.id ? "Guardando…" : "Listo para recoger"}
              </button>
            )}
            {p.estado !== "pendiente" && (
              /* cancelable mientras el repartidor no haya recogido — la RPC
                 cancelar_pedido valida la etapa real con lock */
              <button className="btn btn-ghost" disabled={busyId === p.id} onClick={() => { setRechazo(p); setMotivo(""); }}>
                Cancelar pedido
              </button>
            )}
          </div>
        )}
      </div>
    );
  };

  return (
    <div className="fade-in">
      {err && <div className="login-err" style={{ marginBottom: 14 }}><Icon name="flag" style={{ width: 15, height: 15 }} />{err}</div>}

      {pendientes.length > 0 && (
        <React.Fragment>
          <div className="eyebrow-s" style={{ marginBottom: 12, color: "var(--g1)" }}>
            🔔 {pendientes.length} {pendientes.length === 1 ? "pedido nuevo esperando" : "pedidos nuevos esperando"} tu confirmación
          </div>
          {pendientes.map((p) => <CardPedido key={p.id} p={p} />)}
        </React.Fragment>
      )}

      {resto.length > 0 && (
        <div className="eyebrow-s" style={{ margin: "16px 0 12px" }}>
          {integrado ? "Marketplace · en cocina" : "Últimas 48 horas"}
        </div>
      )}
      {!integrado && resto.length === 0 && pendientes.length === 0 && (
        <div className="card card-pad">
          <p className="muted" style={{ fontSize: 14, margin: 0 }}>
            Sin pedidos del marketplace aún. Cuando un cliente pida desde tu página
            pública, aparecerá aquí al instante (con alerta sonora).
          </p>
        </div>
      )}
      {resto.map((p) => <CardPedido key={p.id} p={p} />)}
      {integrado && (pendientes.length > 0 || resto.length > 0) && (
        <div style={{ height: 10 }}></div>
      )}

      {rechazo && (
        <div className="pd-pin-overlay" onClick={() => setRechazo(null)}>
          <div className="pd-pin-modal" onClick={(e) => e.stopPropagation()} style={{ width: "min(440px,100%)" }}>
            <div className="between" style={{ marginBottom: 12 }}>
              <b style={{ fontSize: 16 }}>Rechazar pedido #{rechazo.id}</b>
              <button type="button" className="pd-pin-x" onClick={() => setRechazo(null)} aria-label="Cerrar"><span aria-hidden>✕</span></button>
            </div>
            <div className="set-field">
              <label>Motivo (lo verá el cliente)</label>
              <textarea rows="2" value={motivo} onChange={(e) => setMotivo(e.target.value)}
                placeholder="Ej. Sin ingredientes disponibles en este momento" />
            </div>
            <div className="row" style={{ gap: 10, justifyContent: "flex-end" }}>
              <button className="btn btn-ghost" onClick={() => setRechazo(null)}>Volver</button>
              <button className="btn btn-primary" disabled={busyId === rechazo.id} onClick={rechazar}>Rechazar pedido</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

Object.assign(window, {
  MkPanelProductos, MkPanelFotos, MkPanelPerfil, MkPanelPagos, MkPanelPedidosMk,
  treegoMkAlertaInit,
});
