// ====== Main app shell ======

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accent": "#c8a25c",
  "density": "Comfortable"
}/*EDITMODE-END*/;

const ACCENT_MAP = {
  "#c8a25c": { deep: "#b48a3a", soft: "#f3e7c4" },  // Antique Gold
  "#5c9b7b": { deep: "#357a5a", soft: "#d8ead9" },  // Imperial Jade
  "#b35a4a": { deep: "#8a3e30", soft: "#f3d7d0" },  // Ceremonial Rouge
  "#b87349": { deep: "#915732", soft: "#f0d9c4" },  // Copper
};

const STORE_PICK_AFTER_LOGIN_KEY = "teaGangPickStoreAfterLogin";
const NAV_ORDER_FILTER_STORAGE_KEY = "teaGangOrdersFiltersV1";
const NAV_ORDER_FILTER_CHANGED_EVENT = "teaGangOrdersFiltersChanged";
const NAV_ORDER_DATE_FILTERS = new Set(["all", "today", "week", "month", "custom-day", "custom-week", "custom-month", "custom-range"]);
const NAV_ORDER_CHANNEL_FILTERS = new Set(["all", "pickup", "delivery"]);
const DEFAULT_NAV_ORDER_FILTERS = {
  dateFilter: "today",
  dateBasis: "scheduled",
  customDate: "",
  customRange: { from: "", to: "" },
  channelFilter: "all",
  sourceFilter: "all",
  query: "",
};

const normalizeNavOrderFilters = (saved = {}) => ({
  dateFilter: NAV_ORDER_DATE_FILTERS.has(saved.dateFilter) || String(saved.dateFilter || "").startsWith("custom-range:")
    ? saved.dateFilter
    : "today",
  dateBasis: saved.dateBasis === "created" ? "created" : "scheduled",
  customDate: typeof saved.customDate === "string" ? saved.customDate : "",
  customRange: saved.customRange && typeof saved.customRange === "object"
    ? { from: saved.customRange.from || "", to: saved.customRange.to || "" }
    : { from: "", to: "" },
  channelFilter: NAV_ORDER_CHANNEL_FILTERS.has(saved.channelFilter) ? saved.channelFilter : "all",
  sourceFilter: typeof saved.sourceFilter === "string" ? saved.sourceFilter : "all",
  query: typeof saved.query === "string" ? saved.query : "",
});

const readNavOrderFilters = () => {
  try {
    const raw = window.localStorage.getItem(NAV_ORDER_FILTER_STORAGE_KEY);
    if (!raw) return { ...DEFAULT_NAV_ORDER_FILTERS, customRange: { ...DEFAULT_NAV_ORDER_FILTERS.customRange } };
    return normalizeNavOrderFilters(JSON.parse(raw));
  } catch {
    return { ...DEFAULT_NAV_ORDER_FILTERS, customRange: { ...DEFAULT_NAV_ORDER_FILTERS.customRange } };
  }
};

const navOrderFilterRange = (filters, customDateRanges = []) => {
  const namedRange = window.TeaGangCustomDateRanges?.findByFilter?.(customDateRanges, filters.dateFilter);
  if (namedRange) return window.TeaGangCustomDateRanges.range(namedRange);
  const now = new Date();
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const day = 864e5;
  switch (filters.dateFilter) {
    case "all": return {};
    case "today": return { dateFrom: today, dateTo: new Date(today.getTime() + day) };
    case "week": {
      const start = new Date(today);
      start.setDate(today.getDate() - ((today.getDay() || 7) - 1));
      return { dateFrom: start, dateTo: new Date(today.getTime() + day) };
    }
    case "month": return { dateFrom: new Date(now.getFullYear(), now.getMonth()), dateTo: new Date(today.getTime() + day) };
    case "custom-day": {
      if (!filters.customDate) return {};
      const date = new Date(`${filters.customDate}T00:00:00`);
      return { dateFrom: date, dateTo: new Date(date.getTime() + day) };
    }
    case "custom-week": {
      if (!filters.customDate) return {};
      const date = new Date(`${filters.customDate}T00:00:00`);
      const start = new Date(date);
      start.setDate(date.getDate() - ((date.getDay() || 7) - 1));
      return { dateFrom: start, dateTo: new Date(start.getTime() + 7 * day) };
    }
    case "custom-month": {
      if (!filters.customDate) return {};
      const [year, month] = filters.customDate.split("-").map(Number);
      return { dateFrom: new Date(year, month - 1), dateTo: new Date(year, month) };
    }
    case "custom-range": {
      const range = filters.customRange || {};
      if (!range.from || !range.to || range.from > range.to) return {};
      const from = new Date(`${range.from}T00:00:00`);
      const to = new Date(`${range.to}T00:00:00`);
      return { dateFrom: from, dateTo: new Date(to.getTime() + day) };
    }
    default: return {};
  }
};

