const { useState, useEffect, useCallback, useMemo } = React;

// ============================================
// Vista de Configuración de Tienda
// Gerentes configuran áreas de impresión por CATEGORÍA
// ============================================

const StoreConfigView = ({ user, showToast }) => {
  const [tab, setTab] = useState("areas");
  const isAdmin = user.role === "admin";

  const [stores, setStores] = useState([]);
  const [selectedStore, setSelectedStore] = useState(user.storeId || null);

  useEffect(() => {
    if (!isAdmin) return;
    fetchWithAuth(`${API_BASE}/admin/stores`).then(async (res) => {
      if (res.ok) {
        const d = await res.json();
        setStores(d.stores || []);
        if (!selectedStore && d.stores.length > 0) setSelectedStore(d.stores[0].id);
      }
    }).catch(() => {});
  }, [isAdmin]);

  const storeName = useMemo(() => {
    if (!isAdmin) return user.displayName || "Mi Sucursal";
    const s = stores.find((st) => st.id === Number(selectedStore));
    return s ? s.name : "Sucursal";
  }, [selectedStore, stores, isAdmin, user]);

  const tabs = [
    { id: "status",  label: "Estado Tienda",      icon: "store" },
    { id: "hours",   label: "Horarios",           icon: "history" },
    { id: "areas",   label: "Areas de Impresion", icon: "layers" },
    { id: "print",   label: "Impresoras",         icon: "printer" },
    { id: "menusync", label: "Menú Plataformas",  icon: "menu" },
    { id: "cooks",   label: "Colaboradores KDS",  icon: "chef" },
    ...(isAdmin ? [{ id: "integration", label: "Integración Uber", icon: "link" }] : []),
  ];

  return (
    <div className="admin-wrap">
      <div className="admin-header">
        <div style={{ display: "flex", alignItems: "center", gap: 12, flex: 1 }}>
          <h1><Icon name="store" size={22} /> Configuracion de Tienda</h1>
          {isAdmin && stores.length > 0 && (
            <select className="reports-select" value={selectedStore || ""} onChange={(e) => setSelectedStore(Number(e.target.value))}>
              {stores.map((s) => <option key={s.id} value={s.id}>{s.name} ({s.code})</option>)}
            </select>
          )}
          {!isAdmin && <span className="muted" style={{ fontSize: 14 }}>{storeName}</span>}
        </div>
      </div>
      <div className="admin-tabs">
        {tabs.map((t) => (
          <button key={t.id} className={`admin-tab ${tab === t.id ? "is-active" : ""}`} onClick={() => setTab(t.id)}>
            <Icon name={t.icon} size={15} /> {t.label}
          </button>
        ))}
      </div>
      <div className="admin-content">
        {!selectedStore ? (
          <div className="empty"><div className="empty-text">Selecciona una sucursal para configurar</div></div>
        ) : (
          <>
            {tab === "status" && <StoreStatusControl storeId={selectedStore} storeName={storeName} showToast={showToast} />}
            {tab === "hours" && <StoreHoursConfig storeId={selectedStore} showToast={showToast} />}
            {tab === "areas" && <StoreCategoryAreasConfig storeId={selectedStore} showToast={showToast} />}
            {tab === "print" && <StorePrintConfig storeId={selectedStore} showToast={showToast} />}
            {tab === "menusync" && <StoreMenuSync storeId={selectedStore} storeName={storeName} showToast={showToast} />}
            {tab === "cooks" && <KdsCooksConfig storeId={selectedStore} showToast={showToast} />}
            {tab === "integration" && isAdmin && <UberIntegrationConfig storeId={selectedStore} storeName={storeName} showToast={showToast} />}
          </>
        )}
      </div>
    </div>
  );
};

// ============================================
// Config: Áreas de impresión POR CATEGORÍA
// ============================================
const AREA_OPTS = [
  { key: "cocina", label: "Cocina", icon: "chef", color: "#E67E22" },
  { key: "bebidas", label: "Bebidas", icon: "coffee", color: "#3498DB" },
];

const AreaChip = ({ active, color, icon, label, onClick }) => (
  <button onClick={onClick} type="button" style={{
    display: "inline-flex", alignItems: "center", gap: 5, padding: "4px 11px", borderRadius: 20,
    fontSize: 12, fontWeight: 600, cursor: "pointer", transition: "all 120ms",
    border: `1px solid ${active ? color : "var(--border)"}`,
    background: active ? color : "transparent", color: active ? "#fff" : "var(--text-3)",
  }}>
    <Icon name={icon} size={12} /> {label}
  </button>
);

