// Sidebar + Topbar shared shell

const NAV_ITEMS = [
  { id: "create", label: "Create Post", icon: "Edit", section: "Create", perm: ["create_posts"] },
  { id: "calendar", label: "Calendar", icon: "Calendar", section: "Create", perm: ["create_posts", "edit_posts", "publish_posts"] },
  { id: "approvals", label: "Approvals", icon: "Check", badge: 7, badgeKind: "warn", section: "Create", perm: ["approve_posts", "comment_approvals"] },
  { id: "published", label: "Published", icon: "Globe", section: "Create", perm: ["view_reports", "create_posts", "publish_posts"] },
  { id: "experiments", label: "A/B Tests", icon: "TrendUp", section: "Create", perm: ["create_posts", "view_reports"] },
  { id: "content", label: "Recycle & RSS", icon: "Refresh", section: "Create", perm: ["create_posts"] },
  { id: "bulk", label: "Bulk Upload", icon: "Upload", section: "Create", perm: ["create_posts"] },
  { id: "inbox", label: "Inbox", icon: "Inbox", badge: 18, section: "Engage", perm: ["reply_inbox", "manage_inbox"] },
  { id: "listening", label: "Listening", icon: "Search", section: "Engage", perm: ["view_reports"] },
  { id: "reviews", label: "Reviews", icon: "Star", section: "Engage", perm: ["reply_inbox", "manage_inbox", "view_reports"] },
  { id: "advocacy", label: "Advocacy & UGC", icon: "Heart", section: "Engage", perm: ["create_posts", "manage_inbox"] },
  { id: "analytics", label: "Analytics", icon: "Bar", section: "Analyze", perm: ["view_reports"] },
  { id: "benchmarking", label: "Benchmarks", icon: "Grid", section: "Analyze", perm: ["view_reports"] },
  { id: "reports", label: "Reports", icon: "File", section: "Analyze", perm: ["view_reports"] },
  { id: "ads", label: "Ads", icon: "TrendUp", section: "Grow", perm: ["publish_posts"] },
  { id: "linkbio", label: "Link in Bio", icon: "Hash", section: "Grow", perm: ["manage_links"] },
  { id: "links", label: "Links", icon: "Link", section: "Grow", perm: ["manage_links"] },
  { id: "media", label: "Media Library", icon: "Image", section: "Grow", perm: ["manage_media"] },
  { id: "team", label: "Team", icon: "Users", section: "Account", perm: ["manage_team"] },
  { id: "integrations", label: "Integrations", icon: "Plug", section: "Account", perm: ["manage_integrations"] },
  { id: "developer", label: "Developer / API", icon: "Lock", section: "Account", perm: ["manage_integrations"] },
  { id: "agency", label: "Agency & White-label", icon: "Bookmark", section: "Account", perm: ["manage_workspace"] },
  { id: "billing", label: "Billing & Plan", icon: "Tag", section: "Account", perm: ["manage_workspace"] },
  { id: "settings", label: "Settings", icon: "Settings", section: "Account", perm: ["manage_workspace"] },
  { id: "admin", label: "Admin Console", icon: "Lock", section: "Account", adminOnly: true },
];

const NAV_SECTION_ORDER = ["Create", "Engage", "Analyze", "Grow", "Account"];

// Show a nav item if it needs no permission, the user's permissions are unknown
// (fail open so the nav is never empty), or the user holds any required permission.
function allowedNavItems(data) {
  const perms = data && data.currentPermissions;
  const isAdmin = Boolean(data && data.isAdmin);
  const base = (!Array.isArray(perms) || !perms.length)
    ? NAV_ITEMS
    : NAV_ITEMS.filter((item) => !item.perm || item.perm.some((p) => perms.includes(p)));
  // The Admin Console is gated strictly on admin status, never on workspace permissions.
  return base.filter((item) => !item.adminOnly || isAdmin);
}

// Group allowed items into ordered sections (desktop sidebar).
function allowedNavSections(data) {
  const items = allowedNavItems(data);
  return NAV_SECTION_ORDER
    .map((label) => ({ label, items: items.filter((i) => i.section === label) }))
    .filter((s) => s.items.length);
}