const normalizeNavOrderSearch = (value) => {
  if (typeof normalizeVi === "function") return normalizeVi(value);
  return (value || "").toString().toLowerCase();
};

const navOrderMatchesFilters = (order, filters) => {
  if (filters.channelFilter !== "all" && order.channel !== filters.channelFilter) return false;
  if (filters.sourceFilter !== "all" && order.source_id !== filters.sourceFilter && order.source !== filters.sourceFilter) return false;
  const query = normalizeNavOrderSearch(filters.query.trim());
  if (!query) return true;
  return (
    normalizeNavOrderSearch(order.customer || "").includes(query) ||
    normalizeNavOrderSearch(order.id || "").includes(query) ||
    (order.items || [])
      .filter(item => item.is_included_addon !== true)
      .some(item => normalizeNavOrderSearch(item.name || "").includes(query))
  );
};

const AuthScreen = ({ error, onGoogle }) => (
  <div style={{
    minHeight: "100vh",
    display: "grid",
    placeItems: "center",
    background: "var(--cream-100)",
    padding: 24,
  }}>
    <div className="card" style={{ width: "min(460px, 100%)", padding: 28 }}>
      <div className="brand" style={{ background: "transparent", border: 0, padding: 0, marginBottom: 22 }}>
        <div className="brand-mark" style={{ backgroundImage: "url(assets/logo.jpg)" }} />
        <div>
          <div className="brand-name" style={{ color: "var(--green-800)" }}>The Tea Gang</div>
          <div className="brand-sub">secure admin console</div>
        </div>
      </div>
      <div className="page-eyebrow">Staff sign in</div>
      <h1 className="page-title" style={{ fontSize: 34, margin: "4px 0 10px" }}>Welcome back</h1>
      <p className="muted" style={{ margin: "0 0 20px" }}>
        Sign in with a store member account. Store data is loaded through Supabase RLS after authentication.
      </p>
      {error && (
        <div style={{
          padding: 12,
          background: "rgba(179,90,74,0.10)",
          color: "var(--rose-500)",
          borderRadius: "var(--r-md)",
          marginBottom: 14,
          fontSize: 13,
        }}>{error}</div>
      )}
      <button className="btn btn-primary" onClick={onGoogle} style={{ width: "100%", justifyContent: "center" }}>
        Sign in with Google
      </button>
    </div>
  </div>
);

const StoreScreen = ({ stores, onSelect, onSignOut }) => (
  <div style={{ minHeight: "100vh", display: "grid", placeItems: "center", background: "var(--cream-100)", padding: 24 }}>
    <div className="card" style={{ width: "min(520px, 100%)", padding: 28 }}>
      <div className="page-eyebrow">Choose store</div>
      <h1 className="page-title" style={{ fontSize: 34, margin: "4px 0 14px" }}>Select a workspace</h1>
      <div style={{ display: "flex", flexDirection: "column", gap: 10 }}>
        {stores.map(store => (
          <button key={store.id} className="btn btn-ghost" onClick={() => onSelect(store)} style={{ justifyContent: "space-between" }}>
            <span>{store.name}</span>
            <Ic name="arrow-right" size={14} />
          </button>
        ))}
      </div>
      <button className="btn btn-ghost" onClick={onSignOut} style={{ marginTop: 16, color: "var(--rose-500)" }}>
        Sign out
      </button>
    </div>
  </div>
);