const StoreCategoryAreasConfig = ({ storeId, showToast }) => {
  const [categories, setCategories] = useState([]);
  const [loading, setLoading] = useState(true);
  const [expanded, setExpanded] = useState(null);
  const [products, setProducts] = useState([]);
  const [loadingProducts, setLoadingProducts] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    const res = await fetchWithAuth(`${API_BASE}/catalog/store-category-areas/${storeId}`);
    if (res.ok) { const d = await res.json(); setCategories(d.categories || []); }
    setLoading(false);
  }, [storeId]);
  useEffect(() => { load(); }, [load]);

  const loadProducts = async (categoryId) => {
    setLoadingProducts(true); setProducts([]);
    const res = await fetchWithAuth(`${API_BASE}/catalog/store-product-areas/${storeId}?category_id=${categoryId}`);
    if (res.ok) { const d = await res.json(); setProducts(d.products || []); }
    setLoadingProducts(false);
  };

  const toggleExpand = (categoryId) => {
    if (expanded === categoryId) { setExpanded(null); return; }
    setExpanded(categoryId); loadProducts(categoryId);
  };

  const toggleCatArea = async (cat, area) => {
    const next = cat.areas.includes(area) ? cat.areas.filter((a) => a !== area) : [...cat.areas, area];
    const res = await fetchWithAuth(`${API_BASE}/catalog/store-category-areas/${storeId}`, {
      method: "POST", body: JSON.stringify({ category_id: cat.category_id, areas: next }),
    });
    if (res.ok) {
      setCategories((prev) => prev.map((c) => c.category_id === cat.category_id ? { ...c, areas: next } : c));
      if (expanded === cat.category_id) loadProducts(cat.category_id);
    } else showToast("Error al actualizar");
  };

  const toggleProdArea = async (prod, area) => {
    const base = prod.effective_areas || [];
    const next = base.includes(area) ? base.filter((a) => a !== area) : [...base, area];
    const res = await fetchWithAuth(`${API_BASE}/catalog/store-product-areas/${storeId}`, {
      method: "POST", body: JSON.stringify({ product_id: prod.product_id, areas: next }),
    });
    if (res.ok) { loadProducts(expanded); load(); } else showToast("Error");
  };

  const resetProd = async (prod) => {
    const res = await fetchWithAuth(`${API_BASE}/catalog/store-product-areas/${storeId}`, {
      method: "POST", body: JSON.stringify({ product_id: prod.product_id, areas: [] }),
    });
    if (res.ok) { showToast("Producto vuelve a heredar"); loadProducts(expanded); load(); }
  };

  if (loading) {
    return <div className="empty"><div className="empty-icon"><Icon name="refresh" size={26} /></div><div className="empty-text">Cargando...</div></div>;
  }

  return (
    <div>
      <div className="admin-toolbar">
        <h2>Áreas de Impresión</h2>
        <span className="muted" style={{ fontSize: 13 }}>Asigna cada categoría (y producto) a Cocina y/o Bebidas.</span>
      </div>

      <div className="menusync-info" style={{ marginBottom: 14 }}>
        <Icon name="alert" size={14} />
        <div>
          Una categoría o producto puede ir a <strong>ambas áreas</strong> (se imprime en las dos).
          Los productos <strong>heredan</strong> su categoría salvo que los personalices.
          En <strong>paquetes</strong>, cada área imprime solo sus componentes, pero ambos tickets llevan el nombre del paquete.
        </div>
      </div>

      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {categories.map((cat) => {
          const isOpen = expanded === cat.category_id;
          return (
          <div key={cat.category_id} style={{ border: "1px solid var(--border)", borderRadius: 10, overflow: "hidden", background: "var(--surface)" }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "10px 14px", flexWrap: "wrap" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 10, minWidth: 200 }}>
                <button className="icon-btn-sm" onClick={() => toggleExpand(cat.category_id)} title="Ver/personalizar productos">
                  <Icon name="chevronRight" size={15} style={{ transform: isOpen ? "rotate(90deg)" : "none", transition: "transform 150ms" }} />
                </button>
                <div>
                  <strong>{cat.category_name}</strong>
                  <div className="muted" style={{ fontSize: 12 }}>
                    {cat.product_count} productos
                    {cat.overrides > 0 ? ` · ${cat.overrides} personalizados` : ""}
                    {cat.areas.length === 0 ? " · sin asignar" : ""}
                  </div>
                </div>
              </div>
              <div style={{ display: "flex", gap: 6 }}>
                {AREA_OPTS.map((a) => (
                  <AreaChip key={a.key} active={cat.areas.includes(a.key)} color={a.color} icon={a.icon} label={a.label} onClick={() => toggleCatArea(cat, a.key)} />
                ))}
              </div>
            </div>

            {isOpen && (
              <div style={{ borderTop: "1px solid var(--border)", background: "var(--surface-2)", padding: "10px 14px" }}>
                {loadingProducts ? (
                  <div className="muted" style={{ fontSize: 13, padding: 6 }}>Cargando productos…</div>
                ) : products.length === 0 ? (
                  <div className="muted" style={{ fontSize: 13, padding: 6 }}>Sin productos en la categoría</div>
                ) : (
                  <div style={{ display: "flex", flexDirection: "column", gap: 6, maxHeight: 340, overflowY: "auto" }}>
                    {products.map((p) => (
                      <div key={p.product_id} style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 10, padding: "7px 11px", background: "var(--surface)", border: "1px solid var(--border)", borderRadius: 8, flexWrap: "wrap" }}>
                        <div style={{ minWidth: 160 }}>
                          <span style={{ fontWeight: 500, fontSize: 13 }}>{p.name}</span>
                          {p.pos_code && <span className="mono muted" style={{ fontSize: 11, marginLeft: 6 }}>{p.pos_code}</span>}
                          <span className="muted" style={{ fontSize: 11, marginLeft: 6 }}>{p.is_overridden ? "· personalizado" : "· hereda categoría"}</span>
                        </div>
                        <div style={{ display: "flex", gap: 6, alignItems: "center" }}>
                          {AREA_OPTS.map((a) => (
                            <AreaChip key={a.key} active={(p.effective_areas || []).includes(a.key)} color={a.color} icon={a.icon} label={a.label} onClick={() => toggleProdArea(p, a.key)} />
                          ))}
                          {p.is_overridden && (
                            <button className="icon-btn-sm" title="Volver a heredar de la categoría" onClick={() => resetProd(p)}><Icon name="refresh" size={13} /></button>
                          )}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>
            )}
          </div>
          );
        })}
      </div>
    </div>
  );
};

// ============================================
// Config: Impresoras por área
// ============================================
const StorePrintConfig = ({ storeId, showToast }) => {
  const [configs, setConfigs] = useState([]);
  const [editing, setEditing] = useState(null);
  const [form, setForm] = useState({});

  const load = useCallback(async () => {
    const res = await fetchWithAuth(`${API_BASE}/admin/stores/${storeId}/print-config`);
    if (res.ok) { const d = await res.json(); setConfigs(d.configs || []); }
  }, [storeId]);

  useEffect(() => { load(); }, [load]);

  const save = async () => {
    const res = await fetchWithAuth(`${API_BASE}/admin/stores/${storeId}/print-config`, {
      method: "POST",
      body: JSON.stringify(form),
    });
    if (res.ok) { showToast("Impresora configurada"); setEditing(null); load(); }
  };

  const startEdit = (area) => {
    const existing = configs.find((c) => c.area === area);
    setForm(existing || { area, printer_name: "", output_dir: "", is_enabled: 1 });
    setEditing(area);
  };

  return (
    <div>
      <div className="admin-toolbar">
        <h2>Impresoras</h2>
        <span className="muted" style={{ fontSize: 13 }}>Configura la impresora de cada area para esta sucursal</span>
      </div>

      <AdminModal
        open={!!editing}
        title={`Configurar impresora: ${editing ? editing.toUpperCase() : ""}`}
        onClose={() => setEditing(null)}
        onSave={save}
      >
        <div className="admin-form-grid">
          <FormField label="Nombre de impresora" value={form.printer_name || ""} onChange={(v) => setForm({ ...form, printer_name: v })} placeholder="Ej: EPSON-TM20" />
          <FormField label="Directorio de salida" value={form.output_dir || ""} onChange={(v) => setForm({ ...form, output_dir: v })} placeholder="/ruta/tickets" />
          <div className="form-field">
            <label>Habilitada</label>
            <select value={form.is_enabled} onChange={(e) => setForm({ ...form, is_enabled: Number(e.target.value) })}>
              <option value={1}>Si</option>
              <option value={0}>No</option>
            </select>
          </div>
        </div>
      </AdminModal>

      <div className="print-areas">
        {["cocina", "bebidas"].map((area) => {
          const cfg = configs.find((c) => c.area === area);
          return (
            <div key={area} className="print-area-card" onClick={() => startEdit(area)}>
              <div className="print-area-icon">
                <Icon name={area === "bebidas" ? "coffee" : "chef"} size={28} />
              </div>
              <div className="print-area-info">
                <h3>{area.toUpperCase()}</h3>
                {cfg ? (
                  <>
                    <div className="print-detail"><Icon name="printer" size={12} /> {cfg.printer_name || "Sin nombre"}</div>
                    <div className="print-detail"><Icon name="note" size={12} /> {cfg.output_dir || "Default"}</div>
                    <span className={`status-dot ${cfg.is_enabled ? "active" : "inactive"}`} />
                    {cfg.is_enabled ? "Activa" : "Inactiva"}
                  </>
                ) : (
                  <div className="print-detail muted">Sin configurar — haz clic para configurar</div>
                )}
              </div>
              <Icon name="edit" size={16} />
            </div>
          );
        })}
      </div>
    </div>
  );
};

// ============================================
// Horario de atención (editor por día)
// ============================================
const DAYS_ES = [
  { key: "sunday", label: "Domingo" },
  { key: "monday", label: "Lunes" },
  { key: "tuesday", label: "Martes" },
  { key: "wednesday", label: "Miércoles" },
  { key: "thursday", label: "Jueves" },
  { key: "friday", label: "Viernes" },
  { key: "saturday", label: "Sábado" },
];

const StoreHoursConfig = ({ storeId, showToast }) => {
  const [hours, setHours] = useState({}); // { day: {is_open, open_time, close_time} }
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [sameAll, setSameAll] = useState(false);
  const [logSignal, setLogSignal] = useState(0);

  const load = useCallback(async () => {
    setLoading(true);
    const res = await fetchWithAuth(`${API_BASE}/catalog/store-hours/${storeId}`);
    const def = {};
    DAYS_ES.forEach((d) => { def[d.key] = { is_open: true, open_time: "12:00", close_time: "21:00" }; });
    if (res.ok) {
      const d = await res.json();
      (d.hours || []).forEach((h) => {
        def[h.day_of_week] = { is_open: !!h.is_open, open_time: h.open_time, close_time: h.close_time };
      });
    }
    setHours(def);
    setLoading(false);
  }, [storeId]);

  useEffect(() => { load(); }, [load]);

  const update = (day, field, value) => {
    setHours((prev) => {
      const next = { ...prev, [day]: { ...prev[day], [field]: value } };
      // Si "igual para todos", replicar el cambio de horas/estado a todos los días
      if (sameAll && field !== "_") {
        DAYS_ES.forEach((d) => { next[d.key] = { ...next[day] }; });
      }
      return next;
    });
  };

  const toggleSameAll = (checked) => {
    setSameAll(checked);
    if (checked) {
      // Tomar el primer día como referencia y aplicar a todos
      const ref = hours[DAYS_ES[0].key];
      const next = {};
      DAYS_ES.forEach((d) => { next[d.key] = { ...ref }; });
      setHours(next);
    }
  };

  const save = async () => {
    setSaving(true);
    const payload = DAYS_ES.map((d) => ({
      day_of_week: d.key,
      is_open: hours[d.key].is_open,
      open_time: hours[d.key].open_time,
      close_time: hours[d.key].close_time,
    }));
    const res = await fetchWithAuth(`${API_BASE}/catalog/store-hours/${storeId}`, {
      method: "POST", body: JSON.stringify({ hours: payload }),
    });
    const d = await res.json().catch(() => ({}));
    if (res.ok) {
      // El backend reenvía el horario a Uber (re-sube el menú). Avisar el resultado.
      if (d.uber_sync && d.uber_sync.ok) showToast("Horario guardado y sincronizado con Uber");
      else if (d.uber_sync) showToast(d.uber_sync.message || "Horario guardado (sin sincronizar con Uber)");
      else showToast("Horario guardado");
      setLogSignal((s) => s + 1);
    } else {
      showToast(d.message || "Error al guardar");
    }
    setSaving(false);
  };

  if (loading) {
    return <div className="empty"><div className="empty-icon"><Icon name="refresh" size={26} /></div><div className="empty-text">Cargando...</div></div>;
  }

  return (
    <div>
      <div className="admin-toolbar">
        <h2>Horario de Atención</h2>
        <label className="toggle-label">
          <input type="checkbox" checked={sameAll} onChange={(e) => toggleSameAll(e.target.checked)} />
          <span>Igual para todos los días</span>
        </label>
      </div>

      <div className="hours-editor">
        {DAYS_ES.map((d) => {
          const h = hours[d.key] || {};
          return (
            <div key={d.key} className={`hours-row ${h.is_open ? "" : "closed"}`}>
              <label className="hours-day">
                <input type="checkbox" checked={h.is_open} onChange={(e) => update(d.key, "is_open", e.target.checked)} />
                <span>{d.label}</span>
              </label>
              <div className="hours-times">
                <input type="time" value={h.open_time} disabled={!h.is_open}
                  onChange={(e) => update(d.key, "open_time", e.target.value)} />
                <span className="hours-sep">a</span>
                <input type="time" value={h.close_time} disabled={!h.is_open}
                  onChange={(e) => update(d.key, "close_time", e.target.value)} />
              </div>
            </div>
          );
        })}
      </div>

      <div className="menusync-info" style={{ marginTop: 16 }}>
        <Icon name="alert" size={14} />
        <div>
          Al guardar, el horario se <strong>envía automáticamente a Uber</strong> (se re-sube el menú,
          que es donde Uber guarda el horario de apertura). Los días desmarcados se consideran cerrados.
          <br />
          <strong>Nota:</strong> Uber puede tardar unos minutos en aplicar el nuevo horario. La tienda
          abre/cierra según este horario; el botón "Abrir tienda" solo quita una pausa temporal, no
          adelanta la hora de apertura.
        </div>
      </div>

      <div style={{ marginTop: 16 }}>
        <button className="btn btn-action" onClick={save} disabled={saving}>
          <Icon name="save" size={14} /> {saving ? "Guardando..." : "Guardar horario"}
        </button>
      </div>

      <ActivityHistory storeId={storeId} category="hours" refreshSignal={logSignal} />
    </div>
  );
};

// ============================================
// Estado de tienda (abrir / pausar / cerrar)
// ============================================
const StoreStatusControl = ({ storeId, storeName, showToast }) => {
  const [status, setStatus] = useState(null);
  const [loading, setLoading] = useState(true);
  const [working, setWorking] = useState(false);
  const [logSignal, setLogSignal] = useState(0);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetchWithAuth(`${API_BASE}/catalog/store-status/uber/${storeId}`);
      if (res.ok) { const d = await res.json(); setStatus(d.status); }
      else { setStatus("ERROR"); }
    } catch { setStatus("ERROR"); }
    setLoading(false);
  }, [storeId]);

  useEffect(() => { load(); }, [load]);

  const change = async (newStatus) => {
    setWorking(true);
    try {
      const res = await fetchWithAuth(`${API_BASE}/catalog/store-status/uber/${storeId}`, {
        method: "POST",
        body: JSON.stringify({ status: newStatus }),
      });
      const d = await res.json().catch(() => ({}));
      if (res.ok) { showToast(d.message || "Estado actualizado"); setStatus(newStatus); setLogSignal((s) => s + 1); }
      else { showToast(d.message || "Error al cambiar estado"); }
    } catch { showToast("Error de conexión"); }
    setWorking(false);
  };

  const isOnline = status === "ONLINE";
  const isPaused = status === "PAUSED";

  return (
    <div>
      <div className="admin-toolbar">
        <h2>Estado de Tienda</h2>
        <span className="muted" style={{ fontSize: 13 }}>Abre o pausa tu tienda en las plataformas</span>
      </div>

      <div className="platform-sync-card" style={{ maxWidth: 520 }}>
        <div className="platform-sync-head">
          <span className="platform-chip-sm" style={{ "--p-color": "#00C16A" }}><span className="pdot" /> Uber Eats</span>
          <span className="muted" style={{ fontSize: 12 }}>{storeName}</span>
        </div>

        {loading ? (
          <div className="muted" style={{ padding: "16px 0" }}><Icon name="refresh" size={16} /> Consultando estado...</div>
        ) : (
          <>
            <div className="store-status-badge-row">
              <span className={`store-status-badge ${isOnline ? "online" : isPaused ? "paused" : "offline"}`}>
                <span className="dot" />
                {isOnline ? "Abierta (ONLINE)" : isPaused ? "Pausada (PAUSED)" : status === "OFFLINE" ? "Cerrada (OFFLINE)" : status}
              </span>
            </div>
            <p className="muted" style={{ fontSize: 13, margin: "12px 0 16px" }}>
              {isOnline
                ? "Tu tienda está recibiendo pedidos en Uber Eats."
                : "Tu tienda NO está recibiendo pedidos en Uber Eats."}
            </p>
            <div className="store-status-actions">
              <button className="btn btn-action" disabled={working || isOnline} onClick={() => change("ONLINE")}>
                <Icon name="check" size={14} /> Abrir tienda
              </button>
              <button className="btn" style={{ borderColor: "#D97706", color: "#D97706" }} disabled={working || isPaused} onClick={() => change("PAUSED")}>
                <Icon name="ban" size={14} /> Pausar (hoy)
              </button>
            </div>
            <div className="menusync-info" style={{ marginTop: 16, marginBottom: 0 }}>
              <Icon name="alert" size={14} />
              <div>
                <strong>Pausar</strong> cierra la tienda temporalmente hasta el fin del día (medianoche).
                <strong> Abrir</strong> quita esa pausa. Úsalo cuando no laboren o en emergencias.
                <br />
                Ojo: "Abrir" <strong>no adelanta la hora de apertura</strong>. La tienda abre según el
                <strong> Horario de Atención</strong>; si quieres abrir antes, cambia el horario en la pestaña
                <strong> Horarios</strong> (se sincroniza con Uber al guardar).
              </div>
            </div>
          </>
        )}
      </div>

      <ActivityHistory storeId={storeId} category="status" refreshSignal={logSignal} />
    </div>
  );
};