function navBadge(item, data) {
  if (!data) return item.badge;
  if (item.id === "inbox") return (data.inbox || []).filter((message) => !message.archived && (message.unread || message.assignee === "Emma" || message.assignee === "Emma Watanabe")).length;
  if (item.id === "approvals") return (data.posts || []).filter((post) => ["needs_approval", "changes_requested"].includes(post.status)).length;
  return item.badge;
}

function buildTaskItems(data) {
  if (!data) return [];
  const taskState = Object.fromEntries((data.taskState || []).map((item) => [item.id, item]));
  const notificationSettings = data.workspace?.notificationSettings || {};
  const notificationEnabled = (label) => {
    const setting = notificationSettings[label];
    if (!setting) return true;
    return Boolean(setting.e || setting.p || setting.s);
  };
  const now = Date.now();
  const applyState = (task) => {
    const state = taskState[task.id] || {};
    const muted = task.notificationLabel ? !notificationEnabled(task.notificationLabel) : false;
    return {
      ...task,
      muted,
      dismissed: Boolean(state.dismissed),
      snoozedUntil: state.snoozedUntil || null,
      hidden: muted || Boolean(state.dismissed) || (state.snoozedUntil && Date.parse(state.snoozedUntil) > now)
    };
  };
  const integrations = Object.fromEntries((data.integrations || []).map((item) => [item.id, item]));
  const platformIssues = (post) => (post.platforms || []).flatMap((platform) => {
    const integration = integrations[platform];
    const name = Platforms[platform]?.name || platform;
    const issues = [];
    if (!integration || !integration.connected) issues.push(`${name} is not connected`);
    if (integration?.status === "reauth") issues.push(`${name} needs re-authorization`);
    if (integration?.status === "limited") issues.push(`${name} has limited permissions`);
    if (integration && !(integration.supportedTypes || []).includes(post.contentType || "feed")) issues.push(`${name} does not support ${post.contentType || "feed"} posts`);
    if (integration?.issues?.length) issues.push(...integration.issues.map((issue) => `${name}: ${issue}`));
    return issues;
  });
  const posts = data.posts || [];
  const inbox = data.inbox || [];
  const tasks = [];

  posts.filter((post) => ["failed", "blocked"].includes(post.status)).forEach((post) => tasks.push({
    id: `publish-${post.id}`,
    entityId: post.id,
    actionType: "retry_publish",
    kind: "Publishing",
    notificationLabel: "Post failures",
    tone: "danger",
    icon: "Upload",
    title: post.status === "failed" ? "Publishing failed" : "Publishing blocked",
    detail: post.lastPublishError || post.caption,
    meta: `${post.date} · ${post.time}`,
    page: "approvals"
  }));

  posts.filter((post) => ["needs_approval", "changes_requested"].includes(post.status)).slice(0, 8).forEach((post) => tasks.push({
    id: `approval-${post.id}`,
    entityId: post.id,
    actionType: "approve",
    kind: "Approval",
    notificationLabel: "Approval requests",
    tone: "warn",
    icon: "Check",
    title: post.status === "changes_requested" ? "Changes requested" : "Approval needed",
    detail: post.caption,
    meta: `${(post.platforms || []).length} channels · ${post.date}`,
    page: "approvals"
  }));

  posts.filter((post) => post.status === "scheduled").forEach((post) => {
    const issues = platformIssues(post);
    if (!issues.length) return;
    tasks.push({
      id: `readiness-${post.id}`,
      entityId: post.id,
      actionType: "open_integrations",
      kind: "Queue",
      notificationLabel: "Post failures",
      tone: "warn",
      icon: "Bell",
      title: "Scheduled post needs readiness check",
      detail: issues[0],
      meta: `${post.date} · ${post.time}`,
      page: "calendar"
    });
  });

  inbox.filter((message) => !message.archived && (message.unread || message.assignee === "Emma" || message.assignee === "Emma Watanabe" || message.vip)).slice(0, 8).forEach((message) => tasks.push({
    id: `inbox-${message.id}`,
    entityId: message.id,
    actionType: "mark_inbox_done",
    kind: "Inbox",
    notificationLabel: "Comments & DMs",
    tone: message.vip ? "warn" : "info",
    icon: message.type === "dms" ? "Mail" : "Message",
    title: message.vip ? "VIP conversation" : message.unread ? "Unread conversation" : "Assigned conversation",
    detail: `${message.from}: ${message.draft ? `Draft: ${message.draft}` : message.text}`,
    meta: message.assignee || "Unassigned",
    page: "inbox"
  }));

  return tasks.map(applyState).slice(0, 24);
}

