"use client";
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { memo, useMemo } from "react";
import Markdown from "react-markdown";
import { cn } from "@stigmer/theme";
import { MARKDOWN_COMPONENTS, REMARK_PLUGINS } from "../internal/markdown-components.js";
import { formatDuration, formatTimestamp } from "./format-utils.js";
/**
 * Read-only decision report for a resolved workflow human_input gate.
 *
 * Renders the prompt, the chosen outcome, the reviewer and timing, and any
 * comment or form answers captured with the decision — sourced entirely
 * from the canonical task-output record (see `derive-task-detail`). This is
 * the resolved counterpart to {@link WorkflowTaskApprovalCard}: the card
 * collects a decision while a gate is `waiting_approval`; this component
 * presents the decision once it is made, so the Approval tab never offers
 * an already-answered gate for a second decision.
 *
 * Designed for embedding in both the Stigmer Console and third-party
 * dashboards — no routing, auth, or app-shell dependencies (DD-004). All
 * visual properties flow through `--stgm-*` tokens (DD-005).
 *
 * @example
 * ```tsx
 * <WorkflowTaskApprovalSummary
 *   taskName="team_lead_review"
 *   prompt="Review today's notification plan."
 *   outcomes={[{ name: "approve", label: "Approve Plan" }]}
 *   decision={detail.approval.decision}
 * />
 * ```
 */
export const WorkflowTaskApprovalSummary = memo(function WorkflowTaskApprovalSummary({ taskName, prompt, outcomes, decision, className, }) {
    const isFinalizing = !decision || decision.outcome === "";
    const outcomeLabel = useMemo(() => {
        if (!decision || !decision.outcome)
            return "";
        const match = outcomes.find((o) => o.name === decision.outcome);
        return match?.label || capitalize(decision.outcome.replace(/_/g, " "));
    }, [decision, outcomes]);
    const tone = useMemo(() => (decision && !isFinalizing ? resolveTone(decision.outcome) : "neutral"), [decision, isFinalizing]);
    const formEntries = useMemo(() => extractFormEntries(decision?.formData ?? null), [decision]);
    return (_jsxs("div", { role: "group", "aria-label": `Approval decision for ${taskName}`, className: cn("mt-2 rounded-lg border border-border bg-muted-subtle p-3", className), children: [isFinalizing ? (_jsxs("div", { className: "flex items-center gap-2 text-xs text-muted-foreground", children: [_jsx(SpinnerIcon, {}), _jsx("span", { children: "Decision recorded \u2014 finalizing\u2026" })] })) : (_jsxs("div", { className: "flex flex-wrap items-center gap-x-2 gap-y-1", children: [_jsxs("span", { className: cn("inline-flex items-center gap-1.5 rounded-md px-2 py-1 text-xs font-medium", TONE_CLASSES[tone]), children: [_jsx(ToneIcon, { tone: tone }), outcomeLabel] }), decision.autoResolved && (_jsx("span", { className: "rounded bg-muted px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground", children: "auto-resolved" }))] })), !isFinalizing && (_jsxs("div", { className: "mt-1.5 flex flex-wrap items-center gap-x-1.5 text-[11px] text-muted-foreground", children: [decision.reviewer && (_jsxs("span", { children: ["by ", _jsx("span", { className: "font-medium text-foreground", children: decision.reviewer })] })), decision.respondedAt && (_jsxs(_Fragment, { children: [decision.reviewer && _jsx(Dot, {}), _jsx("span", { className: "tabular-nums", children: formatTimestamp(decision.respondedAt) })] })), decision.waitDurationMs > 0 && (_jsxs(_Fragment, { children: [(decision.reviewer || decision.respondedAt) && _jsx(Dot, {}), _jsxs("span", { className: "tabular-nums", children: ["waited ", formatDuration(decision.waitDurationMs)] })] }))] })), prompt && (_jsx("div", { className: "mt-3 max-h-80 overflow-y-auto rounded border border-border bg-background p-3", children: _jsx("div", { className: "stgm-prose", children: _jsx(Markdown, { components: MARKDOWN_COMPONENTS, remarkPlugins: REMARK_PLUGINS, children: prompt }) }) })), !isFinalizing && decision.comment && (_jsxs("div", { className: "mt-3", children: [_jsx("p", { className: "mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: "Comment" }), _jsx("p", { className: "whitespace-pre-wrap rounded border border-border bg-background p-2 text-xs text-foreground", children: decision.comment })] })), !isFinalizing && formEntries.length > 0 && (_jsx("dl", { className: "mt-3 space-y-2", children: formEntries.map((entry) => (_jsxs("div", { children: [_jsx("dt", { className: "mb-1 text-[11px] font-medium uppercase tracking-wide text-muted-foreground", children: entry.label }), _jsx("dd", { className: "whitespace-pre-wrap rounded border border-border bg-background p-2 text-xs text-foreground", children: entry.value })] }, entry.key))) }))] }));
});
const TONE_CLASSES = {
    approve: "bg-success-subtle text-success",
    reject: "bg-destructive-subtle text-destructive",
    neutral: "bg-muted text-foreground",
};
/**
 * Maps an outcome identifier to a visual tone. Reject/deny outcomes read
 * as destructive; approve/accept as success; everything else neutral.
 * Color is never the sole signal — the outcome label is always shown.
 */
function resolveTone(outcome) {
    const lower = outcome.toLowerCase();
    if (lower.includes("reject") || lower.includes("deny") || lower.includes("decline")) {
        return "reject";
    }
    if (lower.includes("approve") || lower.includes("accept") || lower === "yes") {
        return "approve";
    }
    return "neutral";
}
/** Flattens a form-data object into displayable label/value entries. */
function extractFormEntries(formData) {
    if (!formData)
        return [];
    return Object.entries(formData).map(([key, raw]) => ({
        key,
        label: capitalize(key.replace(/_/g, " ")),
        value: stringifyValue(raw),
    }));
}
function stringifyValue(value) {
    if (value === null || value === undefined)
        return "";
    if (typeof value === "string")
        return value;
    if (typeof value === "number" || typeof value === "boolean")
        return String(value);
    try {
        return JSON.stringify(value, null, 2);
    }
    catch {
        return String(value);
    }
}
function capitalize(s) {
    return s.length > 0 ? s.charAt(0).toUpperCase() + s.slice(1) : s;
}
// ---------------------------------------------------------------------------
// Inline SVG icons
// ---------------------------------------------------------------------------
function Dot() {
    return _jsx("span", { "aria-hidden": "true", children: "\u00B7" });
}
function ToneIcon({ tone }) {
    if (tone === "reject") {
        return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.75", "aria-hidden": "true", children: _jsx("path", { d: "M3 3l6 6M9 3l-6 6", strokeLinecap: "round" }) }));
    }
    if (tone === "approve") {
        return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.75", "aria-hidden": "true", children: _jsx("path", { d: "M2.5 6.5l2.5 2.5 4.5-5.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
    }
    return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.75", "aria-hidden": "true", children: _jsx("circle", { cx: "6", cy: "6", r: "4" }) }));
}
function SpinnerIcon() {
    return (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.5", className: "animate-spin", "aria-hidden": "true", children: _jsx("path", { d: "M6 1.5A4.5 4.5 0 1 1 1.5 6", strokeLinecap: "round" }) }));
}
//# sourceMappingURL=WorkflowTaskApprovalSummary.js.map