// ============================================
// Sincronización de menú a plataformas
// ============================================
const StoreMenuSync = ({ storeId, storeName, showToast }) => {
  const [syncing, setSyncing] = useState(null); // "uber" | "rappi" | null
  const [results, setResults] = useState({}); // { uber: {ok,msg}, rappi: {ok,msg} }
  const [logSignal, setLogSignal] = useState(0);

  const platforms = [
    { id: "uber", label: "Uber Eats", color: "#00C16A" },
    { id: "rappi", label: "Rappi", color: "#FF4D4D" },
  ];

  const sync = async (platform) => {
    setSyncing(platform.id);
    setResults((r) => ({ ...r, [platform.id]: null }));
    try {
      const res = await fetchWithAuth(`${API_BASE}/catalog/sync-menu/${platform.id}/${storeId}`, { method: "POST" });
      const d = await res.json().catch(() => ({}));
      if (res.ok) {
        showToast(`${platform.label}: ${d.items} productos sincronizados`);
        setResults((r) => ({ ...r, [platform.id]: { ok: true, msg: `${d.items} productos enviados a ${platform.label}` } }));
        setLogSignal((s) => s + 1);
      } else {
        showToast(d.message || "Error al sincronizar");
        setResults((r) => ({ ...r, [platform.id]: { ok: false, msg: d.message || "Error al sincronizar" } }));
      }
    } catch (e) {
      showToast("Error de conexión");
      setResults((r) => ({ ...r, [platform.id]: { ok: false, msg: "Error de conexión" } }));
    }
    setSyncing(null);
  };

  return (
    <div>
      <div className="admin-toolbar">
        <h2>Menú en Plataformas</h2>
        <span className="muted" style={{ fontSize: 13 }}>Envía tu catálogo a las plataformas de delivery</span>
      </div>

      <div className="menusync-info">
        <Icon name="alert" size={15} />
        <div>
          El menú se construye desde tu <strong>catálogo</strong> (productos, categorías y modificadores)
          usando el modelo de <strong>precio base + ajuste</strong>, para que los precios no se dupliquen.
          Solo se envían los productos <strong>activos</strong>.
        </div>
      </div>

      <div className="platform-sync-grid">
        {platforms.map((pl) => {
          const result = results[pl.id];
          return (
            <div key={pl.id} className="platform-sync-card">
              <div className="platform-sync-head">
                <span className="platform-chip-sm" style={{ "--p-color": pl.color }}><span className="pdot" /> {pl.label}</span>
                <span className="muted" style={{ fontSize: 12 }}>{storeName}</span>
              </div>
              <p className="muted" style={{ fontSize: 13, margin: "8px 0 14px" }}>
                Sube el menú completo (productos con sus tamaños/modificadores) a tu tienda de {pl.label}.
              </p>
              <button className="btn btn-action" onClick={() => sync(pl)} disabled={syncing !== null}>
                <Icon name={syncing === pl.id ? "refresh" : "menu"} size={15} /> {syncing === pl.id ? "Sincronizando..." : `Sincronizar menú a ${pl.label}`}
              </button>
              {result && (
                <div className={`sync-result ${result.ok ? "ok" : "err"}`}>
                  <Icon name={result.ok ? "check" : "x"} size={14} /> {result.msg}
                </div>
              )}
            </div>
          );
        })}
      </div>

      <ActivityHistory storeId={storeId} category="menusync" refreshSignal={logSignal} />
    </div>
  );
};