function workspaceInitials(name) {
  return (name || "CC")
    .split(/\s+/)
    .map((word) => word[0])
    .filter(Boolean)
    .join("")
    .slice(0, 2)
    .toUpperCase();
}

function WorkspaceSwitcher({ workspaces, activeWorkspaceId, actions, variant = "sidebar" }) {
  const hub = window.useClearCast ? window.useClearCast() : null;
  const [open, setOpen] = React.useState(false);
  const [adding, setAdding] = React.useState(false);
  const [name, setName] = React.useState("");
  const [busy, setBusy] = React.useState(false);
  const list = workspaces || [];
  const active = list.find((workspace) => workspace.id === activeWorkspaceId) || list[0];

  const close = () => { setOpen(false); setAdding(false); setName(""); };
  const goManage = () => { if (hub && hub.setPage) hub.setPage("businesses"); close(); };

  const switchTo = async (id) => {
    if (id === activeWorkspaceId) { close(); return; }
    setBusy(true);
    try { await actions.switchWorkspace(id); close(); }
    finally { setBusy(false); }
  };

  const add = async () => {
    const trimmed = name.trim();
    if (!trimmed || busy) return;
    setBusy(true);
    try { await actions.createWorkspace({ name: trimmed }); close(); }
    catch (error) { console.error(error); }
    finally { setBusy(false); }
  };

  return (
    <div className={`ws-switcher ws-switcher-${variant}`}>
      <button className="ws-trigger" onClick={() => setOpen(!open)} title="Switch business">
        <span className="ws-avatar">{workspaceInitials(active?.name)}</span>
        <span className="ws-trigger-text">
          <span className="ws-trigger-label">Business</span>
          <span className="ws-trigger-name">{active?.name || "Select business"}</span>
        </span>
        <Icon.ChevronDown width="14" height="14" className="ws-caret" />
      </button>

      {open && (
        <React.Fragment>
          <div className="ws-overlay" onClick={close} />
          <div className="ws-menu">
            <div className="ws-menu-head">Your businesses</div>
            <div className="ws-menu-list">
              {list.map((workspace) => (
                <button
                  key={workspace.id}
                  className={`ws-item ${workspace.id === activeWorkspaceId ? "active" : ""}`}
                  disabled={busy}
                  onClick={() => switchTo(workspace.id)}
                >
                  <span className="ws-avatar sm">{workspaceInitials(workspace.name)}</span>
                  <span className="ws-item-body">
                    <b>{workspace.name}</b>
                    <small>{workspace.connectedChannels || 0} channels · {workspace.postCount || 0} posts</small>
                  </span>
                  {workspace.id === activeWorkspaceId && <Icon.Check width="15" height="15" className="ws-check" />}
                </button>
              ))}
            </div>
            {adding ? (
              <div className="ws-add-form">
                <input
                  autoFocus
                  value={name}
                  onChange={(event) => setName(event.target.value)}
                  onKeyDown={(event) => { if (event.key === "Enter") add(); if (event.key === "Escape") { setAdding(false); setName(""); } }}
                  placeholder="Business name"
                  className="ws-add-input"
                />
                <div className="ws-add-actions">
                  <button className="btn btn-sm" onClick={() => { setAdding(false); setName(""); }}>Cancel</button>
                  <button className="btn btn-sm btn-primary" disabled={busy || !name.trim()} onClick={add}>{busy ? "Adding" : "Add"}</button>
                </div>
              </div>
            ) : (
              <button className="ws-add" onClick={() => setAdding(true)}>
                <Icon.Plus width="15" height="15" /> Add business
              </button>
            )}
            <button className="ws-manage" onClick={goManage}>
              <Icon.Settings width="14" height="14" /> Manage businesses
            </button>
          </div>
        </React.Fragment>
      )}
    </div>
  );
}

function useIsMobile() {
  const query = "(max-width: 760px)";
  const [mobile, setMobile] = React.useState(() => typeof window !== "undefined" && window.matchMedia(query).matches);
  React.useEffect(() => {
    const mq = window.matchMedia(query);
    const onChange = () => setMobile(mq.matches);
    onChange();
    mq.addEventListener("change", onChange);
    return () => mq.removeEventListener("change", onChange);
  }, []);
  return mobile;
}