const GlobalToastOverlay = ({ toasts, onDismiss }) => {
  if (!toasts.length) return null;
  return ReactDOM.createPortal(
    <div className="order-toast-stack">
      {toasts.map(toast => (
        <div key={toast.id} className={`order-toast ${toast.tone || "success"}`}>
          <div className="order-toast-icon">
            <Ic name={toast.tone === "error" ? "x" : "check"} size={14} />
          </div>
          <div className="order-toast-copy">
            <div className="order-toast-title">{toast.title}</div>
            <div className="order-toast-message">{toast.message}</div>
          </div>
          <button className="order-toast-close" onClick={() => onDismiss(toast.id)} title="Dismiss">
            <Ic name="x" size={11} />
          </button>
        </div>
      ))}
    </div>,
    document.body
  );
};

const App = () => {
  const [page, setPage] = React.useState("dashboard");
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [session, setSession] = React.useState(null);
  const [stores, setStores] = React.useState([]);
  const [selectedStoreId, setSelectedStoreId] = React.useState("");
  const [authLoading, setAuthLoading] = React.useState(true);
  const [authError, setAuthError] = React.useState("");
  const [userRole, setUserRole] = React.useState("");
  const [globalSearch, setGlobalSearch] = React.useState("");
  const [activeOrderCount, setActiveOrderCount] = React.useState(0);
  const [mobileNavOpen, setMobileNavOpen] = React.useState(false);
  const [toasts, setToasts] = React.useState([]);
  const localOrderMutationUntilRef = React.useRef(0);
  const recentOrderEventUntilRef = React.useRef(new Map());
  const itemToastTimersRef = React.useRef(new Map());

  const notifyGlobal = React.useCallback((title, message, tone = "success") => {
    const id = `${Date.now()}-${Math.random().toString(36).slice(2)}`;
    setToasts(prev => [...prev.slice(-3), { id, title, message, tone }]);
    window.setTimeout(() => {
      setToasts(prev => prev.filter(t => t.id !== id));
    }, 3800);
  }, []);

  const dismissToast = React.useCallback((id) => {
    setToasts(prev => prev.filter(t => t.id !== id));
  }, []);

  const suppressOrderRealtime = React.useCallback(() => {
    localOrderMutationUntilRef.current = Date.now() + 2500;
  }, []);

  const formatRealtimeOrderId = (row) => row?.order_number ? `TG-${row.order_number}` : "Order";
  const orderNotificationSubject = (label, customer) => `${label} of ${customer || "Walk-in guest"}`;
  const statusNotificationVerb = (status) => ({
    ready: "ready",
    completed: "completed",
    pending: "pending",
  }[status] || "updated");
  const isFreshlyCreated = (createdAt) => {
    if (!createdAt) return false;
    const created = new Date(createdAt).getTime();
    return Number.isFinite(created) && Math.abs(Date.now() - created) < 10000;
  };
  const markRecentOrderEvent = (orderId, duration = 2500) => {
    if (!orderId) return;
    const until = Date.now() + duration;
    recentOrderEventUntilRef.current.set(orderId, until);
    window.setTimeout(() => {
      if (recentOrderEventUntilRef.current.get(orderId) === until) {
        recentOrderEventUntilRef.current.delete(orderId);
      }
    }, duration + 250);
  };

  const notifyRealtimeOrderChange = React.useCallback((payload) => {
    if (Date.now() < localOrderMutationUntilRef.current) return;
    if (!["orders", "order_items"].includes(payload?.table)) return;
    const eventType = payload.eventType || payload.event;
    const next = payload.new || {};
    const old = payload.old || {};

    if (payload.table === "order_items") {
      const orderId = next.order_id || old.order_id;
      const recentUntil = recentOrderEventUntilRef.current.get(orderId);
      if (recentUntil && recentUntil > Date.now()) return;

      window.clearTimeout(itemToastTimersRef.current.get(orderId));
      const timer = window.setTimeout(async () => {
        itemToastTimersRef.current.delete(orderId);
        let orderSummary = null;
        try {
          orderSummary = await window.TeaGangBackend?.fetchOrderNotificationSummary?.(orderId);
        } catch (error) {
          console.warn("Could not load order notification context.", error);
        }
        if (!orderSummary && eventType === "DELETE") return;
        if (eventType === "INSERT" && isFreshlyCreated(orderSummary?.created_at)) return;
        const orderLabel = orderSummary?.label || "an order";
        const customer = orderSummary?.customer || "Walk-in guest";
        notifyGlobal("Order edited", `${orderNotificationSubject(orderLabel, customer)} is edited.`);
      }, 500);
      itemToastTimersRef.current.set(orderId, timer);
      return;
    }

    const label = formatRealtimeOrderId(next.id ? next : old);
    const customer = next.customer_name || old.customer_name || "Walk-in guest";

    if (eventType === "INSERT") {
      markRecentOrderEvent(next.id, 2500);
      notifyGlobal("Order added", `${orderNotificationSubject(label, customer)} is added.`);
      return;
    }
    if (eventType === "DELETE") {
      markRecentOrderEvent(old.id, 2500);
      notifyGlobal("Order removed", `${orderNotificationSubject(label, customer)} is removed.`);
      return;
    }
    if (eventType === "UPDATE") {
      markRecentOrderEvent(next.id, 3000);
      if (next.status === "cancelled") {
        notifyGlobal("Order removed", `${orderNotificationSubject(label, customer)} is removed.`);
      } else if (old.status && next.status && old.status !== next.status) {
        notifyGlobal("Order updated", `${orderNotificationSubject(label, customer)} is ${statusNotificationVerb(next.status)}.`);
      } else {
        notifyGlobal("Order edited", `${orderNotificationSubject(label, customer)} is edited.`);
      }
    }
  }, [notifyGlobal]);

  React.useEffect(() => {
    window.TeaGangNotify = notifyGlobal;
    window.TeaGangSuppressOrderRealtime = suppressOrderRealtime;
    return () => {
      if (window.TeaGangNotify === notifyGlobal) delete window.TeaGangNotify;
      if (window.TeaGangSuppressOrderRealtime === suppressOrderRealtime) delete window.TeaGangSuppressOrderRealtime;
      itemToastTimersRef.current.forEach(timer => window.clearTimeout(timer));
      itemToastTimersRef.current.clear();
    };
  }, [notifyGlobal, suppressOrderRealtime]);

  const loadSecureContext = React.useCallback(async (nextSession) => {
    const backend = window.TeaGangBackend;
    if (!backend?.enabled) {
      setAuthError("Supabase client is not available.");
      setAuthLoading(false);
      return;
    }
    setAuthLoading(true);
    try {
      const activeSession = nextSession ?? await backend.getSession();
      setSession(activeSession);
      if (!activeSession) {
        setStores([]);
        setSelectedStoreId("");
        setAuthLoading(false);
        return;
      }
      await backend.bootstrapUserPreferences?.("web", {
        accent: TWEAK_DEFAULTS.accent,
        density: TWEAK_DEFAULTS.density,
      });
      const availableStores = await backend.fetchStores();
      setStores(availableStores);
      const shouldPickStore = window.sessionStorage.getItem(STORE_PICK_AFTER_LOGIN_KEY) === "1";
      const savedStoreId = window.localStorage.getItem("teaGangStoreId");
      const savedStore = availableStores.find(store => store.id === savedStoreId);
      if (!shouldPickStore && savedStore) {
        backend.setStore(savedStore);
        setSelectedStoreId(savedStore.id);
      } else {
        backend.clearStore?.();
        setSelectedStoreId("");
        window.sessionStorage.removeItem(STORE_PICK_AFTER_LOGIN_KEY);
      }
      backend.fetchUserRole?.().then(role => setUserRole(role)).catch(() => setUserRole("Staff"));
      setAuthError("");
    } catch (error) {
      console.error("Auth/store setup failed.", error);
      setAuthError(error.message || "Could not load secure store access.");
    } finally {
      setAuthLoading(false);
    }
  }, []);

  React.useEffect(() => {
    loadSecureContext();
    const subscription = window.TeaGangBackend?.onAuthStateChange?.((nextSession, event) => {
      if (event === "TOKEN_REFRESHED" || event === "USER_UPDATED") return;
      loadSecureContext(nextSession);
    });
    return () => subscription?.unsubscribe?.();
  }, [loadSecureContext]);

  const signIn = async () => {
    setAuthError("");
    try {
      window.sessionStorage.setItem(STORE_PICK_AFTER_LOGIN_KEY, "1");
      await window.TeaGangBackend.signInWithGoogle();
    } catch (error) {
      window.sessionStorage.removeItem(STORE_PICK_AFTER_LOGIN_KEY);
      setAuthError(error.message || "Could not start Google sign in.");
    }
  };

  const signOut = async () => {
    await window.TeaGangBackend?.signOut?.();
    setSession(null);
    setStores([]);
    setSelectedStoreId("");
    window.sessionStorage.removeItem(STORE_PICK_AFTER_LOGIN_KEY);
  };

  const selectStore = (store) => {
    window.TeaGangBackend.setStore(store);
    window.sessionStorage.removeItem(STORE_PICK_AFTER_LOGIN_KEY);
    setSelectedStoreId(store.id);
    setStores([store, ...stores.filter(s => s.id !== store.id)]);
  };

  // Apply accent live
  React.useEffect(() => {
    const a = ACCENT_MAP[t.accent] || ACCENT_MAP["#c8a25c"];
    const r = document.documentElement.style;
    r.setProperty("--gold-500", t.accent);
    r.setProperty("--gold-600", a.deep);
    r.setProperty("--gold-400", t.accent);
    r.setProperty("--gold-700", a.deep);
    r.setProperty("--gold-100", a.soft);
    r.setProperty("--gold-200", a.soft);
    r.setProperty("--line-gold", t.accent + "73");
  }, [t.accent]);

  React.useEffect(() => {
    document.documentElement.style.setProperty("--page-pad", t.density === "Compact" ? "20px 24px 48px" : "28px 32px 60px");
  }, [t.density]);

  const loadActiveOrderCount = React.useCallback(async () => {
    const backend = window.TeaGangBackend;
    if (!session || !selectedStoreId || !backend?.enabled) {
      setActiveOrderCount(0);
      return;
    }
    try {
      const filters = readNavOrderFilters();
      const customDateRanges = await window.TeaGangCustomDateRanges?.load?.();
      const range = navOrderFilterRange(filters, customDateRanges || []);
      const rows = await backend.fetchOrders({ ...range, dateBasis: filters.dateBasis });
      setActiveOrderCount((rows || [])
        .filter(o => o.status === "pending")
        .filter(o => navOrderMatchesFilters(o, filters))
        .length);
    } catch (error) {
      console.warn("Could not load order count.", error);
      setActiveOrderCount(0);
    }
  }, [session, selectedStoreId]);

  React.useEffect(() => { loadActiveOrderCount(); }, [loadActiveOrderCount]);

  React.useEffect(() => {
    const refresh = () => loadActiveOrderCount();
    window.addEventListener(NAV_ORDER_FILTER_CHANGED_EVENT, refresh);
    window.addEventListener(window.TeaGangCustomDateRanges?.event || "teaGangCustomDateRangesChanged", refresh);
    return () => {
      window.removeEventListener(NAV_ORDER_FILTER_CHANGED_EVENT, refresh);
      window.removeEventListener(window.TeaGangCustomDateRanges?.event || "teaGangCustomDateRangesChanged", refresh);
    };
  }, [loadActiveOrderCount]);

  React.useEffect(() => {
    const backend = window.TeaGangBackend;
    if (!session || !selectedStoreId || !backend?.subscribeToStoreData) return undefined;
    let disposed = false;
    let subscription = null;
    backend
      .subscribeToStoreData((payload) => {
        if (!disposed) {
          notifyRealtimeOrderChange(payload);
          loadActiveOrderCount();
        }
      }, ["orders", "order_items"])
      .then(nextSubscription => {
        if (disposed) nextSubscription?.unsubscribe?.();
        else subscription = nextSubscription;
      })
      .catch(error => console.warn("Order count realtime unavailable.", error));
    return () => {
      disposed = true;
      subscription?.unsubscribe?.();
    };
  }, [session, selectedStoreId, loadActiveOrderCount, notifyRealtimeOrderChange]);

  const navTop = [
    { id: "dashboard", label: "Dashboard", icon: "dashboard" },
    { id: "orders", label: "Orders", icon: "orders", badge: activeOrderCount ? String(activeOrderCount) : "" },
    { id: "menu", label: "Menu", icon: "menu" },
  ];
  const navOps = [
    { id: "inventory", label: "Inventory", icon: "inventory" },
    { id: "promotions", label: "Promotions", icon: "promotions" },
    { id: "customers", label: "Customers", icon: "customers" },
  ];
  const navAdmin = [
    { id: "staff", label: "Staff", icon: "staff" },
    { id: "settings", label: "Settings", icon: "settings" },
  ];

  const renderPage = () => {
    if (page === "dashboard") return <Dashboard />;
    if (page === "orders") return <Orders />;
    if (page === "menu") return <Menu />;
    if (page === "inventory") return <Inventory />;
    if (page === "promotions") return <Promotions />;
    if (page === "customers") return <Customers />;
    if (page === "settings") return <Settings accent={t.accent} setAccent={(v) => setTweak("accent", v)} density={t.density} setDensity={(v) => setTweak("density", v)} />;
    return (
      <div style={{ padding: 80, textAlign: "center", color: "var(--ink-500)" }}>
        <div style={{ fontFamily: "var(--font-display)", fontSize: 36, color: "var(--green-800)" }}>Coming soon</div>
        <div style={{ marginTop: 8, fontFamily: "var(--font-script)", color: "var(--gold-600)", fontSize: 22 }}>
          this corner of the shop is still being arranged
        </div>
      </div>
    );
  };

  const crumbLabel = (id) => {
    const all = [...navTop, ...navOps, ...navAdmin];
    return all.find(n => n.id === id)?.label || id;
  };

  const selectNavPage = (id) => {
    setPage(id);
    setMobileNavOpen(false);
  };

  const runGlobalSearch = (value = globalSearch) => {
    const q = normalizeVi(value.trim());
    if (!q) return;
    const targets = [
      { id: "orders", terms: ["order", "orders", "don", "don hang", "khach dat", "drink order"] },
      { id: "menu", terms: ["menu", "drink", "drinks", "do uong", "tra sua", "mon", "thuc don"] },
      { id: "customers", terms: ["customer", "customers", "guest", "guests", "khach", "khach hang"] },
      { id: "inventory", terms: ["inventory", "stock", "ingredient", "ingredients", "kho", "ton kho", "nguyen lieu"] },
      { id: "promotions", terms: ["promotion", "promotions", "promo", "comp", "gift", "discount", "item type", "order item type"] },
      { id: "dashboard", terms: ["dashboard", "report", "sales", "bao cao", "doanh thu"] },
    ];
    const hit = targets.find(target => target.terms.some(term => normalizeVi(term).includes(q) || q.includes(normalizeVi(term))));
    if (hit) setPage(hit.id);
  };

  if (authLoading) {
    return (
      <div style={{ minHeight: "100vh", display: "grid", placeItems: "center", background: "var(--cream-100)" }}>
        <div className="card" style={{ padding: 28 }}>Loading secure session…</div>
      </div>
    );
  }

  if (!session) return <AuthScreen error={authError} onGoogle={signIn} />;

  if (!selectedStoreId) {
    return <StoreScreen stores={stores} onSelect={selectStore} onSignOut={signOut} />;
  }

  return (
    <div className={`app ${mobileNavOpen ? "mobile-nav-open" : ""}`} data-screen-label={`Admin · ${crumbLabel(page)}`}>
      <button
        className="mobile-nav-toggle"
        type="button"
        onClick={() => setMobileNavOpen(open => !open)}
        title={mobileNavOpen ? "Close navigation" : "Open navigation"}
        aria-label={mobileNavOpen ? "Close navigation" : "Open navigation"}
        aria-expanded={mobileNavOpen}
      >
        {mobileNavOpen ? <Ic name="x" size={18} /> : <span className="mobile-nav-toggle-lines" aria-hidden="true" />}
      </button>
      {mobileNavOpen && <button className="mobile-nav-scrim" type="button" onClick={() => setMobileNavOpen(false)} aria-label="Close navigation" />}
      {/* SIDEBAR */}
      <aside className={`sidebar ${mobileNavOpen ? "mobile-open" : ""}`}>
        <div className="brand">
          <div className="brand-mark" style={{ backgroundImage: "url(assets/logo.jpg)" }} />
          <div>
            <div className="brand-name">The Tea Gang</div>
            <div className="brand-sub">drinks &amp; snacks</div>
          </div>
        </div>

        <div className="nav-section">Operate</div>
        {navTop.map(n => (
          <div key={n.id} className={`nav-item ${page === n.id ? "active" : ""}`} onClick={() => selectNavPage(n.id)}>
            <span className="nav-ico"><Ic name={n.icon} size={16} /></span>
            {n.label}
            {n.badge && <span className="nav-badge">{n.badge}</span>}
          </div>
        ))}

        <div className="nav-section">Manage</div>
        {navOps.map(n => (
          <div key={n.id} className={`nav-item ${page === n.id ? "active" : ""}`} onClick={() => selectNavPage(n.id)}>
            <span className="nav-ico"><Ic name={n.icon} size={16} /></span>
            {n.label}
          </div>
        ))}

        <div className="nav-section">Shop</div>
        {navAdmin.map(n => (
          <div key={n.id} className={`nav-item ${page === n.id ? "active" : ""}`} onClick={() => selectNavPage(n.id)}>
            <span className="nav-ico"><Ic name={n.icon} size={16} /></span>
            {n.label}
          </div>
        ))}

        <div className="sidebar-foot">
          {(() => {
            const name = session?.user?.user_metadata?.full_name || session?.user?.email?.split("@")[0] || "User";
            const initials = name.split(" ").map(n => n[0]).filter(Boolean).slice(0, 2).join("").toUpperCase() || "?";
            const storeName = window.localStorage.getItem("teaGangStoreName") || "";
            return (
              <>
                <div className="avatar">{initials}</div>
                <div style={{ minWidth: 0 }}>
                  <div className="user-name" style={{ overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{name}</div>
                  <div className="user-role">{userRole || "Staff"}{storeName ? ` · ${storeName}` : ""}</div>
                </div>
              </>
            );
          })()}
        </div>
      </aside>

      {/* MAIN */}
      <main className="main">
        <div className="topbar">
          <div className="crumbs">
            Tea Gang <span className="sep">/</span> Admin <span className="sep">/</span>
            <span style={{ color: "var(--green-700)" }}>{crumbLabel(page)}</span>
          </div>
          <div className="search">
            <Ic name="search" size={14} />
            <input
              placeholder="Search orders, drinks, guests…"
              value={globalSearch}
              onChange={e => setGlobalSearch(e.target.value)}
              onKeyDown={e => {
                if (e.key === "Enter") runGlobalSearch();
              }}
            />
            {globalSearch && (
              <button
                className="icon-btn"
                style={{ width: 22, height: 22, border: "none", background: "transparent", padding: 0 }}
                onClick={() => setGlobalSearch("")}
                title="Clear"
              ><Ic name="x" size={12} /></button>
            )}
            <span className="mono" style={{ fontSize: 10.5, color: "var(--ink-400)", padding: "0 4px", border: "1px solid var(--line)", borderRadius: 4 }}>⌘K</span>
          </div>
          <button className="icon-btn" title="Notifications"><Ic name="bell" size={16} /><span className="dot" /></button>
          <button className="icon-btn" title="Today"><Ic name="calendar" size={16} /></button>
          <button className="icon-btn" title="Sign out" onClick={signOut}><Ic name="x" size={14} /></button>
        </div>

        <div className="page" style={{ padding: "var(--page-pad)" }}>
          {renderPage()}
        </div>
      </main>

      {/* Tweaks panel */}
      <TweaksPanel title="Tweaks">
        <TweakSection label="Accent">
          <TweakColor
            label="Trim"
            value={t.accent}
            options={["#c8a25c", "#5c9b7b", "#b35a4a", "#b87349"]}
            onChange={(v) => setTweak("accent", v)}
          />
        </TweakSection>

        <TweakSection label="Layout">
          <TweakRadio
            label="Density"
            value={t.density}
            options={["Comfortable", "Compact"]}
            onChange={(v) => setTweak("density", v)}
          />
        </TweakSection>

        <TweakSection label="Page">
          <TweakRadio
            label="View"
            value={page === "dashboard" ? "Dashboard" : page === "orders" ? "Orders" : page === "menu" ? "Menu" : "Dashboard"}
            options={["Dashboard", "Orders", "Menu"]}
            onChange={(v) => setPage(v.toLowerCase())}
          />
        </TweakSection>
      </TweaksPanel>

      <GlobalToastOverlay toasts={toasts} onDismiss={dismissToast} />
    </div>
  );
};

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