// ============================================
// Config: Activación / migración de integración Uber (pos_data)
// Cambia webhooks_version a 1.0.0 → Uber enruta los webhooks a la nueva API (/delivery)
// ============================================
const UberIntegrationConfig = ({ storeId, storeName, showToast }) => {
  const [config, setConfig] = useState(null);
  const [loading, setLoading] = useState(true);
  const [working, setWorking] = useState(false);
  const [result, setResult] = useState(null);
  const [confirmOpen, setConfirmOpen] = useState(false);
  const [logSignal, setLogSignal] = useState(0);
  const [valResults, setValResults] = useState({}); // { key: {ok, msg} }
  const [valBusy, setValBusy] = useState(null);

  const load = useCallback(async () => {
    setLoading(true);
    setResult(null);
    try {
      const res = await fetchWithAuth(`${API_BASE}/catalog/integration/uber/${storeId}`);
      const d = await res.json().catch(() => ({}));
      if (res.ok) setConfig(d.config || {});
      else { setConfig(null); setResult({ ok: false, msg: d.message || "No se pudo consultar la integración" }); }
    } catch (e) {
      setConfig(null);
      setResult({ ok: false, msg: "Error de conexión" });
    }
    setLoading(false);
  }, [storeId]);

  useEffect(() => { load(); }, [load]);

  // --- Validación de producción: ejecutar cada endpoint y mostrar el resultado ---
  const runVal = async (key, method, path, okMsg, bodyObj) => {
    setValBusy(key);
    try {
      const res = await fetchWithAuth(`${API_BASE}${path}`, {
        method,
        headers: { "Content-Type": "application/json" },
        ...(method === "POST" ? { body: JSON.stringify(bodyObj || {}) } : {}),
      });
      const d = await res.json().catch(() => ({}));
      if (res.ok) setValResults((r) => ({ ...r, [key]: { ok: true, msg: okMsg(d) } }));
      else setValResults((r) => ({ ...r, [key]: { ok: false, msg: `HTTP ${res.status}: ${d.error || d.message || "error"}` } }));
    } catch (e) {
      setValResults((r) => ({ ...r, [key]: { ok: false, msg: "Error de conexión" } }));
    }
    setValBusy(null);
  };

  const connectUber = async () => {
    setValBusy("oauth");
    try {
      const res = await fetchWithAuth(`${API_BASE}/uber/oauth/authorize/${storeId}`);
      const d = await res.json().catch(() => ({}));
      if (res.ok && d.authorize_url) {
        window.open(d.authorize_url, "_blank", "width=520,height=720");
        setValResults((r) => ({ ...r, oauth: { ok: true, msg: "Se abrió el login de Uber. Autoriza y vuelve a 'Activar'." } }));
      } else setValResults((r) => ({ ...r, oauth: { ok: false, msg: d.error || "No se pudo generar la URL" } }));
    } catch (e) { setValResults((r) => ({ ...r, oauth: { ok: false, msg: "Error de conexión" } })); }
    setValBusy(null);
  };

  const migrate = async () => {
    setConfirmOpen(false);
    setWorking(true);
    setResult(null);
    try {
      const res = await fetchWithAuth(`${API_BASE}/catalog/integration/uber/${storeId}/update`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ webhooks_version: "1.0.0", integration_enabled: true }),
      });
      const d = await res.json().catch(() => ({}));
      if (res.ok) {
        showToast("Integración migrada a la nueva API (/delivery)");
        setResult({ ok: true, msg: "Integración actualizada: los webhooks ahora usan la nueva API (/delivery)." });
        setLogSignal((s) => s + 1);
        load();
      } else {
        showToast(d.message || "Error al migrar la integración");
        setResult({ ok: false, msg: d.message || "Error al migrar la integración" });
      }
    } catch (e) {
      showToast("Error de conexión");
      setResult({ ok: false, msg: "Error de conexión" });
    }
    setWorking(false);
  };

  const wh = config && config.webhooks_config ? config.webhooks_config : null;
  const currentVersion = wh && wh.webhooks_version ? wh.webhooks_version : null;
  const isNewApi = currentVersion === "1.0.0";

  return (
    <div>
      <div className="admin-toolbar">
        <h2>Integración Uber Eats</h2>
        <span className="muted" style={{ fontSize: 13 }}>{storeName}</span>
      </div>

      <div className="menusync-info">
        <Icon name="alert" size={15} />
        <div>
          La <strong>versión de webhooks</strong> determina a qué API te envía Uber los pedidos.
          Con <strong>1.0.0</strong> Uber usa la <strong>nueva API (/delivery)</strong>, que es la requerida
          para validar producción. Este cambio aplica directamente sobre tu tienda en Uber.
        </div>
      </div>

      {loading ? (
        <div className="empty"><div className="empty-text">Consultando integración…</div></div>
      ) : (
        <div className="platform-sync-card" style={{ maxWidth: 560 }}>
          <div className="platform-sync-head">
            <span className="platform-chip-sm" style={{ "--p-color": "#00C16A" }}><span className="pdot" /> Uber Eats</span>
            {config && (
              <span className={`sync-result ${isNewApi ? "ok" : "err"}`} style={{ margin: 0, padding: "3px 10px" }}>
                {isNewApi ? "Nueva API (/delivery)" : currentVersion ? `API previa (v${currentVersion})` : "API previa (/eats)"}
              </span>
            )}
          </div>

          {config && (
            <div className="muted" style={{ fontSize: 13, margin: "10px 0 14px", lineHeight: 1.7 }}>
              <div>webhooks_version: <strong>{currentVersion || "(no definido → API previa)"}</strong></div>
              {typeof config.integration_enabled !== "undefined" && <div>integración habilitada: <strong>{config.integration_enabled ? "sí" : "no"}</strong></div>}
              {config.online_status && <div>estado: <strong>{config.online_status}</strong></div>}
            </div>
          )}

          {isNewApi ? (
            <div className="sync-result ok"><Icon name="check" size={14} /> Esta tienda ya usa la nueva API.</div>
          ) : (
            <button className="btn btn-action" onClick={() => setConfirmOpen(true)} disabled={working}>
              <Icon name={working ? "refresh" : "link"} size={15} /> {working ? "Migrando…" : "Migrar a la nueva API (/delivery)"}
            </button>
          )}

          {result && (
            <div className={`sync-result ${result.ok ? "ok" : "err"}`}>
              <Icon name={result.ok ? "check" : "x"} size={14} /> {result.msg}
            </div>
          )}
        </div>
      )}

      <ConfirmModal
        open={confirmOpen}
        title="Migrar integración a la nueva API"
        message={`Se actualizará la configuración de "${storeName}" en Uber para que los webhooks usen la nueva API (/delivery), con webhooks_version 1.0.0. ¿Continuar?`}
        confirmLabel="Sí, migrar"
        confirmDanger={false}
        onConfirm={migrate}
        onCancel={() => setConfirmOpen(false)}
      />

      {/* Validación de producción Uber: ejecutar los endpoints que Uber requiere con 200 */}
      <div style={{ marginTop: 22 }}>
        <h3 style={{ fontSize: 14, margin: "0 0 4px", display: "flex", alignItems: "center", gap: 6 }}>
          <Icon name="check" size={15} /> Validación de Producción (Uber)
        </h3>
        <p className="muted" style={{ fontSize: 12, margin: "0 0 12px" }}>
          Uber requiere que estos endpoints respondan 200 desde la app de prueba. Ejecútalos aquí.
        </p>
        <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
          {[
            { key: "stores", label: "1. Get Stores", run: () => runVal("stores", "GET", `/catalog/integration/uber/${storeId}/stores`, (d) => `OK · ${d.stores_count} tiendas`) },
            { key: "report", label: "2. Crear Reporte", run: () => runVal("report", "POST", `/catalog/integration/uber/${storeId}/report`, (d) => `OK · workflow ${String(d.workflow_id || "").slice(0, 12)}…`) },
            { key: "deny", label: "3. Rechazar pedido nuevo (Deny)", run: () => runVal("deny", "POST", `/catalog/integration/uber/${storeId}/deny`, (d) => `OK · pedido #${d.order_id} rechazado`) },
            { key: "activate", label: "4. Activar Integración (pos_data)", run: () => runVal("activate", "POST", `/catalog/integration/uber/${storeId}/activate`, () => "OK · integración activada") },
            { key: "fulfill", label: "5. Fulfillment Issue (agotado en pedido)", run: () => runVal("fulfill", "POST", `/catalog/integration/uber/${storeId}/fulfillment-issue`, (d) => `OK · pedido #${d.order_id}, item reportado`) },
            { key: "getstatus", label: "6. Consultar estado de tienda (Get)", run: () => runVal("getstatus", "GET", `/catalog/store-status/uber/${storeId}`, (d) => `OK · estado ${d.status}`) },
            { key: "setstatus", label: "7. Fijar estado de tienda (Set)", run: () => runVal("setstatus", "POST", `/catalog/store-status/uber/${storeId}`, (d) => `OK · ${d.status}`, { status: "ONLINE" }) },
          ].map((b) => (
            <div key={b.key} style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap" }}>
              <button className="btn btn-sm" style={{ minWidth: 230, justifyContent: "flex-start" }} onClick={b.run} disabled={valBusy !== null}>
                <Icon name={valBusy === b.key ? "refresh" : "arrowRight"} size={14} /> {b.label}
              </button>
              {valResults[b.key] && (
                <span className={`sync-result ${valResults[b.key].ok ? "ok" : "err"}`} style={{ margin: 0, padding: "3px 10px", fontSize: 12 }}>
                  <Icon name={valResults[b.key].ok ? "check" : "x"} size={13} /> {valResults[b.key].msg}
                </span>
              )}
            </div>
          ))}

          {/* OAuth + nota de Deny */}
          <div style={{ display: "flex", alignItems: "center", gap: 10, flexWrap: "wrap", borderTop: "1px solid var(--border)", paddingTop: 10, marginTop: 2 }}>
            <button className="btn btn-sm" style={{ minWidth: 230, justifyContent: "flex-start", borderColor: "#00C16A", color: "#00C16A" }} onClick={connectUber} disabled={valBusy !== null}>
              <Icon name="link" size={14} /> Conectar con Uber (para Activar)
            </button>
            {valResults.oauth && (
              <span className={`sync-result ${valResults.oauth.ok ? "ok" : "err"}`} style={{ margin: 0, padding: "3px 10px", fontSize: 12 }}>
                <Icon name={valResults.oauth.ok ? "check" : "x"} size={13} /> {valResults.oauth.msg}
              </span>
            )}
          </div>
          <div className="menusync-info" style={{ marginTop: 4 }}>
            <Icon name="alert" size={14} />
            <div>
              <strong>Activar (#4)</strong> requiere primero <strong>Conectar con Uber</strong> (login del merchant).
              <strong> Deny (#3)</strong>: pedido de prueba <strong>sin aceptar</strong> → "Rechazar pedido nuevo".
              <strong> Fulfillment (#5)</strong>: pedido de prueba <strong>aceptado</strong> → reporta un artículo agotado a Uber.
              <strong> Además:</strong> hacer un <strong>pedido programado</strong> en Uber (webhook de scheduled) y <strong>cancelar</strong> un pedido aceptado desde Pedidos (webhook de cancelación).
            </div>
          </div>
        </div>
      </div>

      <ActivityHistory storeId={storeId} category="integration" refreshSignal={logSignal} />
    </div>
  );
};

// ============================================
// Historial de actividad por sección (reutilizable)
// category: "status" | "menusync" | "integration"
// refreshSignal: cambia para forzar recarga tras una acción
// ============================================
const ActivityHistory = ({ storeId, category, refreshSignal }) => {
  const [items, setItems] = useState([]);
  const [loading, setLoading] = useState(true);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetchWithAuth(`${API_BASE}/catalog/activity/${storeId}?category=${category}&limit=15`);
      if (res.ok) { const d = await res.json(); setItems(d.activity || []); }
      else setItems([]);
    } catch { setItems([]); }
    setLoading(false);
  }, [storeId, category]);

  useEffect(() => { load(); }, [load, refreshSignal]);

  return (
    <div style={{ marginTop: 22 }}>
      <h3 style={{ fontSize: 14, margin: "0 0 10px", display: "flex", alignItems: "center", gap: 6 }}>
        <Icon name="history" size={15} /> Historial
      </h3>
      {loading ? (
        <div className="muted" style={{ fontSize: 13 }}>Cargando…</div>
      ) : items.length === 0 ? (
        <div className="muted" style={{ fontSize: 13 }}>Sin actividad registrada todavía.</div>
      ) : (
        <ul style={{ listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 8 }}>
          {items.map((a) => (
            <li key={a.id} style={{ display: "flex", gap: 10, alignItems: "flex-start", padding: "8px 11px", borderRadius: 8, background: "var(--surface)", border: "1px solid var(--border)" }}>
              <Icon name={a.success ? "check" : "x"} size={14} style={{ color: a.success ? "var(--accent)" : "var(--danger)", marginTop: 2, flexShrink: 0 }} />
              <div style={{ flex: 1, minWidth: 0 }}>
                <div style={{ fontSize: 13, fontWeight: 600 }}>{a.action}</div>
                {a.detail && <div className="muted" style={{ fontSize: 12 }}>{a.detail}</div>}
                <div className="muted" style={{ fontSize: 11, marginTop: 2 }}>
                  {new Date(a.created_at).toLocaleString("es-MX", { day: "2-digit", month: "short", hour: "2-digit", minute: "2-digit" })}
                  {a.username ? ` · ${a.username}` : ""}
                </div>
              </div>
            </li>
          ))}
        </ul>
      )}
    </div>
  );
};