function Sidebar({ page, setPage, data, workspaces, activeWorkspaceId, actions }) {
  const isMobile = useIsMobile();
  const [moreOpen, setMoreOpen] = React.useState(false);
  const items = allowedNavItems(data);
  const collapse = isMobile && items.length > 5;
  const visibleItems = collapse ? items.slice(0, 4) : items;
  const overflowItems = collapse ? items.slice(4) : [];
  const renderNavButton = (item, onClick) => {
    const Ico = Icon[item.icon];
    const active = page === item.id;
    const badge = navBadge(item, data);
    return (
      <button key={item.id} className={`nav-item ${active ? "active" : ""}`} onClick={onClick || (() => setPage(item.id))}>
        <Ico className="ico" />
        <span>{item.label}</span>
        {badge != null && badge > 0 && <span className={`nav-badge ${item.badgeKind === "warn" ? "warn" : ""}`}>{badge}</span>}
      </button>
    );
  };
  return (
    <aside className="sidebar">
      <div className="brand">
        <div className="brand-mark">
          <svg width="18" height="18" viewBox="0 0 24 24" fill="none">
            <path d="M9 6c0-2 2-3 4-3s4 1 4 3-2 3-4 3-4 1-4 3 2 3 4 3 4 1 4 3-2 3-4 3-4-1-4-3" stroke="#061811" strokeWidth="2.5" strokeLinecap="round"/>
          </svg>
        </div>
        <div className="brand-name">ClearCast</div>
      </div>

      <WorkspaceSwitcher workspaces={workspaces} activeWorkspaceId={activeWorkspaceId} actions={actions} variant="sidebar" />

      <nav className="nav">
        {isMobile
          ? (
            <React.Fragment>
              {visibleItems.map((item) => renderNavButton(item))}
              {overflowItems.length > 0 && (
                <button className={`nav-item nav-more ${overflowItems.some((i) => i.id === page) ? "active" : ""}`} onClick={() => setMoreOpen(true)}>
                  <Icon.Dots className="ico" />
                  <span>More</span>
                </button>
              )}
            </React.Fragment>
          )
          : allowedNavSections(data).map((sec) => (
            <div key={sec.label} className="nav-section">
              <div className="nav-section-label">{sec.label}</div>
              {sec.items.map((item) => renderNavButton(item))}
            </div>
          ))}
      </nav>
      {moreOpen && (
        <React.Fragment>
          <div className="ws-overlay" onClick={() => setMoreOpen(false)} />
          <div className="more-sheet">
            <div className="more-sheet-head">
              <span>More</span>
              <button className="icon-btn" aria-label="Close" onClick={() => setMoreOpen(false)}><Icon.X width="16" height="16" /></button>
            </div>
            <div className="more-sheet-grid">
              {overflowItems.map((item) => renderNavButton(item, () => { setPage(item.id); setMoreOpen(false); }))}
            </div>
          </div>
        </React.Fragment>
      )}

      <div className="sidebar-foot">
        <div className="app-promo" role="button" onClick={() => {
          if (window.__clearcastInstall) { window.__clearcastInstall.prompt(); window.__clearcastInstall = null; }
          else { window.alert("To install ClearCast: on desktop use your browser's Install icon in the address bar; on iPhone tap Share → Add to Home Screen."); }
        }}>
          <div className="app-promo-ico"><Icon.Phone width="16" height="16" /></div>
          <div className="app-promo-text">
            <div className="t1">Install the app</div>
            <div className="t2">Add to your phone or desktop</div>
          </div>
          <Icon.ChevronRight width="14" height="14" style={{ color: "var(--text-3)" }} />
        </div>

        <div className="user-card" role={data?.authUser ? "button" : undefined} title={data?.authUser ? "Sign out" : undefined} onClick={() => { if (data?.authUser && actions?.logout) actions.logout(); }}>
          <div className="avatar sz-36" style={{ background: "linear-gradient(135deg, #f4c2a1, #d99c70)", color: "#3a1f0c" }}>{workspaceInitials(data?.workspace?.user?.name)}</div>
          <div className="who">
            <div className="name">{(data?.workspace?.user?.name || "User").split(" ")[0]}</div>
            <div className="role">{data?.authUser ? "Sign out" : (data?.workspace?.user?.role || "Member")}</div>
          </div>
          <Icon.ChevronDown width="14" height="14" style={{ color: "var(--text-3)" }} />
        </div>
      </div>
    </aside>
  );
}

