// ─────────────────────────────────────────────────────────
// ChefVerse · Shell components — sidebar, topbar, locale chip
// ─────────────────────────────────────────────────────────

const { useState, useEffect, useRef } = React;

// Reusable lucide icon (inline SVG so it works without runtime fetch)
function Icon({ name, size = 16, strokeWidth = 1.75, style, className }) {
  const paths = {
    "panel-left":   <><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M9 3v18"/></>,
    "panel-top":    <><rect x="3" y="3" width="18" height="18" rx="2"/><path d="M3 9h18"/></>,
    "bell":         <><path d="M6 8a6 6 0 0 1 12 0c0 7 3 9 3 9H3s3-2 3-9"/><path d="M10.3 21a1.94 1.94 0 0 0 3.4 0"/></>,
    "settings":     <><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></>,
    "search":       <><circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></>,
    "chevron-down": <><path d="m6 9 6 6 6-6"/></>,
    "chevron-up":   <><path d="m18 15-6-6-6 6"/></>,
    "chevron-right":<><path d="m9 18 6-6-6-6"/></>,
    "chevron-left": <><path d="m15 18-6-6 6-6"/></>,
    "chevrons-up-down": <><path d="m7 15 5 5 5-5"/><path d="m7 9 5-5 5 5"/></>,
    "play":         <><polygon points="6 3 20 12 6 21 6 3"/></>,
    "pause":        <><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></>,
    "skip-forward": <><polygon points="5 4 15 12 5 20 5 4"/><line x1="19" x2="19" y1="5" y2="19"/></>,
    "skip-back":    <><polygon points="19 20 9 12 19 4 19 20"/><line x1="5" x2="5" y1="19" y2="5"/></>,
    "list-video":   <><path d="M12 12H3"/><path d="M16 6H3"/><path d="M12 18H3"/><path d="m18 9 5 3-5 3z"/></>,
    "graduation-cap": <><path d="M22 10v6"/><path d="M2 10l10-5 10 5-10 5z"/><path d="M6 12v5c0 1.7 2.7 3 6 3s6-1.3 6-3v-5"/></>,
    "layers":       <><path d="m12 2 9 5-9 5-9-5 9-5z"/><path d="m3 12 9 5 9-5"/><path d="m3 17 9 5 9-5"/></>,
    "salad":        <><path d="M7 21h10"/><path d="M12 21a9 9 0 0 0 9-9H3a9 9 0 0 0 9 9z"/><path d="M11.38 12a2.4 2.4 0 0 1-.4-4.77 2.4 2.4 0 0 1 3.2-2.77 2.4 2.4 0 0 1 3.47-.63 2.4 2.4 0 0 1 3.37 3.37 2.4 2.4 0 0 1-1.1 3.7 2.51 2.51 0 0 1 .03 1.1"/></>,
    "book-open":    <><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></>,
    "compass":      <><circle cx="12" cy="12" r="10"/><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"/></>,
    "shield-check": <><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></>,
    "message-circle": <><path d="M7.9 20A9 9 0 1 0 4 16.1L2 22z"/></>,
    "briefcase":    <><rect width="20" height="14" x="2" y="7" rx="2"/><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"/></>,
    "users":        <><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></>,
    "user":         <><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></>,
    "help-circle":  <><circle cx="12" cy="12" r="10"/><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"/><path d="M12 17h.01"/></>,
    "log-out":      <><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" x2="9" y1="12" y2="12"/></>,
    "mail":         <><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></>,
    "music":        <><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></>,
    "camera":       <><path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3"/></>,
    "edit":         <><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></>,
    "alert-triangle": <><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3z"/><line x1="12" x2="12" y1="9" y2="13"/><line x1="12" x2="12.01" y1="17" y2="17"/></>,
    "globe":        <><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15 15 0 0 1 4 10 15 15 0 0 1-4 10 15 15 0 0 1-4-10 15 15 0 0 1 4-10z"/></>,
    "check":        <><polyline points="20 6 9 17 4 12"/></>,
    "check-circle": <><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></>,
    "circle":       <><circle cx="12" cy="12" r="10"/></>,
    "lock":         <><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></>,
    "clock":        <><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></>,
    "calendar":     <><rect x="3" y="4" width="18" height="18" rx="2"/><line x1="16" x2="16" y1="2" y2="6"/><line x1="8" x2="8" y1="2" y2="6"/><line x1="3" x2="21" y1="10" y2="10"/></>,
    "video":        <><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2"/></>,
    "captions":     <><rect width="18" height="14" x="3" y="5" rx="2"/><path d="M7 15h4M15 15h2"/><path d="M7 11h2M13 11h4"/></>,
    "trending-up":  <><polyline points="22 7 13.5 15.5 8.5 10.5 2 17"/><polyline points="16 7 22 7 22 13"/></>,
    "trending-down":<><polyline points="22 17 13.5 8.5 8.5 13.5 2 7"/><polyline points="16 17 22 17 22 11"/></>,
    "arrow-right":  <><path d="M5 12h14"/><path d="m12 5 7 7-7 7"/></>,
    "arrow-up-right": <><path d="M7 7h10v10"/><path d="M7 17 17 7"/></>,
    "filter":       <><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/></>,
    "plus":         <><path d="M12 5v14"/><path d="M5 12h14"/></>,
    "x":            <><path d="M18 6 6 18"/><path d="m6 6 12 12"/></>,
    "bookmark":     <><path d="m19 21-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/></>,
    "bookmark-plus":<><path d="m19 21-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/><path d="M12 7v6"/><path d="M9 10h6"/></>,
    "maximize":     <><path d="M8 3H5a2 2 0 0 0-2 2v3"/><path d="M21 8V5a2 2 0 0 0-2-2h-3"/><path d="M3 16v3a2 2 0 0 0 2 2h3"/><path d="M16 21h3a2 2 0 0 0 2-2v-3"/></>,
    "minimize":     <><path d="M8 3v3a2 2 0 0 1-2 2H3"/><path d="M21 8h-3a2 2 0 0 1-2-2V3"/><path d="M3 16h3a2 2 0 0 1 2 2v3"/><path d="M16 21v-3a2 2 0 0 1 2-2h3"/></>,
    "instagram":    <><rect width="20" height="20" x="2" y="2" rx="5"/><circle cx="12" cy="12" r="4"/><path d="M17.5 6.5h.01"/></>,
    "facebook":     <><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"/></>,
    "tiktok":       <><path d="M9 12a4 4 0 1 0 4 4V4a5 5 0 0 0 5 5"/></>,
    "youtube":      <><path d="M22 8.5a4.5 4.5 0 0 0-3.5-4.4 89 89 0 0 0-13 0A4.5 4.5 0 0 0 2 8.5v7a4.5 4.5 0 0 0 3.5 4.4 89 89 0 0 0 13 0A4.5 4.5 0 0 0 22 15.5z"/><polygon points="10 9 15 12 10 15 10 9"/></>,
    "moon":         <><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></>,
    "sun":          <><circle cx="12" cy="12" r="4"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></>,
    "more-horizontal": <><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></>,
    "edit-3":       <><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4z"/></>,
    "upload":       <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/></>,
    "file-text":    <><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" x2="8" y1="13" y2="13"/><line x1="16" x2="8" y1="17" y2="17"/></>,
    "info":          <><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></>,
    "trash-2":       <><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></>,
    "image":        <><rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><circle cx="9" cy="9" r="2"/><path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21"/></>,
    "images":       <><path d="M18 22H4a2 2 0 0 1-2-2V6"/><path d="m22 14-3.086-3.086a2 2 0 0 0-2.828 0L10 17"/><circle cx="12" cy="8" r="2"/><rect width="16" height="16" x="6" y="2" rx="2"/></>,
    "shield":       <><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/></>,
    "flame":        <><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z"/></>,
    "award":        <><circle cx="12" cy="8" r="6"/><path d="M15.477 12.89 17 22l-5-3-5 3 1.523-9.11"/></>,
    "external-link": <><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" x2="21" y1="14" y2="3"/></>,
    "pin":          <><path d="M12 17v5"/><path d="M9 10.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24V16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V7a1 1 0 0 1 1-1 2 2 0 0 0 0-4H8a2 2 0 0 0 0 4 1 1 0 0 1 1 1z"/></>,
    "send":         <><path d="m22 2-7 20-4-9-9-4z"/><path d="M22 2 11 13"/></>,
    "download":     <><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></>,
    "refresh-cw":   <><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M3 21v-5h5"/></>,
    "gift":         <><polyline points="20 12 20 22 4 22 4 12"/><rect width="20" height="5" x="2" y="7"/><line x1="12" x2="12" y1="22" y2="7"/><path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"/><path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"/></>,
    "circle":       <><circle cx="12" cy="12" r="10"/></>,
    "package":      <><path d="m7.5 4.27 9 5.15"/><path d="M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z"/><path d="M3.3 7 12 12l8.7-5"/><path d="M12 22V12"/></>,
    "knife":        <><path d="m2.5 21.5 1-1"/><path d="M15.5 8.5 7 17l-3 3"/><path d="M21 3l-7.5 7.5L9 6l8.5-4z"/></>,
    "sparkles":     <><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1"/></>,
    "dot":          <><circle cx="12" cy="12" r="1"/></>,
  };
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round" style={style} className={className}>
      {paths[name] || null}
    </svg>
  );
}