// ============================================
// Config: Colaboradores del KDS (quiénes preparan)
// Alta/edición con área: cocina, bebidas o ambos.
// ============================================
const COOK_AREAS = [
  { key: "cocina", label: "Cocina", color: "#E67E22" },
  { key: "bebidas", label: "Bebidas", color: "#3498DB" },
  { key: "ambos", label: "Ambas", color: "#477327" },
];

const KdsCooksConfig = ({ storeId, showToast }) => {
  const [cooks, setCooks] = useState([]);
  const [loading, setLoading] = useState(true);
  const [newName, setNewName] = useState("");
  const [newArea, setNewArea] = useState("ambos");
  const [saving, setSaving] = useState(false);

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const res = await fetchWithAuth(`${API_BASE}/kds/cooks?storeId=${storeId}`);
      const d = await res.json().catch(() => ({}));
      setCooks(res.ok ? (d.cooks || []) : []);
    } catch { setCooks([]); }
    setLoading(false);
  }, [storeId]);

  useEffect(() => { load(); }, [load]);

  const create = async () => {
    if (newName.trim().length < 2) { showToast("Escribe el nombre del colaborador"); return; }
    setSaving(true);
    try {
      const res = await fetchWithAuth(`${API_BASE}/kds/cooks`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ name: newName.trim(), area: newArea, storeId }),
      });
      const d = await res.json().catch(() => ({}));
      if (res.ok) { showToast(`Colaborador ${d.cook_code} agregado`); setNewName(""); setNewArea("ambos"); load(); }
      else showToast(d.error || d.message || "Error al agregar");
    } catch { showToast("Error de conexión"); }
    setSaving(false);
  };

  const update = async (dbId, patch, okMsg) => {
    try {
      const res = await fetchWithAuth(`${API_BASE}/kds/cooks/${dbId}`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ...patch, storeId }),
      });
      if (res.ok) { showToast(okMsg); load(); }
      else { const d = await res.json().catch(() => ({})); showToast(d.error || "Error al actualizar"); }
    } catch { showToast("Error de conexión"); }
  };

  const rename = (c) => {
    const name = window.prompt("Nuevo nombre del colaborador:", c.name);
    if (name && name.trim().length >= 2) update(c.dbId, { name: name.trim() }, "Nombre actualizado");
  };

  const areaChipStyle = (opt, active) => ({
    padding: "5px 12px", borderRadius: 16, fontSize: 12, fontWeight: 700, cursor: "pointer",
    border: `1.5px solid ${active ? opt.color : "var(--border)"}`,
    background: active ? `${opt.color}1A` : "var(--surface)",
    color: active ? opt.color : "var(--text-3)",
  });

  return (
    <div>
      <h2 style={{ fontSize: 16, margin: "0 0 4px" }}>Colaboradores del KDS</h2>
      <p className="muted" style={{ fontSize: 12.5, margin: "0 0 16px" }}>
        Quiénes preparan los platillos. El área define dónde aparecen en la pantalla de cocina:
        <strong> Cocina</strong>, <strong>Bebidas</strong> o <strong>Ambas</strong>.
      </p>

      {/* Alta */}
      <div style={{ display: "flex", gap: 10, alignItems: "center", flexWrap: "wrap", padding: 14, border: "1px solid var(--border)", borderRadius: 10, background: "var(--surface)", marginBottom: 18 }}>
        <input
          className="reports-select" style={{ minWidth: 220, flex: "0 1 260px" }}
          placeholder="Nombre del colaborador…" value={newName}
          onChange={(e) => setNewName(e.target.value)}
          onKeyDown={(e) => { if (e.key === "Enter") create(); }}
        />
        <div style={{ display: "flex", gap: 6 }}>
          {COOK_AREAS.map((o) => (
            <span key={o.key} style={areaChipStyle(o, newArea === o.key)} onClick={() => setNewArea(o.key)}>{o.label}</span>
          ))}
        </div>
        <button className="btn btn-primary btn-sm" onClick={create} disabled={saving}>
          <Icon name="plus" size={14} /> Agregar
        </button>
      </div>

      {/* Lista */}
      {loading ? (
        <div className="muted" style={{ fontSize: 13 }}>Cargando…</div>
      ) : cooks.length === 0 ? (
        <div className="empty"><div className="empty-text">Sin colaboradores registrados. Agrega el primero arriba.</div></div>
      ) : (
        <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
          {cooks.map((c) => (
            <div key={c.dbId} style={{ display: "flex", alignItems: "center", gap: 12, padding: "10px 14px", border: "1px solid var(--border)", borderRadius: 10, background: "var(--surface)", flexWrap: "wrap" }}>
              <span style={{ width: 34, height: 34, borderRadius: "50%", background: c.color, color: "#fff", display: "grid", placeItems: "center", fontSize: 12, fontWeight: 800 }}>{c.initials}</span>
              <div style={{ minWidth: 160, flex: "0 1 220px" }}>
                <div style={{ fontWeight: 700, fontSize: 13.5 }}>{c.name}</div>
                <div className="muted" style={{ fontSize: 11 }}>Código {c.id}</div>
              </div>
              <div style={{ display: "flex", gap: 6, flex: 1 }}>
                {COOK_AREAS.map((o) => (
                  <span key={o.key} style={areaChipStyle(o, c.area === o.key)}
                    onClick={() => c.area !== o.key && update(c.dbId, { area: o.key }, `${c.name} → ${o.label}`)}>
                    {o.label}
                  </span>
                ))}
              </div>
              <button className="btn btn-sm" onClick={() => rename(c)}><Icon name="edit" size={13} /> Renombrar</button>
              <button className="btn btn-sm" style={{ color: "var(--mym-red)" }}
                onClick={() => { if (window.confirm(`¿Dar de baja a ${c.name}?`)) update(c.dbId, { is_active: false }, `${c.name} dado de baja`); }}>
                <Icon name="x" size={13} /> Baja
              </button>
            </div>
          ))}
        </div>
      )}
    </div>
  );
};

Object.assign(window, { StoreConfigView, ActivityHistory });
