// TopBar.jsx — workspace controls, notifications, language and role switcher
(function () {
  const { useState, useEffect } = React;
  const h = React.createElement;

  // deployment environments (Selector + Settings) — was window.DATA.environments;
  // declared once here, referenced by the Topbar Selector and the Settings screen.
  const ENVIRONMENTS = ["Demo", "Pilot", "Production"];

  const { LEVELS, LEVEL_LABEL, LEVEL_DESC } = window.EmplixPermissions;

  function Selector({ icon, label, value, options, onChange, disabled, disabledReason, onDenied, action }) {
    const [open, setOpen] = useState(false);
    function clickButton() {
      if (disabled) {
        if (onDenied) onDenied();
        setOpen(false);
        return;
      }
      setOpen(!open);
    }
    return h("div", { style: { position: "relative" } },
      h("button", { className: "btn", onClick: clickButton, title: disabled ? disabledReason : undefined,
        "data-topbar-action": action || undefined,
        "data-selector-current": value,
        "data-selector-open": !disabled && open ? "true" : "false",
        "data-selector-disabled": disabled ? "true" : "false",
        "aria-haspopup": action ? "menu" : undefined,
        "aria-expanded": action ? (!disabled && open ? "true" : "false") : undefined,
        "aria-disabled": disabled ? "true" : undefined,
        style: { background: "var(--bg-2)", opacity: disabled ? 0.62 : 1 } },
        icon && h(window.Icon, { name: icon, size: 14, color: "var(--text-faint)" }),
        h("div", { style: { textAlign: "left", lineHeight: 1.1 } },
          label && h("div", { style: { fontSize: 9.5, color: "var(--text-faint)", fontWeight: 600, letterSpacing: ".04em" } }, label),
          h("div", { style: { fontSize: 13 } }, value)),
        h(window.Icon, { name: disabled ? "lock" : "chevDown", size: 13, color: "var(--text-faint)" })),
      !disabled && open && h(React.Fragment, null,
        h("div", { onClick: () => setOpen(false), style: { position: "fixed", inset: 0, zIndex: 40 } }),
        h("div", { className: "glass", role: action ? "menu" : undefined, "data-selector-panel": action || undefined, style: { position: "absolute", top: "calc(100% + 6px)", left: 0, minWidth: "100%", zIndex: 50, padding: 5, boxShadow: "var(--shadow-lg)" } },
          options.map((o) => h("button", { key: o, onClick: () => { onChange(o); setOpen(false); },
            className: "dd-opt" + (o === value ? " active" : ""),
            role: action ? "menuitemradio" : undefined,
            "aria-checked": action ? (o === value ? "true" : "false") : undefined,
            "data-selector-for": action || undefined,
            "data-selector-option": o,
            "data-selector-active": o === value ? "true" : "false",
            style: { display: "flex", alignItems: "center", gap: 8, width: "100%", textAlign: "left", padding: "8px 10px", borderRadius: 7, border: "none", cursor: "pointer",
              background: o === value ? "var(--blue-soft)" : "transparent", color: o === value ? "var(--blue-deep)" : "var(--text)", fontFamily: "var(--font)", fontSize: 13, fontWeight: o === value ? 600 : 500, whiteSpace: "nowrap" } },
            o === value && h(window.Icon, { name: "check", size: 13, color: "var(--blue)" }),
            h("span", { style: { marginLeft: o === value ? 0 : 21 } }, o))))));
  }

  function LangToggle() {
    const [l, setL] = useState(window.I18N ? window.I18N.getLang() : "en");
    useEffect(() => { if (window.I18N) return window.I18N.onChange(setL); }, []);
    if (!window.I18N) return null;
    return h("select", { className: "field", value: l, "aria-label": "Language", "data-topbar-action": "language", "data-language-current": l, onChange: (e) => window.I18N.setLang(e.target.value),
      style: { width: 176, padding: "8px 30px 8px 10px", fontWeight: 700, fontSize: 13, cursor: "pointer" } },
      h("option", { value: "en" }, "English"),
      h("option", { value: "zh-Hant-HK" }, "繁體中文（香港）"),
      h("option", { value: "zh-Hans" }, "简体中文"));
  }

  // Acting-as identity + 4-level human role switcher merged into ONE control (C2/C5).
  // The button itself shows the current acting level (tone-coloured) and opens the picker —
  // replaces the old separate ActingBadge + plain switcher that displayed the level twice.
  function RoleSwitcher({ role, setRole }) {
    const [open, setOpen] = useState(false);
    const tone = role === "viewer" ? "neutral" : role === "operator" ? "amber" : role === "manager" ? "blue" : "green";
    const c = { neutral: "var(--text-faint)", amber: "var(--amber)", blue: "var(--blue)", green: "var(--green)" }[tone];
    const bg = { neutral: "var(--bg-3)", amber: "var(--amber-soft)", blue: "var(--blue-soft)", green: "var(--green-soft)" }[tone];
    return h("div", { style: { position: "relative" } },
      h("button", { className: "btn", onClick: () => setOpen(!open), title: "Switch role. Current: " + LEVEL_LABEL[role] + ".",
        "data-topbar-action": "role-switch",
        "data-role-switch-current": role,
        "aria-haspopup": "menu",
        "aria-expanded": open ? "true" : "false",
        style: { background: bg, border: "1px solid var(--border)", gap: 8, padding: "5px 10px" } },
        h(window.Icon, { name: role === "viewer" ? "eye" : "shield", size: 14, color: c }),
        h("div", { style: { lineHeight: 1.05, textAlign: "left" } },
          h("div", { style: { fontSize: 9, fontWeight: 700, letterSpacing: ".06em", color: "var(--text-faint)" } }, "ACTING AS"),
          h("div", { style: { fontSize: 12, fontWeight: 700, color: c } }, LEVEL_LABEL[role])),
        h(window.Icon, { name: "chevDown", size: 13, color: "var(--text-faint)" })),
      open && h(React.Fragment, null,
        h("div", { onClick: () => setOpen(false), style: { position: "fixed", inset: 0, zIndex: 40 } }),
        h("div", { className: "glass", role: "menu", "data-role-switch-panel": "true", style: { position: "absolute", top: "calc(100% + 6px)", right: 0, width: 280, maxWidth: "calc(100vw - 24px)", zIndex: 50, padding: 6, boxShadow: "var(--shadow-lg)" } },
          LEVELS.map((lv) => h("button", { key: lv.id, onClick: () => { setRole(lv.id); setOpen(false); },
            className: "dd-opt" + (lv.id === role ? " active" : ""),
            role: "menuitemradio",
            "aria-checked": lv.id === role ? "true" : "false",
            "data-role-switch-option": lv.id,
            "data-role-switch-active": lv.id === role ? "true" : "false",
            style: { display: "flex", alignItems: "flex-start", gap: 9, width: "100%", textAlign: "left", padding: "9px 10px", borderRadius: 8, border: "none", cursor: "pointer",
              background: lv.id === role ? "var(--blue-soft)" : "transparent", fontFamily: "var(--font)", marginBottom: 2 } },
            h(window.Icon, { name: lv.id === role ? "checkCircle" : "user", size: 15, color: lv.id === role ? "var(--blue)" : "var(--text-faint)", style: { marginTop: 1, flex: "none" } }),
            h("div", { style: { minWidth: 0 } },
              h("div", { style: { fontSize: 13, fontWeight: 600, color: lv.id === role ? "var(--blue-deep)" : "var(--text)" } }, lv.label),
              h("div", { style: { fontSize: 11, color: "var(--text-faint)", lineHeight: 1.4, marginTop: 2 } }, LEVEL_DESC[lv.id]))))))); }

  function notificationState(office) {
    const n = (office && office.notifications) || {};
    return {
      read: n.read || {},
      dismissed: n.dismissed || {},
    };
  }
  function notificationRiskTone(risk) {
    return risk === "高" || risk === "High" ? "red" : risk === "中" || risk === "Medium" ? "amber" : "green";
  }
	function notificationTaskStage(stage) {
	  return ({ Intake: "New", Planning: "Plan", Running: "In progress", QA: "Check", Done: "Done" })[stage] || stage;
	}
	function notificationRoleName(office, roleId) {
	  const r = office && office.roleById && office.roleById[roleId];
	  return (window.officeRoleName && r) ? window.officeRoleName(r, roleId) : ((r && (r.short || r.title)) || roleId || "Employee");
	}
	function notificationTime(value, fallback) {
	  const raw = value || fallback || "";
	  return window.officeTimeDisplay ? window.officeTimeDisplay(raw) : raw;
	}
	function notificationSource(value) {
	  return window.officeSourceDisplay ? window.officeSourceDisplay(value) : value;
	}
  function notificationHkMoney(value) {
    const n = Number(value) || 0;
    return (n < 0 ? "-HK$" : "HK$") + Math.abs(Math.round(n)).toLocaleString();
  }
  function buildWeeklyRoiDigestNotification(office) {
    const k = (office && office.kpi) || {};
    const D = window.deriveDashboardData ? window.deriveDashboardData(office) : {};
    const R = (D && D.roi) || {};
    const monthlySaved = Number(R.monthlySaved != null ? R.monthlySaved : k.costSaved);
    const tasksDone = Number(k.tasksDone || 0);
    if (!(monthlySaved > 0) || !(tasksDone > 0)) return null;
    const weekly = Array.isArray(k.weeklyTasks) ? k.weeklyTasks : [];
    const latestWeekTasks = Number(weekly.length ? weekly[weekly.length - 1] : tasksDone);
    const netValue = Number(R.netRoi || 0);
    const roiMultiple = Number(R.roiMultiple || 0);
    const subParts = [
      notificationHkMoney(monthlySaved) + " saved",
      roiMultiple > 0 ? (Math.round(roiMultiple * 10) / 10) + "x value" : null,
      netValue ? notificationHkMoney(netValue) + " net" : null,
      latestWeekTasks > 0 ? latestWeekTasks.toLocaleString() + " tasks" : null,
    ].filter(Boolean);
    return {
      id: "roi-digest:" + (k.month || "current-month") + ":" + (weekly.length || "total"),
      icon: "dollar",
      tone: netValue >= 0 ? "green" : "amber",
      title: "Weekly value email ready",
      sub: subParts.join(" · "),
      subParts,
      time: "This week",
      page: "roi",
    };
  }
  function notificationWorkOrderForApproval(office, approvalId) {
    const run = ((office && office.runs) || []).find((r) => r.inboxId === approvalId || r.originalInboxId === approvalId);
    if (run && run.workOrderId) return run.workOrderId;
    const board = (office && office.workOrders) || {};
    let hit = null;
    Object.keys(board).forEach((col) => {
      if (hit) return;
      (board[col] || []).forEach((wo) => {
        const wf = wo.workflow || {};
        if (!hit && (wf.approvalId === approvalId || wf.originalApprovalId === approvalId)) hit = wo.id;
      });
    });
    return hit;
  }
  function openNotification(ctx, n) {
    if (!ctx || !n) return;
    if (ctx.markNotificationRead && (!ctx.can || ctx.can("manageNotifications"))) ctx.markNotificationRead(n.id);
    if (n.highlight && ctx.setHighlight) ctx.setHighlight(n.highlight);
    if (n.page && ctx.openPage) ctx.openPage(n.page, n.arg || null);
  }
  function buildTopbarNotifications(ctx) {
    const office = (ctx && ctx.office) || {};
    const settings = (ctx && ctx.settings) || {};
    const state = notificationState(office);
    const hidden = state.dismissed;
    const seen = state.read;
    const out = [];
    const push = (item) => {
      if (!item || hidden[item.id]) return;
      out.push(Object.assign({ unread: !seen[item.id] }, item));
    };
    if (settings.notifyApprovalRequests !== false) {
      (office.inbox || []).slice(0, 5).forEach((item) => {
        const woId = notificationWorkOrderForApproval(office, item.id);
        push({
          id: "approval:" + item.id,
          icon: "inbox",
          tone: notificationRiskTone(item.risk),
          title: item.title || "Approval waiting",
          sub: item.id + " · " + notificationRoleName(office, item.role) + (woId ? " · " + woId : ""),
	          time: notificationTime(item.time, "Waiting"),
          page: "approvals",
          highlight: item.id,
        });
      });
    }
    if (settings.teamChatAlerts !== false) {
      (((office.ops || {}).incidents) || []).filter((inc) => inc.status !== "resolved").slice(0, 4).forEach((inc) => {
        push({
          id: "incident:" + inc.id,
          icon: "alert",
          tone: inc.severity === "high" ? "red" : "amber",
          title: inc.title || "Issue needs attention",
	          sub: inc.id + " · " + notificationSource(inc.source || "App status"),
	          time: notificationTime(inc.opened, "Open"),
          page: "incident",
          arg: inc.id,
        });
      });
    }
    if (settings.weeklyRoiDigest !== false) push(buildWeeklyRoiDigestNotification(office));
    const board = office.workOrders || {};
    ["Intake", "Planning", "Running"].forEach((col) => {
      (board[col] || []).filter((wo) => wo.workflow && wo.workflow.runId).slice(0, 2).forEach((wo) => {
        push({
          id: "workorder:" + wo.id + ":" + wo.workflow.runId,
          icon: "activity",
          tone: "blue",
          title: wo.title || "Task in progress",
          sub: wo.id + " · " + notificationTaskStage(col),
          time: wo.sla || "Active",
          page: "workorder",
          arg: wo.id,
        });
      });
    });
    if (settings.notifyApprovalRequests !== false) {
      const pendingAuto = (office.autoExec || []).filter((ax) => ax.status === "pending").slice(0, 2);
      pendingAuto.forEach((ax) => {
        push({
          id: "auto:" + ax.id,
          icon: "zap",
          tone: "amber",
          title: ax.title || "Repeat work waiting",
          sub: "You can still undo",
	          time: notificationTime(ax.time, "Pending"),
          page: "approvals",
        });
      });
    }
    (office.integrationRequests || []).slice(0, 2).forEach((req) => {
      push({
        id: "integration:" + req.id,
        icon: "mail",
        tone: "green",
        title: req.name + " request received",
        sub: "App request · " + (req.status || "requested"),
	        time: notificationTime(req.time, "Requested"),
        page: "connectors",
      });
    });
    return out.slice(0, 9);
  }

  function Topbar({ role, setRole, env, setEnv, client, setClient, setActive, ctx, onSearch, onNewWO, onBurger, onOpenGuide }) {
    const [bell, setBell] = useState(false);
    const notifications = buildTopbarNotifications(ctx);
    const unread = notifications.filter((n) => n.unread);
    const canManageWorkspace = ctx && ctx.can && ctx.can("manageCompanyUsers");
    const manageWorkspaceReason = ctx && ctx.denyReason ? ctx.denyReason("manageCompanyUsers") : "";
    const canManageNotifications = !(ctx && ctx.can) || ctx.can("manageNotifications");
    const notificationDenyReason = ctx && ctx.denyReason ? ctx.denyReason("manageNotifications") : "Viewers have read-only access";
    const canWorkOrder = !(ctx && ctx.can) || ctx.can("workOrder");
    const workOrderReason = ctx && ctx.denyReason ? ctx.denyReason("workOrder") : "Viewers have read-only access";
    const denyWorkspaceChange = () => { if (ctx && ctx.showToast) ctx.showToast(manageWorkspaceReason); };
    const denyWorkOrder = () => { if (ctx && ctx.showToast) ctx.showToast(workOrderReason); };
    const bellPanelId = "topbar-notifications-panel";
    useEffect(() => {
      if (!bell) return;
      const closeOnEscape = (e) => { if (e.key === "Escape") setBell(false); };
      document.addEventListener("keydown", closeOnEscape);
      return () => document.removeEventListener("keydown", closeOnEscape);
    }, [bell]);
    function renderNotification(n) {
      const subParts = n.subParts || [n.sub];
      return h("div", { key: n.id, className: "notif-row" + (n.unread ? " unread" : ""),
        "data-notification-id": n.id,
        "data-notification-unread": n.unread ? "true" : "false",
        "data-notification-page": n.page || "",
        "data-notification-arg": n.arg || "",
        "data-notification-highlight": n.highlight || "",
        "data-notification-tone": n.tone || "",
        "data-notification-title": n.title || "" },
        h("button", { type: "button", className: "notif-main", "data-notification-action": "open", "data-notification-id": n.id, "data-notification-page": n.page || "", "data-notification-arg": n.arg || "", "data-notification-highlight": n.highlight || "", "data-notification-rbac-disabled": canManageNotifications ? "false" : "true", onClick: () => { openNotification(ctx, n); setBell(false); } },
          h("div", { style: { width: 28, height: 28, borderRadius: 8, background: `var(--${n.tone}-soft)`, color: `var(--${n.tone})`, display: "grid", placeItems: "center", flex: "none" } }, h(window.Icon, { name: n.icon, size: 14 })),
          h("div", { className: "grow", style: { minWidth: 0 } },
            h("div", { className: "row gap6", style: { alignItems: "flex-start" } },
              n.unread && h("span", { className: "notif-dot" }),
              h("div", { className: "notif-title grow" }, n.title)),
            h("div", { className: "notif-sub" },
              subParts.map((part, i) => h(React.Fragment, { key: i }, i > 0 && h("span", null, " · "), h("span", null, part))),
              h("span", null, " · "), h("span", null, n.time))),
          h(window.Icon, { name: "chevRight", size: 14, color: "var(--text-faint)", style: { marginTop: 7, flex: "none" } })),
        h("button", { type: "button", className: "notif-dismiss", "data-notification-action": "dismiss", "data-notification-id": n.id, "data-notification-rbac-disabled": canManageNotifications ? "false" : "true", disabled: !canManageNotifications, title: canManageNotifications ? "Dismiss notification" : notificationDenyReason, "aria-label": "Dismiss " + n.title, onClick: (e) => { e.stopPropagation(); if (canManageNotifications && ctx && ctx.dismissNotification) ctx.dismissNotification(n.id); } },
          h(window.Icon, { name: "x", size: 13 })));
    }
    return h("header", { className: "app-topbar", style: { height: "var(--topbar-h)", position: "sticky", top: 0, zIndex: 18, display: "flex", alignItems: "center", gap: 12, padding: "0 22px",
      background: "rgba(255,255,255,0.78)", backdropFilter: "blur(14px)", borderBottom: "1px solid var(--border)" } },
      // mobile-only: hamburger + compact brand (sidebar is off-canvas at this width)
      h("button", { className: "btn btn-ghost tb-burger", style: { padding: 9 }, onClick: onBurger, title: "Menu", "aria-label": "Open navigation", "data-nav-action": "open" }, h(window.Icon, { name: "menu", size: 19 })),
      h("div", { className: "tb-brand row gap8" },
        h("div", { style: { width: 28, height: 28, borderRadius: 8, background: "linear-gradient(135deg,#5aa2ff,#6438e8)", display: "grid", placeItems: "center", color: "#fff", flex: "none" } }, h(window.Icon, { name: "layers", size: 15 })),
        h("div", { style: { fontWeight: 700, fontSize: 15, letterSpacing: "-0.02em" } }, "Emplix")),
      h("div", { className: "tb-client" },
        h(Selector, { icon: "pin", label: "WORKSPACE", value: client, options: ["SME Demo Workspace", "Trading Company Demo", "Clinic Admin Demo"], onChange: setClient,
          disabled: !canManageWorkspace, disabledReason: manageWorkspaceReason, onDenied: denyWorkspaceChange, action: "workspace" })),
      h("div", { className: "tb-env" },
        h(Selector, { icon: "layers", label: "ENVIRONMENT", value: env, options: ENVIRONMENTS, onChange: setEnv,
          disabled: !canManageWorkspace, disabledReason: manageWorkspaceReason, onDenied: denyWorkspaceChange, action: "environment" })),
      h("div", { className: "grow" }),
      // acting-as identity + role switcher, merged into one control (C2/C5)
      h("div", { className: "tb-role" },
        h(RoleSwitcher, { role, setRole })),
      // language toggle
      h("div", { className: "tb-lang" }, h(LangToggle)),
      // getting-started guide (A7) — reopen the first-run checklist anytime
      h("button", { className: "btn btn-ghost", style: { padding: 9 }, onClick: onOpenGuide, title: "Getting started guide", "aria-label": "Open getting started guide", "data-topbar-action": "getting-started" }, h(window.Icon, { name: "sparkle", size: 17 })),
      // search
      h("button", { className: "btn btn-ghost", style: { padding: 9 }, onClick: onSearch, title: "Search pages and tasks (⌘K)", "aria-label": "Search pages and tasks", "data-topbar-action": "search" }, h(window.Icon, { name: "search", size: 17 })),
      // bell
      h("div", { style: { position: "relative" } },
        h("button", { className: "btn btn-ghost", style: { padding: 9 }, "data-topbar-action": "notifications", "data-notification-unread-count": String(unread.length), "data-notification-total-count": String(notifications.length), "data-notification-panel-open": bell ? "true" : "false", "aria-expanded": bell ? "true" : "false", "aria-controls": bell ? bellPanelId : undefined, onClick: () => setBell(!bell), title: "Notifications", "aria-label": unread.length ? unread.length + " unread notifications" : "No unread notifications" },
          h(window.Icon, { name: "bell", size: 17 }),
          unread.length > 0 && h("span", { className: "notif-count" }, unread.length > 9 ? "9+" : String(unread.length))),
        bell && h(React.Fragment, null,
          h("div", { onClick: () => setBell(false), style: { position: "fixed", inset: 0, zIndex: 40 } }),
          h("div", { id: bellPanelId, className: "glass", role: "region", "aria-label": "Notifications", "data-notification-panel": "true", "data-notification-panel-unread": String(unread.length), "data-notification-panel-total": String(notifications.length), style: { position: "fixed", top: "calc(var(--topbar-h) + 8px)", right: 12, width: "min(320px, calc(100vw - 24px))", zIndex: 50, padding: 0, boxShadow: "var(--shadow-lg)", overflow: "hidden" } },
            h("div", { className: "row between", style: { padding: "12px 14px", borderBottom: "1px solid var(--border)", gap: 10 } },
              h("div", null,
                h("div", { style: { fontWeight: 700, fontSize: 13 } }, "Notifications"),
                h("div", { style: { fontSize: 11, color: "var(--text-faint)", marginTop: 2 } }, unread.length ? unread.length + " unread notifications" : "All notifications are read.")),
              unread.length > 0 && h("button", { className: "notif-mark", "data-notification-action": "mark-read", "data-notification-mark-count": String(unread.length), "data-notification-rbac-disabled": canManageNotifications ? "false" : "true", disabled: !canManageNotifications, title: canManageNotifications ? "" : notificationDenyReason, onClick: () => canManageNotifications && ctx && ctx.markNotificationRead && ctx.markNotificationRead(unread.map((n) => n.id)) }, "Mark read")),
            notifications.length === 0
              ? h("div", { className: "notif-empty" }, h("div", { style: { marginBottom: 8 } }, h(window.Icon, { name: "checkCircle", size: 20, color: "var(--green)" })), "No approval, issue, value or task updates need attention.")
              : notifications.map(renderNotification))),
      ),
      h(window.Button, { variant: "primary", icon: "plus", ariaLabel: "New task", disabled: !canWorkOrder, title: canWorkOrder ? "" : workOrderReason, "aria-disabled": canWorkOrder ? "false" : "true", "data-topbar-action": "new-work-order", "data-workorder-rbac-disabled": canWorkOrder ? "false" : "true", onClick: canWorkOrder ? onNewWO : denyWorkOrder }, h("span", { className: "tb-newwo-label" }, "New task")));
  }

  // ⌘K command palette — search and jump across the operating system surface.

  window.EmplixTopBar = {
    Selector,
    LangToggle,
    RoleSwitcher,
    buildTopbarNotifications,
    Topbar,
  };
  window.LangToggle = LangToggle;
  window.Topbar = Topbar;
  window.TopBar = Topbar;
})();