function TaskCenter({ data, actions, setPage, onClose }) {
  const [filter, setFilter] = React.useState("active");
  const allTasks = buildTaskItems(data);
  const visibleTasks = allTasks.filter((task) => {
    if (filter === "active") return !task.hidden;
    if (filter === "urgent") return !task.hidden && task.tone === "danger";
    if (filter === "approvals") return !task.hidden && task.kind === "Approval";
    if (filter === "inbox") return !task.hidden && task.kind === "Inbox";
    if (filter === "queue") return !task.hidden && ["Queue", "Publishing"].includes(task.kind);
    if (filter === "snoozed") return task.snoozedUntil && !task.dismissed;
    if (filter === "dismissed") return task.dismissed;
    if (filter === "muted") return task.muted && !task.dismissed;
    return !task.hidden;
  });
  const tasks = visibleTasks;
  const [busyTaskId, setBusyTaskId] = React.useState("");
  const runTaskAction = async (event, task) => {
    event.stopPropagation();
    if (!task.actionType || !actions) return;
    setBusyTaskId(task.id);
    try {
      if (task.actionType === "approve") {
        await actions.approvalAction(task.entityId, "approve", "Approved from Task Center");
      } else if (task.actionType === "retry_publish") {
        await actions.publishPost(task.entityId, true);
      } else if (task.actionType === "mark_inbox_done") {
        await actions.updateInbox(task.entityId, { unread: false, status: "done", archived: true }, "Inbox task marked done");
      } else if (task.actionType === "open_integrations") {
        setPage("integrations");
        onClose();
      }
    } catch (error) {
      console.error(error);
    } finally {
      setBusyTaskId("");
    }
  };
  const actionLabel = (task) => ({
    approve: "Approve",
    retry_publish: "Retry",
    mark_inbox_done: "Done",
    open_integrations: "Fix"
  }[task.actionType] || "Open");
  const snoozeTask = async (event, task) => {
    event.stopPropagation();
    const until = new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString();
    setBusyTaskId(task.id);
    try {
      await actions.updateTask(task.id, { snoozedUntil: until, dismissed: false });
    } finally {
      setBusyTaskId("");
    }
  };
  const dismissTask = async (event, task) => {
    event.stopPropagation();
    setBusyTaskId(task.id);
    try {
      await actions.updateTask(task.id, { dismissed: true });
    } finally {
      setBusyTaskId("");
    }
  };
  const restoreTask = async (event, task) => {
    event.stopPropagation();
    setBusyTaskId(task.id);
    try {
      await actions.restoreTask(task.id);
    } finally {
      setBusyTaskId("");
    }
  };
  const counts = {
    active: allTasks.filter((item) => !item.hidden).length,
    urgent: allTasks.filter((item) => !item.hidden && item.tone === "danger").length,
    approvals: allTasks.filter((item) => !item.hidden && item.kind === "Approval").length,
    inbox: allTasks.filter((item) => !item.hidden && item.kind === "Inbox").length,
    queue: allTasks.filter((item) => !item.hidden && (item.kind === "Queue" || item.kind === "Publishing")).length,
    snoozed: allTasks.filter((item) => item.snoozedUntil && !item.dismissed).length,
    dismissed: allTasks.filter((item) => item.dismissed).length,
    muted: allTasks.filter((item) => item.muted && !item.dismissed).length
  };
  const toneColor = (tone) => tone === "danger" ? "var(--danger)" : tone === "warn" ? "var(--warn)" : "var(--accent)";
  return (
    <div style={{ position: "absolute", top: 54, right: 84, width: 420, maxHeight: "calc(100vh - 90px)", overflow: "auto", border: "1px solid var(--border)", borderRadius: 14, background: "var(--card)", boxShadow: "var(--shadow)", zIndex: 30 }}>
      <div style={{ padding: 16, borderBottom: "1px solid var(--border)", display: "flex", justifyContent: "space-between", gap: 12 }}>
        <div>
          <div style={{ fontSize: 15, fontWeight: 700 }}>Task Center</div>
          <div className="muted" style={{ fontSize: 12, marginTop: 3 }}>{counts.active} active item{counts.active === 1 ? "" : "s"} across content ops</div>
        </div>
        <button className="icon-btn" aria-label="Close task center" onClick={onClose}><Icon.X width="16" height="16" /></button>
      </div>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 8, padding: 12, borderBottom: "1px solid var(--border)" }}>
        {[
          ["Urgent", counts.urgent, "danger"],
          ["Approvals", counts.approvals, "warn"],
          ["Inbox", counts.inbox, "info"],
          ["Queue", counts.queue, "info"]
        ].map(([label, count, tone]) => (
          <div key={label} style={{ padding: 10, borderRadius: 10, background: "var(--bg-2)", border: "1px solid var(--border)" }}>
            <div className="muted" style={{ fontSize: 10.5 }}>{label}</div>
            <div style={{ marginTop: 3, fontSize: 18, fontWeight: 750, color: toneColor(tone) }}>{count}</div>
          </div>
        ))}
      </div>
      <div style={{ display: "flex", gap: 6, padding: "10px 12px", borderBottom: "1px solid var(--border)", overflowX: "auto" }}>
        {[
          ["active", "Active", counts.active],
          ["urgent", "Urgent", counts.urgent],
          ["approvals", "Approvals", counts.approvals],
          ["inbox", "Inbox", counts.inbox],
          ["queue", "Queue", counts.queue],
          ["snoozed", "Snoozed", counts.snoozed],
          ["muted", "Muted", counts.muted],
          ["dismissed", "Dismissed", counts.dismissed]
        ].map(([id, label, count]) => (
          <button key={id} className={`btn btn-sm ${filter === id ? "btn-primary" : ""}`} onClick={() => setFilter(id)}>{label} {count > 0 ? count : ""}</button>
        ))}
      </div>
      <div style={{ padding: 10, display: "grid", gap: 8 }}>
        {tasks.map((task) => {
          const Ico = Icon[task.icon] || Icon.Bell;
          return (
            <div key={task.id} role="button" tabIndex="0" onClick={() => { setPage(task.page); onClose(); }} style={{ textAlign: "left", padding: 12, borderRadius: 12, border: "1px solid var(--border)", background: "var(--bg-2)", display: "grid", gridTemplateColumns: "32px 1fr auto", gap: 10, alignItems: "center", cursor: "pointer" }}>
              <div style={{ width: 32, height: 32, borderRadius: 10, display: "grid", placeItems: "center", color: toneColor(task.tone), background: "var(--card)" }}><Ico width="16" height="16" /></div>
              <div style={{ minWidth: 0 }}>
                <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 3 }}>
                  <span className={`pill ${task.tone === "danger" ? "danger" : task.tone === "warn" ? "warn" : "info"}`} style={{ padding: "2px 7px", fontSize: 10 }}>{task.kind}</span>
                  {task.muted && <span className="pill" style={{ padding: "2px 7px", fontSize: 10 }}>Muted</span>}
                  <b style={{ fontSize: 12.5 }}>{task.title}</b>
                </div>
                <div className="muted" style={{ fontSize: 12, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>{task.detail}</div>
                <div className="faint" style={{ fontSize: 11, marginTop: 3 }}>{task.meta}</div>
              </div>
              <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                <button className="btn btn-sm" onClick={(event) => { event.stopPropagation(); setPage(task.page); onClose(); }}>Open</button>
                {task.actionType && !task.dismissed && (
                  <button
                    className={`btn btn-sm ${task.tone === "danger" || task.actionType === "approve" ? "btn-primary" : ""}`}
                    disabled={busyTaskId === task.id}
                    onClick={(event) => runTaskAction(event, task)}
                    style={{ opacity: busyTaskId === task.id ? 0.65 : 1 }}
                  >
                    {busyTaskId === task.id ? "Working" : actionLabel(task)}
                  </button>
                )}
                {task.muted ? (
                  <button className="btn btn-sm" onClick={(event) => { event.stopPropagation(); setPage("settings"); onClose(); }}>Unmute</button>
                ) : task.hidden ? (
                  <button className="btn btn-sm" disabled={busyTaskId === task.id} onClick={(event) => restoreTask(event, task)}>{busyTaskId === task.id ? "Working" : "Restore"}</button>
                ) : (
                  <>
                    <button className="btn btn-sm" disabled={busyTaskId === task.id} onClick={(event) => snoozeTask(event, task)}>Snooze</button>
                    <button className="btn btn-sm" disabled={busyTaskId === task.id} onClick={(event) => dismissTask(event, task)}>Dismiss</button>
                  </>
                )}
              </div>
            </div>
          );
        })}
        {!tasks.length && <div className="empty-note">No tasks match this filter.</div>}
      </div>
    </div>
  );
}

