function Dashboard({ lang, onOpenReserves }) {
  const { useState, useEffect, useRef } = React;
  const T = window.T;
  const ResRow = window.ResRow;
  const t = T[lang].dashboard;
  const [profileName, setProfileName] = useState(null);
  const [clientName, setClientName]   = useState(null);

  const LOADING = null;   // null = loading, number/array = resolved

  const [todayCount,    setTodayCount]    = useState(LOADING);
  const [botCount,      setBotCount]      = useState(LOADING);
  const [botActive,     setBotActive]     = useState(LOADING);
  const [upcoming,      setUpcoming]      = useState(LOADING);
  const [pending,       setPending]       = useState(LOADING);
  const timerRef = useRef(null);

  async function fetchAll() {
    const client = await window.SVX.getCurrentClient();
    if (!client) return;
    if (client.name) setClientName(client.name);

    const profile = await window.SVX.getCurrentProfile();
    if (profile && profile.display_name) setProfileName(profile.display_name);

    const clientId = client.id;

    const todayStart = new Date();
    todayStart.setHours(0, 0, 0, 0);
    const todayEnd = new Date();
    todayEnd.setHours(23, 59, 59, 999);

    const since24h = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();

    // a) Reservas de hoy
    const qToday = window.SB
      .from("reservations")
      .select("*", { count: "exact", head: true })
      .eq("client_id", clientId)
      .gte("reserved_at", todayStart.toISOString())
      .lte("reserved_at", todayEnd.toISOString())
      .in("status", ["pending", "confirmed"]);

    // b) Mensajes bot últimas 24h
    const qBot = window.SB
      .from("reservations")
      .select("*", { count: "exact", head: true })
      .eq("client_id", clientId)
      .eq("source", "whatsapp_bot")
      .gte("created_at", since24h);

    // c) Estado bot + ocupación via clients row
    const qClient = window.SB
      .from("clients")
      .select("features_enabled, subscription_status")
      .eq("id", clientId)
      .single();

    // d) Próximas 5 reservas desde hoy
    const qUpcoming = window.SB
      .from("reservations")
      .select("id, reserved_at, guest_name, pax, table_label, source, notes, allergies, status")
      .eq("client_id", clientId)
      .gte("reserved_at", todayStart.toISOString())
      .in("status", ["pending", "confirmed"])
      .order("reserved_at", { ascending: true })
      .limit(5);

    // e) Pendientes de confirmación
    const qPending = window.SB
      .from("reservations")
      .select("id, reserved_at, guest_name, pax, table_label, source, notes, allergies, status")
      .eq("client_id", clientId)
      .eq("status", "pending")
      .order("created_at", { ascending: false })
      .limit(5);

    const [rToday, rBot, rClient, rUpcoming, rPending] = await Promise.all([
      qToday, qBot, qClient, qUpcoming, qPending
    ]);

    if (rToday.error)   { console.error("[Dashboard] today count:", rToday.error);   setTodayCount(0); }
    else                { setTodayCount(rToday.count ?? 0); }

    if (rBot.error)     { console.error("[Dashboard] bot count:", rBot.error);       setBotCount(0); }
    else                { setBotCount(rBot.count ?? 0); }

    if (rClient.error)  { console.error("[Dashboard] client:", rClient.error);        setBotActive(false); }
    else {
      const features = rClient.data.features_enabled || [];
      setBotActive(Array.isArray(features)
        ? features.includes("bot_whatsapp")
        : false);
    }

    if (rUpcoming.error) { console.error("[Dashboard] upcoming:", rUpcoming.error);  setUpcoming([]); }
    else                 { setUpcoming(rUpcoming.data || []); }

    if (rPending.error)  { console.error("[Dashboard] pending:", rPending.error);    setPending([]); }
    else                 { setPending(rPending.data || []); }
  }

  useEffect(() => {
    fetchAll();
    timerRef.current = setInterval(fetchAll, 60000);
    return () => clearInterval(timerRef.current);
  }, []);

  // Helpers
  function fmtHour(iso) {
    if (!iso) return "—";
    const d = new Date(iso);
    return d.toLocaleTimeString(lang === "es" ? "es-ES" : "ca-ES", { hour: "2-digit", minute: "2-digit" });
  }

  function fmtMeta(row) {
    const parts = [];
    if (row.pax)         parts.push(`${row.pax} pers.`);
    if (row.table_label) parts.push(row.table_label);
    return parts.join(" · ") || "";
  }

  const EMPTY_CA = "Encara no hi ha reserves. Quan n'arribi la primera, apareixerà aquí.";
  const EMPTY_ES = "Aún no hay reservas. Cuando llegue la primera, aparecerá aquí.";
  const emptyMsg  = lang === "es" ? EMPTY_ES : EMPTY_CA;

  const botLabel = botActive === LOADING
    ? "—"
    : botActive
      ? (lang === "es" ? "Activo" : "Actiu")
      : (lang === "es" ? "Inactivo" : "Inactiu");

  // Dynamic date string
  const locale = lang === "es" ? "es-ES" : "ca-ES";
  const now = new Date();
  const dateStr = now.toLocaleDateString(locale, { weekday: "long", day: "numeric", month: "long" });
  const hour = now.getHours();
  const serviceLabel = lang === "es"
    ? (hour < 16 ? "Servicio de mediodía" : "Servicio de noche")
    : (hour < 16 ? "Servei de migdia" : "Servei de vespre");
  const dynamicDate = dateStr.charAt(0).toUpperCase() + dateStr.slice(1) + " · " + serviceLabel;

  // Dynamic greeting
  const greetWord = lang === "es"
    ? (hour < 14 ? "Buenos días" : hour < 20 ? "Buenas tardes" : "Buenas noches")
    : (hour < 14 ? "Bon dia" : hour < 20 ? "Bona tarda" : "Bona nit");
  const displayName = profileName || clientName || "";
  const dynamicHi = displayName ? greetWord + ", " + displayName : greetWord;

  // Dynamic ctaSub
  const pendingCount = pending !== LOADING ? pending.length : 0;
  const ctaSubDynamic = pendingCount > 0
    ? (lang === "es"
        ? `${pendingCount} pendiente${pendingCount > 1 ? "s" : ""} de confirmar`
        : `${pendingCount} per confirmar`)
    : (lang === "es" ? "Sin pendientes" : "Sense pendents");

  return (
    <div>
      <header className="srv-page-head">
        <div>
          <div className="eyebrow">{dynamicDate}</div>
          <h1 className="t-h1 srv-greet">{dynamicHi}</h1>
        </div>
      </header>

      <div className="kpi-grid">
        <div className="kpi-card accent">
          <div className="eyebrow">{t.kpi1}</div>
          <div className="kpi-big">
            {todayCount === LOADING ? "—" : todayCount}
            {todayCount !== LOADING && todayCount > 0 && (
              <span className="kpi-delta up">↑ {t.kpi1delta}</span>
            )}
          </div>
        </div>
        <div className="kpi-card">
          <div className="eyebrow">{t.kpi2}</div>
          <div className="kpi-big">
            {todayCount === LOADING
              ? "—"
              : <span style={{fontSize: 24, color: 'var(--ink-3)'}}>—</span>
            }
          </div>
        </div>
        <div className="kpi-card ok">
          <div className="eyebrow">{t.kpi3}</div>
          <div className="kpi-big">
            {botCount === LOADING ? "—" : botCount}
            {botCount !== LOADING && (
              <span className="kpi-delta">{t.kpi3sub}</span>
            )}
          </div>
        </div>
        <div className="kpi-card">
          <div className="eyebrow">{t.kpi4}</div>
          <div className="kpi-status">
            <span className="status-dot"></span>
            {botActive === LOADING ? "—" : botLabel}
          </div>
        </div>
      </div>

      <div className="srv-cta">
        <button className="btn primary" onClick={onOpenReserves}>
          <i className="ph ph-chat-teardrop-text"></i>{t.cta}
        </button>
        <span style={{marginLeft: 14, color: 'var(--ink-2)', fontSize: 14}}>
          {ctaSubDynamic}
        </span>
      </div>

      <section className="srv-sec">
        <div className="srv-sec-head">
          <h2 className="t-h2">{t.todayH}</h2>
          <button className="link-btn" onClick={onOpenReserves}>{t.seeAll} →</button>
        </div>
        <ul className="res-rows">
          {upcoming === LOADING ? (
            <li style={{padding: "16px 0", color: "var(--ink-3)", fontSize: 14}}>—</li>
          ) : upcoming.length === 0 ? (
            <li style={{padding: "16px 0", color: "var(--ink-3)", fontSize: 14}}>{emptyMsg}</li>
          ) : upcoming.map((r) => (
            <ResRow
              key={r.id}
              hour={fmtHour(r.reserved_at)}
              name={r.guest_name}
              meta={fmtMeta(r)}
              src={r.source === "whatsapp_bot" ? "bot" : r.source === "web_form" ? "web" : "manual"}
              note={[r.notes, r.allergies].filter(Boolean).join(" · ")}
              highlight={r.status === "pending"}
              lang={lang}
            />
          ))}
        </ul>
      </section>
    </div>
  );
}

window.Dashboard = Dashboard;
