// screen_config.jsx — Role Configuration
(function () {
  const { useState, useEffect } = React;
  const h = React.createElement;
  window.Screens = window.Screens || {};

  // ---- A8: persist Config screen choices under a guarded key ----
  // Today the form was useState-only and reset on reload. We now hydrate from
  // localStorage["emplix-config-v1"] (own v1 guard, independent of emplix-config
  // shape) and persist on change. Save/Run/Publish stay demo toasts; the
	  // "no real integrations" banner is unchanged. Nothing here calls a backend.
	  const CONFIG_KEY = "emplix-config-v1";
	  const CONFIG_VERSION = 1;
	  window.CONFIG_STORE_KEY = CONFIG_KEY;
  function loadConfig() {
    try {
      const raw = localStorage.getItem(CONFIG_KEY);
      if (!raw) return null;
      const saved = JSON.parse(raw);
      // version guard — ignore stale shapes silently
      if (!saved || saved.version !== CONFIG_VERSION) return null;
      return saved.state || null;
    } catch (e) { return null; }
  }
  function saveConfig(state) {
    try { localStorage.setItem(CONFIG_KEY, JSON.stringify({ version: CONFIG_VERSION, state })); } catch (e) {}
  }

  const TABS = ["Agent Role", "Instructions", "Tools", "Data Sources", "Approval Rules", "Run Mode"];
  const TAB_LABEL = { "Agent Role": "Profile", Instructions: "Instructions", Tools: "Apps", "Data Sources": "Files", "Approval Rules": "Approval rules", "Run Mode": "Work settings" };
  const TAB_IDS = {
    "Agent Role": "agent-role",
    "Instructions": "instructions",
    "Tools": "tools",
    "Data Sources": "data-sources",
    "Approval Rules": "approval-rules",
    "Run Mode": "run-mode",
  };
  const AUTONOMY = ["Watch only", "Suggest", "Draft with approval", "Auto-send approved work"];
  const WORK_SETTING_LABEL = ["Watch only", "Suggest", "Drafts need approval", "Approved repeat work"];
  // connector id -> dashboard icon name (P dict). Channels (mail/message) vs file drives (folder).
  const CONN_ICON = { email: "mail", instagram: "message", gdrive: "folder", whatsapp: "message", dropbox: "folder", onedrive: "folder", box: "folder" };
  const DATASRC = [
    { name: "ProductFAQ.docx", cls: "Internal", access: "Read + cite", scope: "Published FAQ only" },
    { name: "Customer Email Inbox", cls: "Confidential", access: "Read + draft", scope: "Selected demo messages" },
    { name: "Price List 2026H1.xlsx", cls: "Internal", access: "Read", scope: "Approved price columns" },
    { name: "Receipt Upload Folder", cls: "Restricted", access: "Read + flag", scope: "This month" },
  ];
  const POLICIES = [
    { name: "Read approved files", val: "Always allow" },
    { name: "Draft customer reply", val: "Always allow" },
    { name: "Send customer message", val: "Always ask" },
    { name: "Publish social post", val: "Always ask" },
    { name: "Answer without source", val: "Disabled" },
  ];
  const POLICY_LABEL = { "Answer without source": "Answer without a file" };
  function defaultPolicyMap() { return Object.fromEntries(POLICIES.map((p) => [p.name, p.val])); }
  const POLICY_TONE = { "Always allow": "green", "Always ask": "amber", "Disabled": "neutral" };
  // Per-role English mission lines (grounded, red-line safe). Shown in the Agent Role tab
  // so Config reflects the employee chosen in the selector (synced with #employees).
  const MISSION_EN = {
    clerk: "Summarize approved files, list next steps, and flag missing facts.",
    cs: "Draft replies from approved files. Do not answer without a source.",
    sales: "Draft quotes and follow-ups from approved prices and terms. Flag missing details.",
    social: "Draft posts from the content calendar and product file. Wait for approval.",
    acct: "Read receipts and invoices. Flag items for review. Do not post entries.",
  };
  function releaseSeed() {
    return { publishedVersion: 11, publishedAt: "2d ago", testState: "passed", testProgress: 100, passRate: 94.8, failedCases: 0, status: "published" };
  }
  function releaseOf(map, roleId) { return Object.assign(releaseSeed(), (map && map[roleId]) || {}); }
  function roleDraftFingerprint(draft) {
    const d = draft || {};
    const policyPairs = Object.keys(d.policies || {}).sort().map((k) => k + ":" + d.policies[k]);
    return JSON.stringify({
      name: d.name || "",
      department: d.department || "",
      reportsTo: d.reportsTo || "",
      mission: d.mission || "",
      autonomy: typeof d.autonomy === "number" ? d.autonomy : null,
      policies: policyPairs,
    });
  }
  function ReleasePipeline({ release, canEdit, roleId }) {
    const { Badge, ProgressBar, Icon } = window;
    const draftSaved = !!release.draftVersion;
    const testing = release.testState === "running";
    const tested = release.testState === "passed" && draftSaved;
    const published = draftSaved && release.publishedVersion === release.draftVersion && release.status === "published";
    const rolledBack = published && !!release.rolledBackAt;
    const steps = [
      { id: "draft", label: "Save", done: draftSaved, current: !draftSaved, sub: draftSaved ? "v" + release.draftVersion + " saved " + (release.draftSavedAt || "now") : "Save changes" },
      { label: "Checks", done: tested, current: testing, sub: testing ? "240 checks running" : tested ? (release.passRate || 0) + "% pass · " + (release.failedCases || 0) + " failed" : "Check facts, rules and tone" },
      { id: "publish", label: "Apply", done: published, current: tested && !published, sub: published ? "v" + release.publishedVersion + (rolledBack ? " restored " + release.rolledBackAt : " applied " + (release.publishedAt || "now")) : "Locked until checks pass" },
      { label: "History", done: !!release.auditId, current: published && !release.auditId, sub: release.auditId ? "Saved as " + release.auditId : "Applying saves a history record" },
    ];
    const pct = published ? 100 : tested ? 74 : testing ? Math.max(35, release.testProgress || 35) : draftSaved ? 35 : 12;
    return h(window.Card, {
      "data-config-release-pipeline": "true",
      "data-config-role-id": roleId || "",
      "data-config-draft-version": draftSaved ? String(release.draftVersion) : "",
      "data-config-published-version": release.publishedVersion ? String(release.publishedVersion) : "",
      "data-config-test-state": release.testState || "",
      "data-config-status": release.status || "",
      "data-config-audit-id": release.auditId || "",
      "data-config-rollback-available": release.rollbackState ? "true" : "false",
      style: { padding: 16, marginBottom: 16 }
    },
      h("div", { className: "row between wrap", style: { gap: 12, marginBottom: 12 } },
        h("div", null,
          h("div", { style: { fontSize: 11, fontWeight: 800, letterSpacing: ".08em", color: "var(--text-faint)", textTransform: "uppercase", marginBottom: 5 } }, "Apply changes"),
          h("div", { style: { fontSize: 13, color: "var(--text-dim)", lineHeight: 1.45 } }, "Save, check, then apply.")),
        h(Badge, { tone: rolledBack ? "amber" : published ? "green" : testing ? "blue" : tested ? "amber" : canEdit ? "neutral" : "gray" },
          rolledBack ? "Undone" : published ? "Applied" : testing ? "Checking" : tested ? "Ready to apply" : canEdit ? "Save needed" : "View only")),
      h(ProgressBar, { value: pct, tone: published ? "green" : testing ? "blue" : tested ? "amber" : "neutral", height: 6 }),
      h("div", { className: "release-steps", style: { marginTop: 12 } },
        steps.map((s, i) => h("div", {
          key: s.label,
          className: "release-step" + (s.done ? " done" : "") + (s.current ? " current" : ""),
          "data-config-release-step": s.id || s.label.toLowerCase().replace(/\s+/g, "-"),
          "data-config-step-done": s.done ? "true" : "false",
          "data-config-step-current": s.current ? "true" : "false"
        },
          h("div", { className: "row gap6", style: { alignItems: "center" } },
            h("span", { className: "inline-icon", style: { width: 20, height: 20 } }, s.done ? h(Icon, { name: "check", size: 12 }) : i + 1),
            h("b", null, s.label)),
          h("span", null, s.sub)))));
  }

  // Live instructions editor — bound to office role.instructions (governed, persisted), keyed by roleId so it remounts per employee.
	  function InstructionsEditor({ ctx, role, canEdit }) {
	    const { Badge, Button } = window;
	    const [text, setText] = useState(role.instructions || "");
	    useEffect(() => { setText(role.instructions || ""); }, [role.id, role.instructions]);
	    const dirty = text !== (role.instructions || "");
    const lab = (t) => h("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".06em", color: "var(--text-faint)", margin: "0 0 8px" } }, t);
	    return h("div", { "data-config-instructions-panel": role.id, "data-config-instructions-dirty": dirty ? "true" : "false", "data-config-instructions-length": String((text || "").length) },
	      lab("Working instructions"),
	      h("p", { style: { fontSize: 12, color: "var(--text-faint)", margin: "-4px 0 12px" } }, "Write rules for this employee's next drafts."),
	      h("textarea", { className: "field", rows: 6, value: text, disabled: !canEdit, "data-config-instructions": role.id, onChange: (ev) => setText(ev.target.value) }),
      h("div", { className: "row gap8 wrap", style: { marginTop: 12 } },
        h(Button, { variant: "primary", icon: "check", disabled: !canEdit || !dirty, "data-config-action": "save-instructions", "data-config-role-id": role.id, onClick: () => ctx.saveInstructions(role.id, text) }, "Save instructions"),
        dirty ? h(Badge, { tone: "amber" }, "Unsaved changes") : h(Badge, { tone: "green", dot: true }, "Saved")),
      h("div", { style: { marginTop: 18 } },
        lab("Built-in rules (view only)"),
	        h("textarea", { className: "field", rows: 5, readOnly: true, style: { fontFamily: "var(--mono)", fontSize: 12.5, opacity: .82 },
	          value: ["Use named files only.", "Show the file used for each fact.", "Flag missing files. Do not guess.", "Get approval before anything is sent."].map((line) => window.I18N && window.I18N.t ? window.I18N.t(line) : line).join("\n") }),
        h("div", { className: "row gap8 wrap", style: { marginTop: 12 } }, h(Badge, { tone: "green" }, "Files required"), h(Badge, { tone: "blue" }, "File names shown"), h(Badge, { tone: "amber" }, "Ask when unsure"))));
  }

  function Config({ ctx }) {
    const D = window.deriveDashboardData(ctx.office);
    const { PageHeader, Card, Avatar, Badge, Button, Toggle, Segmented, FutureStep } = window;
    const savedConfig = loadConfig() || {};
    // hydrate from the guarded key so choices survive reload (A8) — read once
    const [tab, setTab] = useState(() => { const t = savedConfig.tab; return TABS.indexOf(t) >= 0 ? t : "Agent Role"; });
    const [autoByRole, setAutoByRole] = useState(() => savedConfig.autoByRole || {});
    const [policiesByRole, setPoliciesByRole] = useState(() => savedConfig.policiesByRole || {});
    const [releaseByRole, setReleaseByRole] = useState(() => savedConfig.releaseByRole || {});
    const [roleDrafts, setRoleDrafts] = useState(() => savedConfig.roleDrafts || {});
    // the missing step: choose WHICH employee to configure (synced to the #employees roster + a #config/<roleId> deep-link)
    const roles = ctx.office.roles || [];
    const firstId = (roles.find((r) => r.hired) || roles[0] || { id: "cs" }).id;
    const [roleId, setRoleId] = useState(() => (ctx.pageArg && ctx.office.roleById[ctx.pageArg]) ? ctx.pageArg : firstId);
    useEffect(() => { if (ctx.pageArg && ctx.office.roleById[ctx.pageArg]) setRoleId(ctx.pageArg); }, [ctx.pageArg]);
    // persist every choice and release gate state (own v1 guard)
    useEffect(() => { saveConfig({ tab, autoByRole, policiesByRole, releaseByRole, roleDrafts }); },
      [tab, autoByRole, policiesByRole, releaseByRole, roleDrafts]);
    const role = ctx.office.roleById[roleId] || ctx.office.roleById[firstId];
    const e = D.emp(roleId);
    // role-driven display values — reads existing fields only (no dataVersion bump)
	    const reportsTo = (e.owner && e.owner !== "—") ? e.owner : "Operations Manager";
	    const roleProfile = window.roleDisplayProfile ? window.roleDisplayProfile(role, roleId, {
	      name: e.name,
	      department: e.dept,
	      reportsTo,
	      mission: MISSION_EN[roleId] || MISSION_EN.cs
	    }) : {};
	    const defaultRoleMission = MISSION_EN[roleId] || MISSION_EN.cs;
	    const roleMission = roleProfile.mission || defaultRoleMission;
	    const roleDraft = Object.assign({ name: roleProfile.name || e.name, department: roleProfile.department || e.dept, reportsTo: roleProfile.reportsTo || reportsTo, mission: roleMission }, roleDrafts[roleId] || {});
    const hasPublishedMission = !!(role && role.publishedProfile && String(role.publishedProfile.mission || "").trim());
    const hasSavedMission = !!(roleDrafts[roleId] && Object.prototype.hasOwnProperty.call(roleDrafts[roleId], "mission"));
    const missionValue = !hasPublishedMission && !hasSavedMission && window.I18N && window.I18N.t
      ? window.I18N.t(defaultRoleMission)
      : roleDraft.mission;
    const auto = typeof autoByRole[roleId] === "number" ? autoByRole[roleId] : (typeof role.publishedAutonomy === "number" ? role.publishedAutonomy : 2);
    const policies = Object.assign(defaultPolicyMap(), role.publishedPolicies || {}, policiesByRole[roleId] || {});
    const draftSnapshot = Object.assign({}, roleDraft, {
      autonomy: auto,
      autonomyLabel: WORK_SETTING_LABEL[auto],
      policies: Object.assign({}, policies),
	    });
	    function setRoleAuto(value) {
	      if (!canEdit) return;
	      setAutoByRole((cur) => Object.assign({}, cur, { [roleId]: value }));
	    }
	    function setRolePolicy(name, value) {
	      if (!canEdit) return;
	      setPoliciesByRole((cur) => {
	        const prev = Object.assign(defaultPolicyMap(), role.publishedPolicies || {}, (cur && cur[roleId]) || {});
	        return Object.assign({}, cur, { [roleId]: Object.assign({}, prev, { [name]: value }) });
	      });
	    }
	    function setRoleDraftField(key, value) {
	      if (!canEdit) return;
	      setRoleDrafts((cur) => {
		        const prev = Object.assign({ name: roleProfile.name || e.name, department: roleProfile.department || e.dept, reportsTo: roleProfile.reportsTo || reportsTo, mission: roleMission }, cur[roleId] || {});
	        return Object.assign({}, cur, { [roleId]: Object.assign({}, prev, { [key]: value }) });
	      });
    }
    // unified tool/connector model: the Tools tab lists the LIVE workspace connector
    // roster; a row's toggle reflects membership in role.connectors (assigned + on).
    const allConnectors = ctx.office.connectors || [];
    const roleConnIds = (role && role.connectors) || [];
    const allFiles = ctx.office.files || [];
    const roleFiles = allFiles.filter((f) => (f.usedBy || []).indexOf(roleId) >= 0);
    // Builder configuration is owner-only (promote/setSkill/configure). Non-owners
    // see the same screen read-only with the publish controls disabled-with-reason.
	        const canEdit = ctx.can("configure");
	        const canEditInstructions = ctx.can("saveInstructions");
		    const canSourceEdit = ctx.can("organizeFiles");
	    const editReason = ctx.denyReason("configure");
	    const sourceEditReason = ctx.denyReason("organizeFiles");
	    const release = releaseOf(releaseByRole, roleId);
	    const draftMatchesSnapshot = !!release.snapshot && roleDraftFingerprint(release.snapshot) === roleDraftFingerprint(draftSnapshot);
	    const hasRollbackState = !!(release.rollbackState && release.rollbackState.roleState);
	    const canRollback = canEdit && hasRollbackState && release.status === "published" && release.publishedVersion === release.draftVersion;
	    function patchRelease(targetRole, patcher) {
	      setReleaseByRole((cur) => {
	        const prev = releaseOf(cur, targetRole);
	        const next = typeof patcher === "function" ? patcher(prev) : Object.assign({}, prev, patcher || {});
	        return Object.assign({}, cur, { [targetRole]: next });
	      });
	    }
	    function clearRoleOverride(setter) {
	      setter((cur) => {
	        if (!cur || !Object.prototype.hasOwnProperty.call(cur, roleId)) return cur || {};
	        const next = Object.assign({}, cur);
	        delete next[roleId];
	        return next;
	      });
	    }
	    function currentPublishedSnapshot() {
	      const currentAuto = typeof role.publishedAutonomy === "number" ? role.publishedAutonomy : 2;
	      return {
	        name: roleProfile.name || e.name,
	        department: roleProfile.department || e.dept,
	        reportsTo: roleProfile.reportsTo || reportsTo,
	        mission: roleProfile.mission || roleMission,
	        autonomy: currentAuto,
	        autonomyLabel: role.publishedAutonomyLabel || WORK_SETTING_LABEL[currentAuto],
	        policies: Object.assign(defaultPolicyMap(), role.publishedPolicies || {}),
	      };
	    }
	    function saveDraft() {
	      if (!canEdit) return;
	      const nextVersion = Math.max(release.maxVersion || 0, release.draftVersion || 0, release.publishedVersion || 11) + 1;
	      patchRelease(roleId, Object.assign({}, release, {
	        draftVersion: nextVersion,
	        draftSavedAt: "just now",
        testState: "not_run",
        testProgress: 0,
        passRate: null,
        failedCases: null,
        testedAt: null,
        status: "draft",
        auditId: null,
        snapshot: Object.assign({}, draftSnapshot),
      }));
      ctx.showToast("Changes saved · v" + nextVersion + " · not applied yet");
    }
    function runTest() {
      if (!canEdit || !release.draftVersion || !draftMatchesSnapshot || release.testState === "running") return;
      const targetRole = roleId;
      const targetVersion = release.draftVersion;
      patchRelease(targetRole, (prev) => Object.assign({}, prev, { testState: "running", testProgress: 42, status: "testing" }));
      ctx.showToast("Checks started. Apply stays locked until they pass.");
      window.setTimeout(() => {
        patchRelease(targetRole, (prev) => {
          if (prev.draftVersion !== targetVersion || prev.testState !== "running") return prev;
          return Object.assign({}, prev, { testState: "passed", testProgress: 100, passRate: 96.4, failedCases: 0, testedAt: "just now", status: "tested" });
        });
      }, 1100);
    }
	    function publishVersion() {
	      if (!canEdit || !release.draftVersion || !draftMatchesSnapshot || release.testState !== "passed") return;
	      const testedDraft = Object.assign({}, release.snapshot || draftSnapshot);
	      const result = ctx.publishConfigVersion ? ctx.publishConfigVersion(roleId, release.draftVersion, release.passRate || 96.4, testedDraft, {
	        previousVersion: release.publishedVersion || role.lastConfigVersion || null,
	        previousPublishedAt: release.publishedAt || "",
	        snapshot: currentPublishedSnapshot(),
	      }) : null;
		      if (!result) return;
		      const auditId = result && typeof result === "object" ? result.auditId : result;
	      const rollbackState = result && typeof result === "object" ? result.rollbackState : null;
	      patchRelease(roleId, (prev) => Object.assign({}, prev, {
	        publishedVersion: prev.draftVersion,
	        publishedAt: "just now",
	        status: "published",
	        auditId: auditId || prev.auditId || "audit-log",
	        maxVersion: Math.max(prev.maxVersion || 0, prev.draftVersion || 0),
	        rollbackState: rollbackState || null,
	        rollbackAuditId: null,
	        rolledBackAt: null,
	        rolledBackFromVersion: null,
	      }));
	    }
		    function rollbackVersion() {
	      if (!canRollback) return;
	      const result = ctx.rollbackConfigVersion ? ctx.rollbackConfigVersion(roleId, release.publishedVersion, release.rollbackState) : null;
	      if (!result) return;
	      clearRoleOverride(setRoleDrafts);
	      clearRoleOverride(setPoliciesByRole);
	      clearRoleOverride(setAutoByRole);
	      patchRelease(roleId, (prev) => {
	        const targetVersion = result.publishedVersion || (prev.rollbackState && prev.rollbackState.previousVersion) || Math.max((prev.publishedVersion || 1) - 1, 1);
	        return Object.assign({}, prev, {
	          publishedVersion: targetVersion,
	          draftVersion: targetVersion,
	          draftSavedAt: "rolled back just now",
	          publishedAt: "rolled back just now",
	          status: "published",
	          testState: "passed",
	          testProgress: 100,
	          passRate: prev.passRate || 96.4,
	          failedCases: 0,
	          testedAt: "rolled back just now",
	          auditId: result.auditId || prev.auditId || "rollback-audit",
	          rollbackAuditId: result.auditId || null,
	          rollbackOf: prev.rollbackState && prev.rollbackState.auditId || null,
	          rolledBackFrom: prev.publishedVersion,
	          rolledBackFromVersion: prev.publishedVersion,
	          rolledBackAt: "just now",
	          snapshot: result.snapshot || (prev.rollbackState && prev.rollbackState.snapshot) || null,
	          rollbackState: null,
	          maxVersion: Math.max(prev.maxVersion || 0, prev.publishedVersion || 0),
	        });
	      });
		    }
		    function requestRoleAuto(value) {
		      if (!canEdit) { ctx.showToast(editReason); return; }
		      setRoleAuto(value);
		    }
		    function requestRolePolicy(name, value) {
		      if (!canEdit) { ctx.showToast(editReason); return; }
		      setRolePolicy(name, value);
		    }

	    return h("div", null,
      // configuration banner
      h("div", { className: "row gap10", style: { padding: "11px 16px", borderRadius: 12, marginBottom: 18, background: "var(--violet-soft)", border: "1px solid rgba(111,91,230,.25)" } },
        h(window.Icon, { name: "lock", size: 16, color: "var(--violet)" }),
	        h("span", { style: { fontSize: 13, fontWeight: 600, color: "#5847c4" } }, canEdit ? "Sample employee setup" : "View-only employee setup"),
        h("span", { className: "grow" }),
	        h("span", { style: { fontSize: 12, color: "var(--text-dim)" } }, canEdit ? "Save, check, then apply." : editReason)),

      h(PageHeader, { eyebrow: "Setup", title: "Employee Setup",
        right: [
          h(Button, { key: "1", disabled: !canEdit, "data-config-action": "save-draft", "data-config-role-id": roleId, title: canEdit ? "Save changes as a draft; nothing changes for employees yet." : editReason, onClick: canEdit ? saveDraft : undefined }, "Save draft"),
          h(Button, { key: "2", icon: "play", disabled: !canEdit || !release.draftVersion || !draftMatchesSnapshot || release.testState === "running",
            "data-config-action": "run-test", "data-config-role-id": roleId,
            title: !canEdit ? editReason : !release.draftVersion ? "Save changes first." : !draftMatchesSnapshot ? "Save the changed draft before checking." : "Run checks before applying.", onClick: canEdit ? runTest : undefined }, release.testState === "running" ? "Checking" : "Run checks"),
	          h(Button, { key: "3", variant: "primary", icon: "arrowUp", disabled: !canEdit || !release.draftVersion || !draftMatchesSnapshot || release.testState !== "passed" || release.publishedVersion === release.draftVersion,
	            "data-config-action": "publish-version", "data-config-role-id": roleId,
	            title: !canEdit ? editReason : !release.draftVersion ? "Save changes first." : !draftMatchesSnapshot ? "Save and check the changes before applying." : release.testState !== "passed" ? "Run and pass checks first." : release.publishedVersion === release.draftVersion ? "These changes are already applied." : "Apply after checks. The change is saved in History and can be undone.", onClick: canEdit ? publishVersion : undefined }, "Apply changes"),
	          h(Button, { key: "4", icon: "refresh", disabled: !canRollback,
	            "data-config-action": "rollback-version", "data-config-role-id": roleId,
	            title: !canEdit ? editReason : !hasRollbackState ? "Apply new changes before undo is available." : release.status !== "published" ? "Undo is available only for the applied version." : "Restore the previous settings and save it in History.", onClick: canRollback ? rollbackVersion : undefined }, "Undo"),
	        ] }),

      // the missing step — choose which employee to configure (synced with #employees)
      h(Card, { style: { padding: 14, marginBottom: 16 } },
        h("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".08em", color: "var(--text-faint)", marginBottom: 10 } }, "CHOOSE AN EMPLOYEE"),
        h("div", { className: "row gap8 wrap" }, roles.map((r) =>
          h("button", { key: r.id, className: "role-tab" + (r.id === roleId ? " on" : ""),
            "data-config-role-tab": r.id, "data-config-role-active": r.id === roleId ? "true" : "false",
            onClick: () => { setRoleId(r.id); ctx.openPage("config", r.id); },
            style: r.id === roleId ? { borderColor: r.color, color: r.deep, background: "#fff" } : {} },
            h(window.Face, { role: r, size: 22, variant: "head" }), h("span", null, D.emp(r.id).short),
            r.hired ? h(window.Chip, { tone: "mint" }, r.hired.tier === "senior" ? "Hired · Senior" : "Hired") : h(window.Chip, { tone: "gray" }, "Not hired"))))),

      // editing target
      h(Card, { style: { padding: 16, marginBottom: 16 } },
        h("div", { className: "row between wrap", style: { gap: 10 } },
          h("div", { className: "row gap12" }, h(window.Face, { roleId: e.id, size: 44, variant: "portrait" }),
            h("div", null, h("div", { style: { fontWeight: 600, fontSize: 15 } }, h("span", null, "Editing · "), h("span", null, e.short)), h("div", { style: { fontSize: 12.5, color: "var(--text-faint)" } }, e.name))),
          h("div", { className: "row gap8 wrap" }, h(Badge, { tone: role.instructions ? "green" : "neutral", dot: true }, role.instructions ? "Instructions set" : "Default instructions"), role.hired ? h(Badge, { tone: "neutral" }, role.hired.tier === "senior" ? "Senior" : "Standard") : h(Badge, { tone: "gray" }, "Not hired"))),
	        h(FutureStep, { compact: true, tone: "violet", text: "Next: save, check, then apply." })),

      h(ReleasePipeline, { release, canEdit, roleId }),

      h("div", { style: { display: "grid", gridTemplateColumns: "200px 1fr", gap: 16, alignItems: "start" } },
        // tab rail
        h(Card, { style: { padding: 8 } }, TABS.map((t) => {
          const active = t === tab;
          return h("button", { key: t, onClick: () => setTab(t),
            "data-config-tab": t, "data-config-tab-id": TAB_IDS[t], "data-config-tab-active": active ? "true" : "false",
            style: { width: "100%", textAlign: "left", padding: "9px 12px", marginBottom: 2, borderRadius: 9, border: "none", cursor: "pointer", fontFamily: "var(--font)", fontSize: 13, fontWeight: active ? 600 : 500,
              background: active ? "var(--blue-soft)" : "transparent", color: active ? "var(--blue-deep)" : "var(--text-dim)" } }, TAB_LABEL[t] || t);
        })),

        // panel
        h(Card, { style: { padding: 22 } }, renderTab())));

    function renderTab() {
      switch (tab) {
        case "Agent Role": return form([
          ["Name", h("input", { id: "config-role-name-" + roleId, key: "rn-" + roleId, className: "field", value: roleDraft.name, disabled: !canEdit, "data-config-field": "name", "data-config-role-id": roleId, onChange: (e) => setRoleDraftField("name", e.target.value) }), "config-role-name-" + roleId],
          ["Department", h("input", { id: "config-role-department-" + roleId, key: "dp-" + roleId, className: "field", value: roleDraft.department, disabled: !canEdit, "data-config-field": "department", "data-config-role-id": roleId, onChange: (e) => setRoleDraftField("department", e.target.value) }), "config-role-department-" + roleId],
          ["Reports to", h("input", { id: "config-role-reports-to-" + roleId, key: "rt-" + roleId, className: "field", value: roleDraft.reportsTo, disabled: !canEdit, "data-config-field": "reportsTo", "data-config-role-id": roleId, onChange: (e) => setRoleDraftField("reportsTo", e.target.value) }), "config-role-reports-to-" + roleId],
          ["Main task", h("textarea", { id: "config-role-main-task-" + roleId, key: "ms-" + roleId, className: "field", rows: 3, value: missionValue, disabled: !canEdit, "data-config-field": "mission", "data-config-role-id": roleId, onChange: (e) => setRoleDraftField("mission", e.target.value) }), "config-role-main-task-" + roleId],
        ]);
        case "Instructions": return h(InstructionsEditor, { key: "instr-" + roleId, ctx, role, canEdit: canEditInstructions });
        case "Tools": return h("div", null, label("Apps"),
	          h("p", { style: { fontSize: 12, color: "var(--text-faint)", margin: "-6px 0 14px" } }, "Choose apps here and documents in Files."),
          allConnectors.length === 0
            ? h("p", { style: { fontSize: 13, color: "var(--text-faint)" } }, "No apps yet. Connect one in Apps.")
            : h("div", { style: { display: "flex", flexDirection: "column", gap: 2 } }, allConnectors.map((c) => {
              const cn = (window.CONN_NAME_EN && window.CONN_NAME_EN[c.id]) || c.name;
              const connected = c.status === "已連接";
              const assigned = roleConnIds.indexOf(c.id) >= 0;
              const statusText = connected ? (c.health !== "ok" ? "Connected · reconnect needed" : "Connected") : "Not connected";
              return h("div", { key: c.id, className: "row between",
                "data-config-tool-row": c.id,
                "data-config-role-id": roleId,
                "data-connector-id": c.id,
                "data-config-tool-assigned": assigned ? "true" : "false",
                "data-config-tool-connected": connected ? "true" : "false",
                "data-config-tool-health": c.health || "",
                style: { padding: "12px 14px", borderRadius: 10, background: assigned ? "var(--blue-soft)" : "var(--bg-3)", border: "1px solid var(--border)", marginBottom: 8, opacity: connected ? 1 : .72 } },
                h("span", { className: "row gap10" },
                  h(window.Icon, { name: CONN_ICON[c.id] || "link", size: 15, color: assigned ? "var(--blue)" : "var(--text-faint)" }),
                  h("span", null,
                    h("div", { style: { fontSize: 13.5, fontWeight: 500 } }, h("span", null, cn)),
                    h("div", { style: { fontSize: 11.5, color: connected && c.health !== "ok" ? "var(--amber)" : "var(--text-faint)" } }, h("span", null, statusText)))),
                connected
                  ? (canEdit
                      ? h(Toggle, { on: assigned, blue: true, "data-config-action": "set-role-connector", "data-config-role-id": roleId, "data-connector-id": c.id, "data-config-tool-assigned": assigned ? "true" : "false", onChange: (v) => ctx.setRoleConnector(roleId, c.id, v) })
                      : h("span", { title: ctx.denyReason("setRoleConnector"), style: { opacity: .5, pointerEvents: "none" } }, h(Toggle, { on: assigned, blue: true, disabled: true, "data-config-action": "set-role-connector", "data-config-role-id": roleId, "data-connector-id": c.id, "data-config-tool-assigned": assigned ? "true" : "false", onChange: () => {} })))
                  : h(Button, { sm: true, variant: "ghost", iconRight: "arrowRight", "data-config-action": "manage-connector", "data-connector-id": c.id, onClick: () => ctx.openPage("connectors") }, "Open Apps"));
            })));
	        case "Data Sources": return h("div", null, label("Files"),
	          h("p", { style: { fontSize: 12, color: "var(--text-faint)", margin: "-6px 0 14px" } }, "Choose the files this employee can use."),
	          h("div", { className: "row gap8 wrap", style: { marginBottom: 12 } },
	            h(Badge, { tone: roleFiles.length ? "blue" : "neutral" }, roleFiles.length + "/" + allFiles.length + " assigned"),
	            h(Button, { sm: true, variant: "ghost", iconRight: "arrowRight", "data-config-action": "open-file-room", "data-config-role-id": roleId, onClick: () => ctx.openPage("files") }, "Open Files")),
	          allFiles.length === 0
	            ? h("p", { style: { fontSize: 13, color: "var(--text-faint)" } }, "No files yet.")
	            : h("div", { "data-config-source-table": "true", "data-config-role-id": roleId, style: { overflowX: "auto" } }, h("table", { className: "tbl" }, h("thead", null, h("tr", null, ["File", "Employee access", "Times used", ""].map((c, i) => h("th", { key: i, style: i === 2 ? { textAlign: "right" } : i === 3 ? { width: 72 } : null }, c)))),
	              h("tbody", null, allFiles.map((f) => {
	                const assigned = (f.usedBy || []).indexOf(roleId) >= 0;
	                return h("tr", { key: f.id || f.name,
	                  "data-config-source-row": f.id || f.name,
	                  "data-config-role-id": roleId,
	                  "data-file-id": f.id || "",
	                  "data-config-source-assigned": assigned ? "true" : "false",
	                  "data-config-source-refs": String(f.refs || 0),
	                  "data-config-source-kind": f.kind || "",
	                  "data-config-source-source": f.source || "",
	                  style: assigned ? { background: "var(--blue-soft)" } : null },
	                  h("td", { style: { fontWeight: 600 } },
	                    h("span", null, f.name),
	                    h("div", { style: { fontSize: 11.5, color: "var(--text-faint)", fontWeight: 400, marginTop: 3 } }, [f.kind, (f.tags || []).slice(0, 3).map((t) => "#" + t).join(" ")].filter(Boolean).join(" · "))),
	                  h("td", null, h(Badge, { tone: assigned ? "blue" : "neutral" }, assigned ? "Can use" : "Not assigned")),
	                  h("td", { className: "mono", style: { textAlign: "right" } }, (f.refs || 0) + "×"),
	                  h("td", { style: { textAlign: "right" } }, canSourceEdit
	                    ? h(Toggle, { on: assigned, blue: true, "data-config-action": "set-role-source", "data-config-role-id": roleId, "data-file-id": f.id || "", "data-config-source-assigned": assigned ? "true" : "false", onChange: (v) => { if (v !== assigned) ctx.toggleFileEmployee(f.id, roleId); } })
	                    : h("span", { title: sourceEditReason, style: { opacity: .5, pointerEvents: "none" } }, h(Toggle, { on: assigned, blue: true, disabled: true, "data-config-action": "set-role-source", "data-config-role-id": roleId, "data-file-id": f.id || "", "data-config-source-assigned": assigned ? "true" : "false", onChange: () => {} }))));
	              })))));
	        case "Approval Rules": return h("div", { "data-config-policy-panel": roleId },
	          h("p", { style: { fontSize: 12, color: "var(--text-faint)", margin: "-6px 0 14px" } }, "Choose what this employee can do after changes are applied."),
	          h("div", { style: { display: "flex", flexDirection: "column", gap: 8 } }, POLICIES.map((p) =>
	            h("div", { key: p.name, className: "row between", "data-config-policy-row": p.name, "data-config-role-id": roleId, "data-config-policy-value": policies[p.name],
	              style: { padding: "10px 14px", borderRadius: 10, background: "var(--bg-3)", border: "1px solid var(--border)" } },
	              h("span", { style: { fontSize: 13.5, fontWeight: 500 } }, POLICY_LABEL[p.name] || p.name),
		              h(Segmented, { value: policies[p.name], disabled: !canEdit, title: canEdit ? "Set the approval rule for the next applied version." : editReason, onChange: (v) => requestRolePolicy(p.name, v), options: ["Always allow", "Always ask", "Disabled"].map((value) => ({
			                value,
			                label: value,
			                attrs: { "data-config-action": "set-policy", "data-config-role-id": roleId, "data-config-policy-name": p.name, "data-config-policy-value": value, "data-config-policy-active": policies[p.name] === value ? "true" : "false" }
			              })) })))));
	        case "Run Mode": return h("div", { "data-config-autonomy-panel": roleId, "data-config-role-id": roleId, "data-config-autonomy-value": String(auto), "data-config-autonomy-label": AUTONOMY[auto] }, label("Work settings"),
	          h("p", { style: { fontSize: 12, color: "var(--text-faint)", margin: "-6px 0 6px" } }, "Choose when this employee needs approval."),
	          h("div", { style: { padding: "10px 4px 0" } },
	            h("div", { style: { position: "relative", height: 6, borderRadius: 999, background: "var(--bg-3)", border: "1px solid var(--border)", margin: "30px 12px 12px" } },
	              h("div", { style: { position: "absolute", left: 0, top: -1, bottom: -1, width: `${(auto / 3) * 100}%`, borderRadius: 999, background: "linear-gradient(90deg,var(--blue),var(--violet))" } }),
		              AUTONOMY.map((a, i) => h("button", { key: i, onClick: canEdit ? () => requestRoleAuto(i) : undefined, disabled: !canEdit, title: canEdit ? "Choose " + WORK_SETTING_LABEL[i] + "." : editReason,
		                "data-config-action": "set-autonomy", "data-config-role-id": roleId, "data-config-autonomy-value": String(i), "data-config-autonomy-label": a, "data-config-autonomy-active": auto === i ? "true" : "false",
		                style: { position: "absolute", left: `${(i / 3) * 100}%`, top: "50%", transform: "translate(-50%,-50%)", width: 20, height: 20, borderRadius: "50%", cursor: canEdit ? "pointer" : "not-allowed", opacity: !canEdit && i > auto ? .55 : 1,
		                  background: i <= auto ? "var(--blue)" : "var(--bg-2)", border: `2px solid ${i <= auto ? "var(--blue)" : "var(--border-2)"}`, boxShadow: "var(--shadow-sm)" } }))),
		            h("div", { className: "row between", style: { margin: "0 6px" } }, AUTONOMY.map((a, i) =>
			              h("div", { key: i, role: "button", tabIndex: canEdit ? 0 : -1, onClick: canEdit ? () => requestRoleAuto(i) : undefined,
			                onKeyDown: canEdit ? (ev) => { if (ev.key === "Enter" || ev.key === " ") { ev.preventDefault(); requestRoleAuto(i); } } : undefined,
		                title: canEdit ? "Choose " + WORK_SETTING_LABEL[i] + "." : editReason, "aria-disabled": !canEdit, "aria-pressed": auto === i ? "true" : "false",
			                "data-config-action": "set-autonomy-label", "data-config-autonomy-label-option": a, "data-config-role-id": roleId, "data-config-autonomy-value": String(i), "data-config-autonomy-active": auto === i ? "true" : "false",
			                style: { textAlign: "center", width: "25%", minHeight: 44, display: "flex", alignItems: "center", justifyContent: "center", padding: "6px 4px", borderRadius: 10, cursor: canEdit ? "pointer" : "not-allowed", opacity: !canEdit && auto !== i ? .65 : 1 } },
	                h("div", { style: { fontSize: 12, fontWeight: auto === i ? 700 : 500, color: auto === i ? "var(--blue-deep)" : "var(--text-faint)" } }, WORK_SETTING_LABEL[i])))),
            h("div", { style: { marginTop: 24, padding: 16, borderRadius: 12, background: "var(--amber-soft)", border: "1px solid rgba(217,138,18,.25)", fontSize: 13, color: "#a8690a" } },
              h("strong", null, WORK_SETTING_LABEL[auto] + " — "), ["Reads and summarizes only.", "Creates suggestions for people to review.", "Creates drafts after a person checks the task.", "Handles proven low-risk repeat work after owner approval."][auto])));
        default: return null;
      }
    }
    function label(t) { return h("div", { style: { fontSize: 11, fontWeight: 700, letterSpacing: ".08em", color: "var(--text-faint)", marginBottom: 14 } }, t.toUpperCase()); }
    function form(rows) {
      return h("div", { style: { display: "flex", flexDirection: "column", gap: 18 } }, rows.map((r, i) =>
        h("div", { key: i }, h("label", { htmlFor: r[2], style: { display: "block", fontSize: 12.5, fontWeight: 600, marginBottom: 8, color: "var(--text-dim)" } }, r[0]), r[1])));
    }
  }

  window.Screens.config = Config;
})();