// ─────────────────────────────────────────────────────────
// Locale switcher in header
// ─────────────────────────────────────────────────────────
function LocaleChip({ locale, onChange }) {
  const [open, setOpen] = useState(false);
  const ref = useRef(null);
  useEffect(() => {
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    return () => document.removeEventListener("mousedown", onDoc);
  }, []);
  const t = window.I18N[locale];
  return (
    <div className="locale-chip" ref={ref}>
      <button className="chip-btn" onClick={() => setOpen(!open)}>
        <span className="flag">{t.flag}</span>
        <span className="loc-label">{t.locale.replace(/\s*\(.*\)$/, "")}</span>
        <Icon name="chevron-down" size={14} />
      </button>
      {open && (
        <div className="chip-menu">
          {["en", "de", "id"].map(k => {
            const o = window.I18N[k];
            return (
              <button key={k} className={"chip-opt " + (locale === k ? "on" : "")} onClick={() => { onChange(k); setOpen(false); }}>
                <span className="flag">{o.flag}</span>
                <div className="opt-name">{o.locale.replace(/\s*\(.*\)$/, "")}</div>
                {locale === k && <Icon name="check" size={14} style={{ color: "var(--ufs-orange)", marginLeft: "auto" }} />}
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────
// Sidebar
// ─────────────────────────────────────────────────────────
function Sidebar({ route, onRoute, locale, profile, onOpenNotif, hasUnread , onLogout }) {
  const t = window.I18N[locale].nav;
  const items = [
    { id: "dashboard", icon: "layers", label: t.dashboard },
    { id: "courses",   icon: "book-open", label: t.learning },
    { id: "briefs",    icon: "flame", label: t.briefs },
    { id: "rewards", icon: "award", label: locale === "de" ? "Belohnungen" : locale === "id" ? "Hadiah" : "Rewards" },
    { id: "community", icon: "users", label: t.community },
  ];
  const accountItems = [
    { id: "profile",  icon: "user", label: t.profile },
    { id: "help",     icon: "help-circle", label: t.help },
  ];
  return (
    <aside className="sidebar" data-tour="fr-nav">
      <div className="sb-head">
        <img src="assets/UFS_logo_orange_box.png" alt="UFS" />
        <div className="sb-brand">
          <div className="sb-brand-name">ChefVerse</div>
        </div>
      </div>
      <div className="sb-group">
        <div className="sb-label">{t.platform}</div>
        {items.map(it => (
          <button key={it.id} className={"sb-item " + (route === it.id ? "active" : "")} onClick={() => onRoute(it.id)}>
            <Icon name={it.icon} />
            <span>{it.label}</span>
          </button>
        ))}
      </div>
      <div className="sb-group">
        <div className="sb-label">{t.account}</div>
        {accountItems.map(it => (
          <button key={it.id} className={"sb-item " + (route === it.id ? "active" : "")} onClick={() => onRoute(it.id)}>
            <Icon name={it.icon} />
            <span>{it.label}</span>
          </button>
        ))}
      </div>
      <div className="sb-spacer" />
      <SidebarProfileMenu locale={locale} profile={profile} onRoute={onRoute} onLogout={onLogout} />
    </aside>
  );
}

// ─────────────────────────────────────────────────────────
// Sidebar profile menu — opens upward from the sidebar foot avatar.
// Items: Profile, Settings, Help, Privacy, Terms, Logout
// ─────────────────────────────────────────────────────────
function SidebarProfileMenu({ locale, profile, onRoute, onLogout }) {
  const t = window.I18N[locale].nav;
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => {
      if (ref.current && !ref.current.contains(e.target)) setOpen(false);
    };
    const onEsc = (e) => { if (e.key === "Escape") setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onEsc);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("keydown", onEsc);
    };
  }, [open]);
  const go = (r) => { onRoute(r); setOpen(false); };
  const openLegalTab = (kind) => {
    setOpen(false);
    try {
      const url = new URL(window.location.href);
      url.searchParams.set("p", kind);
      window.open(url.toString(), "_blank", "noopener,noreferrer");
    } catch (e) {}
  };
  const labels = {
    profile: locale === "de" ? "Profil" : locale === "id" ? "Profil" : "Profile",
    help: t.help || "Help",
    privacy: locale === "de" ? "Datenschutz" : locale === "id" ? "Privasi" : "Privacy",
    terms: locale === "de" ? "AGB" : locale === "id" ? "Ketentuan" : "Terms",
    logout: locale === "de" ? "Abmelden" : locale === "id" ? "Keluar" : "Log out",
  };
  return (
    <div className="sb-profile-menu-wrap" ref={ref}>
      <button className={"sb-foot " + (open ? "open" : "")} onClick={() => setOpen(!open)} aria-haspopup="menu" aria-expanded={open}>
        <Avatar name={profile.name} initials={profile.initials} cls="av-mr" />
        <div className="sb-who">
          <div className="sb-name">{profile.name}</div>
          <div className="sb-email display-italic">{window.I18N[locale].onboard[profile.role_key]}</div>
        </div>
        <Icon name="chevrons-up-down" size={14} style={{ color: "var(--smoke)", marginLeft: "auto" }} />
      </button>
      {open && (
        <div className="sb-pm" role="menu">
          <button className="sb-pm-head" onClick={() => go("profile")}>
            <Avatar name={profile.name} initials={profile.initials} cls="av-mr" />
            <div className="sb-pm-who">
              <div className="sb-pm-name">{profile.name}</div>
              <div className="sb-pm-role display-italic">{window.I18N[locale].onboard[profile.role_key]}</div>
            </div>
            <Icon name="chevron-right" size={14} style={{ color: "var(--smoke)" }} />
          </button>
          <div className="sb-pm-divider" />
          <button className="sb-pm-item" onClick={() => go("help")}>
            <Icon name="help-circle" size={16} /><span>{labels.help}</span>
          </button>
          <div className="sb-pm-divider" />
          <button className="sb-pm-item" onClick={() => openLegalTab("privacy")}>
            <Icon name="shield" size={16} /><span>{labels.privacy}</span>
          </button>
          <button className="sb-pm-item" onClick={() => openLegalTab("terms")}>
            <Icon name="file-text" size={16} /><span>{labels.terms}</span>
          </button>
          <div className="sb-pm-divider" />
          <button className="sb-pm-item sb-pm-logout" onClick={() => { setOpen(false); if (onLogout) onLogout(); }}>
            <Icon name="log-out" size={16} /><span>{labels.logout}</span>
          </button>
        </div>
      )}
    </div>
  );
}

// ─────────────────────────────────────────────────────────
// UFSLocaleDropdown — design-system styled dropdown for locale/language pickers.
// Used in mobile profile sheet, legal page, anywhere else a locale picker is needed.
// Same shape as login locale picker but works as a generic embedded form control.
// ─────────────────────────────────────────────────────────
function UFSLocaleDropdown({ value, onChange, options, ariaLabel, fullWidth }) {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const onDoc = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    const onEsc = (e) => { if (e.key === "Escape") setOpen(false); };
    document.addEventListener("mousedown", onDoc);
    document.addEventListener("keydown", onEsc);
    return () => {
      document.removeEventListener("mousedown", onDoc);
      document.removeEventListener("keydown", onEsc);
    };
  }, [open]);
  const cur = options.find(o => o.value === value) || options[0];
  return (
    <div className={"ufs-dd " + (fullWidth ? "ufs-dd-full" : "") + (open ? " open" : "")} ref={ref}>
      <button type="button"
        className="ufs-dd-trigger"
        onClick={() => setOpen(!open)}
        aria-haspopup="listbox"
        aria-expanded={open}
        aria-label={ariaLabel}>
        {cur && cur.flag && <span className="ufs-dd-flag">{cur.flag}</span>}
        <span className="ufs-dd-lab">{cur ? cur.label : ""}</span>
        <Icon name="chevron-down" size={14} style={{ color: "var(--smoke)", flexShrink: 0 }} />
      </button>
      {open && (
        <div className="ufs-dd-menu" role="listbox">
          {options.map(o => (
            <button key={o.value} type="button"
              className={"ufs-dd-item " + (o.value === value ? "on" : "")}
              onClick={() => { onChange(o.value); setOpen(false); }}
              role="option"
              aria-selected={o.value === value}>
              {o.flag && <span className="ufs-dd-flag">{o.flag}</span>}
              <span className="ufs-dd-text">
                <span className="ufs-dd-lab">{o.label}</span>
                {o.sub && <span className="ufs-dd-sub">{o.sub}</span>}
              </span>
              {o.value === value && <Icon name="check" size={14} style={{ marginLeft: "auto", color: "var(--ufs-orange)", flexShrink: 0 }} />}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}
window.UFSLocaleDropdown = UFSLocaleDropdown;

window.SidebarProfileMenu = SidebarProfileMenu;

// ─────────────────────────────────────────────────────────
// Top bar (used inside sidebar layout)
// ─────────────────────────────────────────────────────────
function TopBar({ crumbs, locale, onLocaleChange, onOpenNotif, hasUnread, canGoBack, onBack, profile, onOpenProfileSheet }) {
  // Mobile: [back-arrow-IF-subpage] [page name] ... [profile-avatar] [bell]
  // Desktop: [panel-left] | [crumbs] ... [search] [locale] [bell]
  const pageTitle = crumbs && crumbs.length > 1 ? crumbs[crumbs.length - 1] : (crumbs && crumbs[0]) || "";
  return (
    <div className="topbar">
      {/* DESKTOP — panel toggle + crumbs */}
      <button className="icon-btn ghost tb-desktop"><Icon name="panel-left" size={16} /></button>
      <div className="sep tb-desktop" />
      <div className="crumbs tb-desktop">
        {crumbs.map((c, i) => (
          <React.Fragment key={i}>
            {i > 0 && <span className="crumb-sep">/</span>}
            <span className={"crumb" + (i < crumbs.length - 1 ? " muted" : "")}>{c}</span>
          </React.Fragment>
        ))}
      </div>

      {/* MOBILE LEFT — back arrow (sub-pages) + page title */}
      <div className="tb-mobile-left">
        {canGoBack && (
          <button className="icon-btn ghost mobile-back-btn" onClick={onBack} aria-label="Back">
            <Icon name="chevron-left" size={20} />
          </button>
        )}
        <div className="tb-mobile-title">{pageTitle}</div>
      </div>

      {/* MOBILE CENTER — UFS logo, always visible on mobile/tablet portrait */}
      <div className="tb-mobile-center">
        <img src="assets/UFS_Primary_logo.png" alt="UFS" className="tb-mobile-logo" />
      </div>

      {/* RIGHT */}
      <div className="topbar-right">
        <div className="tb-search tb-desktop">
          <Icon name="search" size={14} />
          <input placeholder="Search…" />
          <kbd>⌘K</kbd>
        </div>
        <span className="tb-desktop"><LocaleChip locale={locale} onChange={onLocaleChange} /></span>
        {profile && (
          <button className="icon-btn ghost mobile-avatar-btn" onClick={onOpenProfileSheet} aria-label="Profile menu">
            <Avatar name={profile.name} initials={profile.initials} cls="av-mr av-sm" />
          </button>
        )}
      </div>
    </div>
  );
}

// Mobile profile sheet — slides up from bottom. Contains language switcher + nav
function MobileProfileSheet({ open, onClose, locale, profile, onRoute, onLocaleChange, onLogout }) {
  const t = window.I18N[locale].nav;
  if (!open) return null;
  const go = (r) => { onRoute(r); onClose(); };
  const openLegalTab = (kind) => {
    onClose();
    try {
      const url = new URL(window.location.href);
      url.searchParams.set("p", kind);
      window.open(url.toString(), "_blank", "noopener,noreferrer");
    } catch (e) {}
  };
  // Just flag + language name (no country, no sub)
  const langs = ["en", "de", "id"].map(k => {
    const o = window.I18N[k];
    return { code: k, flag: o.flag, label: o.locale.replace(/\s*\(.*\)$/, "") };
  });
  return (
    <>
      <div className="mps-backdrop" onClick={onClose} />
      <div className="mps-sheet" role="dialog" aria-label="Profile menu">
        <div className="mps-handle" />
        <button className="mps-profile" onClick={() => go("profile")}>
          <Avatar name={profile.name} initials={profile.initials} cls="av-mr" />
          <div className="mps-who">
            <div className="mps-name">{profile.name}</div>
            <div className="mps-email">{window.I18N[locale].onboard[profile.role_key]}</div>
          </div>
          <Icon name="chevron-right" size={16} />
        </button>

        {/* Language selector — design-system styled dropdown (scalable for 70+) */}
        <div className="mps-section-label">Language</div>
        <div className="mps-lang-dd-wrap">
          <UFSLocaleDropdown
            value={locale}
            onChange={onLocaleChange}
            ariaLabel="Select language"
            fullWidth
            options={langs.map(l => ({ value: l.code, flag: l.flag, label: l.label }))}
          />
        </div>

        <div className="mps-divider" />
        <button className="mps-item" onClick={() => go("help")}>
          <Icon name="help-circle" size={18} /><span>{t.help}</span>
          <Icon name="chevron-right" size={14} style={{ marginLeft: "auto", color: "var(--smoke)" }} />
        </button>
        <div className="mps-divider" />
        <button className="mps-item" onClick={() => openLegalTab("privacy")}>
          <Icon name="shield" size={18} /><span>{locale === "de" ? "Datenschutz" : locale === "id" ? "Privasi" : "Privacy"}</span>
          <Icon name="chevron-right" size={14} style={{ marginLeft: "auto", color: "var(--smoke)" }} />
        </button>
        <button className="mps-item" onClick={() => openLegalTab("terms")}>
          <Icon name="file-text" size={18} /><span>{locale === "de" ? "AGB" : locale === "id" ? "Ketentuan" : "Terms"}</span>
          <Icon name="chevron-right" size={14} style={{ marginLeft: "auto", color: "var(--smoke)" }} />
        </button>
        <div className="mps-divider" />
        <button className="mps-item mps-logout" onClick={() => { onClose(); if (onLogout) onLogout(); }}>
          <Icon name="log-out" size={18} /><span>{locale === "de" ? "Abmelden" : locale === "id" ? "Keluar" : "Log out"}</span>
        </button>
        <div className="mps-legal">© 2026 Unilever Food Solutions</div>
        <button className="mps-close" onClick={onClose}>Close</button>
      </div>
    </>
  );
}
window.MobileProfileSheet = MobileProfileSheet;


// ─────────────────────────────────────────────────────────
// Saved-items store + SaveBtn — toggles Save / Saved label and color
// ─────────────────────────────────────────────────────────
(function () {
  if (window.__SAVED) return;
  const LS_KEY = "chefverse_saved_v1";
  // New-chef demo profile: clear saved state on initial load so demo always starts fresh
  try {
    const isNewChefStartup = typeof window !== "undefined" && window.__CHEFVERSE_PROFILE === "new";
    if (isNewChefStartup) localStorage.removeItem(LS_KEY);
  } catch (e) {}
  const load = () => {
    try { return JSON.parse(localStorage.getItem(LS_KEY) || "{}"); } catch (e) { return {}; }
  };
  const save = (s) => {
    try { localStorage.setItem(LS_KEY, JSON.stringify(s)); } catch (e) {}
  };
  let state = load();
  const listeners = new Set();
  window.__SAVED = {
    is(kind, id) {
      const key = kind + ":" + id;
      return !!state[key];
    },
    toggle(kind, id) {
      const key = kind + ":" + id;
      if (state[key]) delete state[key];
      else state[key] = true;
      save(state);
      listeners.forEach(fn => fn());
    },
    subscribe(fn) {
      listeners.add(fn);
      return () => listeners.delete(fn);
    },
  };
})();

function SaveBtn({ kind, id, label, savedLabel, className, size = 14 }) {
  const { useState, useEffect } = React;
  const [, force] = useState(0);
  useEffect(() => window.__SAVED.subscribe(() => force(n => n + 1)), []);
  const saved = window.__SAVED.is(kind, id);
  const lab = saved ? (savedLabel || "Saved") : (label || "Save");
  const cls = saved
    ? ("btn btn-save-active " + (className || ""))
    : ("btn btn-outline " + (className || ""));
  return (
    <button
      className={cls.trim()}
      onClick={(e) => { e.stopPropagation(); window.__SAVED.toggle(kind, id); }}
      aria-pressed={saved}
    >
      <Icon name={saved ? "bookmark" : "bookmark-plus"} size={size} />
      <span>{lab}</span>
    </button>
  );
}

window.SaveBtn = SaveBtn;

window.Icon = Icon;
window.LocaleChip = LocaleChip;
window.Sidebar = Sidebar;
window.TopBar = TopBar;