function applyClearCastTheme(t) {
  document.documentElement.setAttribute("data-theme", t);
  try { localStorage.setItem("clearcast-theme", t); } catch (e) { /* ignore */ }
  const meta = document.querySelector('meta[name="theme-color"]');
  if (meta) meta.setAttribute("content", t === "light" ? "#f6f8f7" : "#0a0f0d");
}

function ThemeToggle() {
  const [theme, setTheme] = React.useState(() => document.documentElement.getAttribute("data-theme") || "dark");
  const toggle = () => { const next = theme === "light" ? "dark" : "light"; setTheme(next); applyClearCastTheme(next); };
  return (
    <button className="tb-chip tb-theme" onClick={toggle} aria-label="Toggle light or dark mode" title={theme === "light" ? "Switch to dark mode" : "Switch to light mode"}>
      {theme === "light"
        ? <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
        : <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><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"/></svg>}
    </button>
  );
}

function Topbar({ title, page, data, actions, setPage, workspaces, activeWorkspaceId }) {
  const [open, setOpen] = React.useState(false);
  const tasks = buildTaskItems(data).filter((task) => !task.hidden);
  // Each page can have its own right-side chips. We keep a sensible default.
  return (
    <div className="topbar">
      <div className="tb-left">
        <div className="tb-switcher-mobile">
          <WorkspaceSwitcher workspaces={workspaces} activeWorkspaceId={activeWorkspaceId} actions={actions} variant="topbar" />
        </div>
        <div className="tb-title">{title}</div>
      </div>
      <div className="tb-right">
        <button className="tb-chip" title="Set your workspace timezone in Settings" onClick={() => setPage("settings")}>
          <Icon.Globe className="ico" />
          <span>{data?.workspace?.timezone || "America/New_York"}</span>
          <Icon.ChevronDown className="ico" />
        </button>
        <button className="tb-chip" title="Best times to post live in the composer's schedule picker" onClick={() => setPage("create")}>
          <Icon.Clock className="ico" />
          <span>Best Time</span>
        </button>
        <ThemeToggle />
        <button className="tb-bell" onClick={() => setOpen(!open)} title="Open task center">
          <Icon.Bell width="18" height="18" />
          {tasks.length > 0 && <span className="dot">{Math.min(99, tasks.length)}</span>}
        </button>
        <button className="user-card" title={data?.authUser ? "Sign out" : "Account"} onClick={() => { if (data?.authUser && actions?.logout) actions.logout(); else setPage("settings"); }} style={{ padding: "4px 8px 4px 4px", border: "1px solid var(--border)", borderRadius: 10, background: "var(--card)" }}>
          <div className="avatar sz-32" style={{ background: "linear-gradient(135deg, #f4c2a1, #d99c70)", color: "#3a1f0c" }}>{workspaceInitials(data?.workspace?.user?.name)}</div>
          <div className="who" style={{ paddingRight: 4 }}>
            <div className="name">{(data?.workspace?.user?.name || "User").split(" ")[0]}</div>
            <div className="role">{data?.workspace?.user?.role || "Member"}</div>
          </div>
          <Icon.ChevronDown width="14" height="14" style={{ color: "var(--text-3)" }} />
        </button>
      </div>
      {open && <TaskCenter data={data} actions={actions} setPage={setPage} onClose={() => setOpen(false)} />}
    </div>
  );
}

window.Sidebar = Sidebar;
window.Topbar = Topbar;
window.ThemeToggle = ThemeToggle;
window.buildTaskItems = buildTaskItems;
window.NAV_ITEMS = NAV_ITEMS;
