// screen_roi.jsx — Roof · ROI/KPI (monthly outcomes, routines, reports + folded ROI analytics; reset-safe)
(function () {
  const { useState, useEffect } = React;
  const h = React.createElement;
  const { Card, CardHead, Badge, RiskBadge, Button, KPI, Avatar, PageHeader, Segmented, Toggle, ProgressBar, EmptyHint, FutureStep, Modal, Section, Icon } = window;
	  const { RoleIcon, RoleDot, InlineIcon, StatusIcon, Chip, levelChip, caveatLine, Seg3, AUDIT_TONE } = window;
	  const SHORT_EN = { clerk: "Admin Assistant", cs: "Customer Support Assistant", sales: "Sales Assistant", social: "Marketing Assistant", acct: "Accounting Assistant" };
	  function shortEN(office, id) {
	    const r = office.roleById[id];
	    return r && window.roleDisplayName ? window.roleDisplayName(r, id, { name: SHORT_EN[id] || id }) : (SHORT_EN[id] || (r && r.short) || id);
	  }
  const MONTH_EN = { 1: "January", 2: "February", 3: "March", 4: "April", 5: "May", 6: "June", 7: "July", 8: "August", 9: "September", 10: "October", 11: "November", 12: "December" };
  function monthText(value) {
    const match = String(value || "").match(/^(\d{4})\s*年\s*(\d{1,2})\s*月$/);
    return match ? MONTH_EN[Number(match[2])] + " " + match[1] : String(value || "");
  }
  function reportName(value) {
    const match = String(value || "").match(/^(\d{4})\s*年\s*(\d{1,2})\s*月\s*月度報告$/);
    return match ? MONTH_EN[Number(match[2])] + " " + match[1] + " monthly report" : String(value || "");
  }
  function reportRoleNote(value) {
    const text = String(value || "");
    let match = text.match(/^退回率\s*(\d+%)$/);
    if (match) return match[1] + " return rate";
    match = text.match(/^(\d{1,2})\s*月\s*(\d{1,2})\s*日起試用$/);
    if (match) return "Trial started " + MONTH_EN[Number(match[1])] + " " + match[2];
    match = text.match(/^(\d{1,2})\s*月\s*(\d{1,2})\s*日入職前試任務$/);
    if (match) return "Sample tasks before hiring on " + MONTH_EN[Number(match[1])] + " " + match[2];
    return text;
  }
  function reportNote(value) {
    const text = String(value || "");
    if (text.indexOf("數字以批准紀錄為準") === 0) return "Figures use approved work: 201 approved · 64 edited · 14 returned · 10 repeat tasks.";
    if (text.indexOf("估算工時以每項任務") === 0) return "Hours use task estimates. Change the hourly rate in Settings.";
    return text;
  }
  function taskNameFromRaw(office, roleId, value) {
    const role = office.roleById[roleId];
    const skill = role && (role.skills || []).find((item) => item.name === value || item.id === value);
    return skill && window.skillCopy ? window.skillCopy(roleId, skill, "name") : String(value || "");
  }
  window.Screens = window.Screens || {};

  function ReportPreviewModal({ ctx, onClose }) {
    const rp = ctx.office.kpi.reportPreview;
    const displayMonth = monthText(rp.month);
    const a = rp.approvals; const totalBar = (a.approved + a.edited + a.rejected) || 1;
    const canExport = ctx.can("export");
    function reportMarkdown() {
      const lines = [
        "# Emplix monthly report - " + displayMonth,
        "",
        "## Headline",
        "- Tasks: " + rp.headline.tasks,
        "- Hours saved: " + rp.headline.hours,
        "- Estimated saving: HK$" + rp.headline.cost.toLocaleString(),
        "",
        "## Approval breakdown",
        "- Approved: " + a.approved,
        "- Edited: " + a.edited,
        "- Rejected: " + a.rejected,
        "",
        "## Per role",
      ];
      rp.perRole.forEach((r) => lines.push("- " + shortEN(ctx.office, r.role) + ": " + r.tasks + " tasks - " + reportRoleNote(r.note)));
      lines.push("", "## Notes");
      rp.notes.forEach((n) => lines.push("- " + reportNote(n)));
      return lines.join("\n") + "\n";
    }
    return h(Modal, { title: h("span", null, h("span", null, displayMonth), " monthly report · preview"), sub: "Figures come from approved work and are estimates.", width: 620, onClose, "data-roi-modal": "report-preview",
      footer: [
        h(Button, { key: "dl", variant: "primary", icon: "download", disabled: !canExport, title: canExport ? "" : ctx.denyReason("export"), "data-roi-action": "download-report-preview", onClick: () => ctx.downloadText("emplix-monthly-report-" + rp.month + ".md", reportMarkdown(), "text/markdown;charset=utf-8", "Monthly report preview", rp.headline.tasks + " tasks") }, "Download preview"),
        h(Button, { key: "c", "data-roi-action": "close-report-preview", onClick: onClose }, "Close"),
      ] },
      h("div", { className: "row", style: { gap: 12, marginBottom: 16 } },
        [["Tasks", "" + rp.headline.tasks], ["Hours saved", rp.headline.hours + " hrs"], ["Estimated saving", "HK$" + rp.headline.cost.toLocaleString()]].map((x, i) =>
          h("div", { key: i, style: { flex: 1, textAlign: "center" } }, h("div", { className: "mono", style: { fontSize: 21, fontWeight: 700 } }, x[1]), h("div", { style: { fontSize: 12, color: "var(--text-dim)", marginTop: 3 } }, x[0])))),
      h("b", { style: { fontSize: 12.5 } }, "Approval breakdown"),
      h(Seg3, { ok: Math.round(a.approved / totalBar * 100), ed: Math.round(a.edited / totalBar * 100), bk: Math.round(a.rejected / totalBar * 100) }),
      rp.perRole.map((r, i) => { const role = ctx.office.roleById[r.role];
        return h("div", { key: i, className: "row gap8", style: { padding: "8px 0", borderBottom: "1px solid var(--border)", fontSize: 13.5 } },
          h(window.Face, { role: role, size: 20, variant: "head" }), h("b", null, role ? shortEN(ctx.office, r.role) : r.role), h("span", null, h("span", null, r.tasks + " tasks")), h("span", { className: "grow" }), h("span", { style: { fontSize: 12.5, color: "var(--text-faint)" } }, reportRoleNote(r.note))); }),
      h("div", { style: { marginTop: 12 } }, rp.notes.map((n, i) => h("p", { key: i, style: { fontSize: 12, lineHeight: 1.6, margin: "0 0 6px", color: "var(--text-faint)" } }, reportNote(n)))));
  }

	  function ROI({ ctx }) {
	    const office = ctx.office; const k = office.kpi;
	    const D = window.deriveDashboardData(office); const R = D.roi;   // folded roiExtra/hoursByDept/expansion (PC-7)
	    const [preview, setPreview] = useState(false);
	    const isUsageView = ctx.pageArg === "usage";
	    const projections = D.expansion || [];
	    const selectedProjection = !isUsageView && ctx.pageArg ? projections.find((x) => x.id === ctx.pageArg) : null;
	    const openedProjections = office.expansionRequests || [];
	    const selectedRequest = selectedProjection ? openedProjections.find((r) => r.projectionId === selectedProjection.id) : null;
		    const relatedArea = selectedProjection ? ({ "admin": "clerk", "customer-support": "cs", "sales": "sales", "accounting": "acct" }[selectedProjection.id] || selectedProjection.id) : null;
		    const selectedWorkOrderId = selectedRequest && selectedRequest.workOrderId;
	    const latestOpened = openedProjections.slice(0, 4);
	    useEffect(() => {
	      if (!ctx.pageArg || isUsageView) return;
	      const t = window.setTimeout(() => {
	        const el = document.getElementById("roi-projection-" + ctx.pageArg);
	        if (el && el.scrollIntoView) el.scrollIntoView({ block: "center", behavior: "smooth" });
	      }, 80);
	      return () => window.clearTimeout(t);
	    }, [ctx.pageArg, isUsageView]);
	    const hasTrial = !!k.trial;                     // GUARD: day0/reset has none
	    const hasPreview = !!k.reportPreview;           // GUARD
	    const reports = k.reports || [];                // GUARD: day0 reports:[]
	    function legend(color, label) { return h("span", { className: "row gap6", style: { fontSize: 11.5, color: "var(--text-dim)" } }, h("span", { style: { width: 9, height: 9, borderRadius: 3, background: color } }), label); }
	    function projectionMetric(label, value, tone) {
	      return h("div", { style: { padding: 12, borderRadius: 12, background: "var(--bg-3)", border: "1px solid var(--border)" } },
	        h("div", { className: "mono", style: { fontSize: 18, fontWeight: 750, color: tone || "var(--text)" } }, value || "—"),
	        h("div", { style: { fontSize: 11.5, color: "var(--text-faint)", marginTop: 4 } }, label));
	    }
	    function projectionRow(x) {
	      const isActive = selectedProjection && selectedProjection.id === x.id;
	      const opened = openedProjections.find((r) => r.projectionId === x.id);
	      return h("div", {
	        key: x.id,
	        id: "roi-projection-" + x.id,
	        "data-roi-action": "open-projection",
	        "data-roi-projection-id": x.id,
	        "data-roi-projection-active": isActive ? "true" : "false",
	        "data-roi-projection-opened": opened ? "true" : "false",
	        "data-roi-selected": isActive ? "true" : "false",
	        "data-roi-request-opened": opened ? "true" : "false",
	        "data-roi-projection-confidence": x.conf || "",
	        "data-roi-projection-route": "roi",
	        "data-roi-projection-keyboard": "true",
	        role: "button",
	        tabIndex: 0,
	        "aria-label": "Open value estimate " + (x.name || x.id),
	        className: "glass-hover" + (isActive ? " onboard-hl" : ""),
	        onClick: () => ctx.openExpansionProjection ? ctx.openExpansionProjection(x) : ctx.openPage("roi", x.id),
	        onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); ctx.openExpansionProjection ? ctx.openExpansionProjection(x) : ctx.openPage("roi", x.id); } },
	        style: { padding: "13px 14px", borderRadius: 12, border: isActive ? "1px solid var(--border-glow)" : "1px solid var(--border)", background: isActive ? "var(--blue-soft)" : "var(--bg-3)", cursor: "pointer" }
	      },
	        h("div", { className: "row between", style: { marginBottom: 4 } },
	          h("div", { className: "row gap8" },
	            h("span", { style: { width: 8, height: 8, borderRadius: 3, background: x.color } }),
	            h("span", { style: { fontWeight: 600, fontSize: 13.5 } }, x.name)),
	          h("span", { style: { fontFamily: "var(--mono)", fontWeight: 700, fontSize: 13, color: "var(--green)" } }, x.lift)),
	        h("div", { className: "row between", style: { gap: 10 } },
	          h("span", { style: { fontSize: 12, color: "var(--text-faint)" } }, x.note),
	          h("div", { className: "row gap6", style: { flex: "none" } },
	            opened && h(Chip, { tone: "blue" }, "Opened"),
	            h(Chip, { tone: x.conf === "High" ? "green" : "amber" }, "Ready", " ", h("span", null, x.conf)))));
	    }
		    function recentProjectionRow(r) {
		      return h("div", { key: r.id, className: "row between glass-hover", "data-roi-action": "open-recent-projection", "data-roi-request-id": r.id, "data-roi-request-projection-id": r.projectionId || "", "data-roi-request-workorder-id": r.workOrderId || "", "data-roi-request-route": "roi", "data-roi-request-keyboard": "true", role: "button", tabIndex: 0, "aria-label": "Open recent estimate " + (r.name || r.projectionId || r.id), onClick: () => ctx.openPage("roi", r.projectionId), onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); ctx.openPage("roi", r.projectionId); } }, style: { padding: "10px 12px", borderRadius: 11, border: "1px solid var(--border)", background: "var(--bg-3)", cursor: "pointer" } },
		        h("div", null,
		          h("div", { style: { fontWeight: 650, fontSize: 13 } }, r.name),
		          h("div", { style: { color: "var(--text-faint)", fontSize: 11.5 } }, r.openedAt + " · " + r.openedBy)),
		        h("div", { className: "row gap8" },
		          r.workOrderId && h(Chip, { tone: "blue" }, r.workOrderId),
		          h("span", { className: "mono", style: { color: "var(--green)", fontWeight: 750, fontSize: 13 } }, r.lift || "—"),
		          h(Chip, { tone: r.confidence === "High" ? "green" : "amber" }, r.confidence || "Review")));
	    }
	    if (isUsageView) return h(window.UsageCosts, { ctx });
	    return h("div", { "data-roi-screen": "true", "data-roi-view": "value", "data-roi-selected-projection-id": selectedProjection ? selectedProjection.id : "", "data-roi-opened-count": String(openedProjections.length), "data-roi-projection-count": String(projections.length) },
      h(PageHeader, { eyebrow: "Outcomes", title: h("span", null, "Value — ", h("span", null, monthText(k.month))),
	        sub: "Monthly tasks, time saved, value, and approvals.",
        right: h("div", { className: "row gap10 wrap" },
          h(window.RoiViewSwitch, { ctx, active: "value" }),
          hasPreview && h(Button, { "data-roi-action": "preview-report", onClick: () => setPreview(true) }, "Preview last month's report")) }),
	      h("div", { className: "kpi-grid" },
	        h(Card, { className: "kpi" }, h("div", { className: "kpi-v" }, k.tasksDone), h("div", { className: "kpi-l" }, "Tasks completed this month"), k.tasksDone > 0 && h("div", { className: "kpi-s up row gap4" }, h(Icon, { name: "trendUp", size: 13 }), h("span", null, "12% vs last month"))),
	        h(Card, { className: "kpi" }, h("div", { className: "kpi-v" }, h("span", null, k.hoursSaved + " hrs")), h("div", { className: "kpi-l" }, "Estimated hours saved"), h("div", { className: "kpi-s" }, "Counted on approved tasks")),
		        h(Card, { className: "kpi" }, h("div", { className: "kpi-v" }, h("span", null, "HK$" + k.costSaved.toLocaleString())), h("div", { className: "kpi-l" }, "Estimated cost saved"), h("div", { className: "kpi-s" }, h("span", null, "Based on HK$" + k.hourRate + " per hour. Change it in Settings."))),
		        h(Card, { className: "kpi", "data-roi-action": "open-approvals", onClick: () => ctx.openPage("approvals"), style: { cursor: "pointer" } }, h("div", { className: "kpi-v", style: { color: "var(--red)" } }, office.inbox.length), h("div", { className: "kpi-l" }, "Awaiting your approval"), h("div", { className: "kpi-s" }, "Open My Desk"))),
	      selectedProjection && h(Card, { style: { padding: 18, margin: "0 0 16px", borderColor: selectedProjection.color || "var(--border-glow)", boxShadow: "0 14px 40px rgba(47,127,224,.08)" } },
	        h("div", { className: "row between wrap", style: { gap: 12, marginBottom: 14 } },
	          h("div", null,
	            h("div", { className: "eyebrow", style: { marginBottom: 6 } }, "Opened estimate"),
	            h("h2", { style: { margin: 0, fontSize: 22, letterSpacing: 0 } }, selectedProjection.name + " value estimate"),
	            h("p", { style: { margin: "7px 0 0", color: "var(--text-dim)", fontSize: 13.5, lineHeight: 1.5 } }, selectedProjection.note)),
	          h("div", { className: "row gap8 wrap", style: { justifyContent: "flex-end" } },
	            h(Badge, { tone: selectedProjection.conf === "High" ? "green" : "amber", dot: true }, "Ready: " + selectedProjection.conf),
		            h(Badge, { tone: selectedWorkOrderId ? "green" : selectedRequest ? "blue" : "neutral" }, selectedWorkOrderId ? ("Task " + selectedWorkOrderId) : selectedRequest ? "Saved" : "Preview"))),
	        h("div", { style: { display: "grid", gridTemplateColumns: "repeat(3, minmax(0, 1fr))", gap: 10, marginBottom: 12 } },
	          projectionMetric("Estimated weekly value", selectedProjection.lift, "var(--green)"),
	          projectionMetric("Ready", selectedProjection.conf, selectedProjection.conf === "High" ? "var(--green)" : "var(--amber)"),
	          projectionMetric("Opened by", selectedRequest ? selectedRequest.openedBy : "Link", "var(--blue)")),
	        h("div", { className: "row between wrap", style: { gap: 10, paddingTop: 10, borderTop: "1px solid var(--border)" } },
	          h("div", { style: { fontSize: 12.5, color: "var(--text-faint)" } },
	            selectedRequest ? ("Estimate opened " + selectedRequest.openedAt + " · history record " + selectedRequest.id) : "Open this from Overview to save it in History."),
	          h("div", { className: "row gap8 wrap", style: { justifyContent: "flex-end" } },
		            relatedArea && h(Button, { sm: true, variant: "ghost", "data-roi-action": "open-related-skills", "data-roi-related-area": relatedArea, onClick: () => ctx.openPage("training", relatedArea) }, "Open related tasks"),
		            h(Button, { sm: true, variant: "primary", iconRight: "arrowRight", disabled: !ctx.can("workOrder"), title: ctx.can("workOrder") ? "" : ctx.denyReason("workOrder"),
		              "data-roi-action": selectedWorkOrderId ? "open-workorder" : "create-workorder",
		              "data-roi-projection-id": selectedProjection.id,
		              "data-roi-workorder-id": selectedWorkOrderId || "",
		              onClick: () => ctx.createRoiExpansionWorkOrder ? ctx.createRoiExpansionWorkOrder(selectedProjection.id) : ctx.openPage("workorders") }, selectedWorkOrderId ? "Open task" : "Create task")))),
      (hasTrial || reports.length > 0) && h("div", { className: "two-col" },
        hasTrial && h(Card, { style: { padding: 18 } }, h("b", null, "Trial report · Sales Assistant"),
          h("div", { className: "trial-row" }, h(Chip, { tone: "gray" }, "Day 7"), h("p", null, h("span", null, "Completed " + k.trial.day7.tasks + " tasks · saved ~" + k.trial.day7.hours + " hrs · top: " + taskNameFromRaw(office, k.trial.role, k.trial.day7.top)))),
          h("div", { className: "trial-row" }, h(Chip, { tone: "purple" }, "Day 14"), h("p", null, h("span", null, "Completed " + k.trial.day14.tasks + " tasks · saved ~" + k.trial.day14.hours + " hrs"))),
	          h("div", { className: "rule-banner", style: { marginTop: 10 } }, "Review the time estimate before keeping this employee.")),
        reports.length > 0 && h(Card, { style: { padding: 18 } }, h("b", null, "Monthly reports"),
          reports.map((r, i) => h("div", { key: i, className: "row gap10", style: { padding: "10px 0", borderBottom: "1px solid var(--border)" } },
            h(InlineIcon, { name: "file" }), h("b", { className: "grow", style: { fontSize: 13.5 } }, reportName(r.name)),
            (r.status === "ready" || ctx.day === "monthend") && hasPreview
              ? h(Button, { sm: true, icon: "download", "data-roi-action": "preview-report", "data-roi-report-name": r.name || "", onClick: () => setPreview(true) }, "Preview PDF")
              : h(Chip, { tone: "gray" }, "Auto-generated at month-end"))),
          h("p", { style: { fontSize: 12.5, marginTop: 10, color: "var(--text-faint)" } }, "Reports can be shared. Figures come from approved work and are estimates."))),

      // ===== PC-7: folded ROI analytics — roiExtra / hoursByDept / expansion rendered here so they are not dead =====
      h("div", { style: { display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 14, margin: "18px 0 14px" } },
        [["Net value estimate", "HK$" + (R.netRoi || 0).toLocaleString(), "green", "this month"], ["Value multiple", (R.roiMultiple || 0) + "×", "violet", "estimated return"], ["Time to cover cost", R.payback || "—", "amber", "since the trial started"]].map((m, i) =>
          h(Card, { key: i, style: { padding: 16 } },
            h("div", { className: "mono", style: { fontSize: 23, fontWeight: 700, color: "var(--" + m[2] + ")" } }, m[1]),
            h("div", { style: { fontSize: 12, color: "var(--text-dim)", marginTop: 5, fontWeight: 500 } }, m[0]),
            h("div", { style: { fontSize: 11, color: "var(--text-faint)", marginTop: 3 } }, m[3])))),
	      R.costVsCost && h(Card, { style: { marginBottom: 16 } },
	          h(CardHead, { title: "Value estimate vs. operating cost", sub: "6 months · HK$ thousands", icon: "dollar",
	            right: h("div", { className: "row gap12" }, legend("var(--green)", "Savings"), legend("var(--blue)", "Cost")) }),
	          h("div", { style: { padding: "16px 18px 6px" } },
	            h(window.MultiLine, { labels: R.costVsCost.labels, format: (v) => "HK$" + v + "k", height: 230,
	              series: [{ data: R.costVsCost.saved, color: "#12a877" }, { data: R.costVsCost.cost, color: "#2f7fe0" }] }))),
      R.approvalTrend && h("div", { style: { display: "grid", gridTemplateColumns: "1fr 1.3fr", gap: 16, marginBottom: 16 } },
        h(Card, null,
          h(CardHead, { title: "Approvals over time", sub: "Approvals needed each week", icon: "trending", right: h(Badge, { tone: "green" }, h(Icon, { name: "trendDown", size: 11 }), h("span", null, "44%")) }),
          h("div", { style: { padding: "16px 18px 6px" } },
            h(window.AreaChart, { data: R.approvalTrend.data, labels: R.approvalTrend.labels, height: 210, color: "#6f5be6", yTicks: 4 })),
	          h("div", { style: { padding: "0 18px 18px", fontSize: 12.5, color: "var(--text-dim)" } }, "Proven low-risk tasks can repeat after a short undo wait.")),
        (R.topByRoi && R.topByRoi.length > 0) && h(Card, null,
          h(CardHead, { title: "Value by employee", icon: "users" }),
          h("div", { style: { padding: 14, display: "flex", flexDirection: "column", gap: 6 } },
            R.topByRoi.map((t, i) => { const role = office.roleById[t.id];
              return h("div", { key: t.id, className: "row between glass-hover", "data-roi-action": "open-top-role", "data-roi-top-role-id": t.id, "data-roi-top-role-rank": String(i + 1), "data-roi-top-role-route": "employees", "data-roi-top-role-keyboard": "true", role: "button", tabIndex: 0, "aria-label": "Open Employees for " + shortEN(office, t.id), onClick: () => ctx.openPage("employees"), onKeyDown: (e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); ctx.openPage("employees"); } }, style: { padding: "10px 12px", borderRadius: 11, background: "var(--bg-3)", border: "1px solid var(--border)", cursor: "pointer" } },
                h("div", { className: "row gap10" }, h("span", { className: "mono", style: { fontSize: 12, color: "var(--text-faint)", width: 16 } }, "#" + (i + 1)), h(window.Face, { role: role, size: 22, variant: "head" }),
                  h("div", null, h("div", { style: { fontSize: 13, fontWeight: 600 } }, shortEN(office, t.id)), h("div", { style: { fontSize: 11.5, color: "var(--text-faint)" } }, t.future))),
                h("div", { style: { textAlign: "right", whiteSpace: "nowrap" } }, h("div", { className: "mono", style: { fontWeight: 700, fontSize: 14, color: "var(--green)" } }, t.roi), h("div", { style: { fontSize: 11, color: "var(--text-faint)" } }, t.multiple + " return"))); })))),
	      projections.length > 0 && h("div", { style: { marginBottom: 16 } },
	        h(Card, null,
	          h(CardHead, { title: "Possible next steps", sub: "Estimated weekly value", icon: "sparkle" }),
	          h("div", { style: { padding: 14, display: "flex", flexDirection: "column", gap: 10 } },
	            projections.map(projectionRow))),
	        latestOpened.length > 0 && h(Card, { style: { marginTop: 12 } },
	          h(CardHead, { title: "Recently opened estimates", sub: "Saved in this sample demo", icon: "clock" }),
	          h("div", { style: { padding: 14, display: "flex", flexDirection: "column", gap: 8 } },
	            latestOpened.map(recentProjectionRow)))),

      preview && hasPreview && h(ReportPreviewModal, { ctx, onClose: () => setPreview(false) }));
  }

  window.Screens.roi = ROI;
})();
