"use client";
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import Markdown from "react-markdown";
import { cn } from "@stigmer/theme";
import { MARKDOWN_COMPONENTS, REMARK_PLUGINS } from "../internal/markdown-components.js";
import { DecisionButton } from "../internal/DecisionButton.js";
import { InCardDecisionError } from "../internal/InCardDecisionError.js";
const DEFAULT_OUTCOMES = [
    { name: "approve", label: "Approve" },
    { name: "reject", label: "Reject" },
];
/**
 * Interactive approval card for workflow-level human_input tasks.
 *
 * Renders dynamic outcome buttons (from workflow configuration),
 * optional form fields (from JSON Schema), and a comment textarea.
 * Designed for inline rendering in the execution timeline when a
 * human_input task is in `waiting_approval` state.
 *
 * Distinct from `WorkflowExecutionApprovalCard` (which handles agent
 * tool approvals with `toolCallId` + `ApprovalAction`). This component
 * uses `taskName` + `outcome` string + optional `formData`.
 *
 * Follows SDK component standards:
 * - All colors via `--stgm-*` tokens (DD-005)
 * - Keyboard navigable with ARIA labels (a11y)
 * - `React.memo` for referential stability (DD-010)
 * - Zero framework dependencies (DD-004)
 *
 * @example
 * ```tsx
 * <WorkflowTaskApprovalCard
 *   taskName="daily_approval"
 *   prompt="Review today's notification plan.\n\n**DAU**: 7,297 (down 15%)"
 *   outcomes={[{ name: "approve", label: "Approve Plan" }, { name: "reject", label: "Reject" }]}
 *   formSchema={{ type: "object", properties: { feedback: { type: "string" } } }}
 *   onSubmit={actions.submitTaskApproval}
 *   isSubmitting={actions.isSubmitting}
 * />
 * ```
 */
export const WorkflowTaskApprovalCard = memo(function WorkflowTaskApprovalCard({ taskName, prompt, outcomes: outcomesProp, formSchema, onSubmit, isSubmitting, error, className, }) {
    const outcomes = outcomesProp.length > 0 ? outcomesProp : DEFAULT_OUTCOMES;
    const [activeOutcome, setActiveOutcome] = useState(null);
    const [comment, setComment] = useState("");
    const [formData, setFormData] = useState({});
    const formFields = useMemo(() => extractFormFields(formSchema), [formSchema]);
    useEffect(() => {
        if (!isSubmitting) {
            setActiveOutcome(null);
        }
    }, [isSubmitting]);
    const handleFieldChange = useCallback((fieldName, value) => {
        setFormData((prev) => ({ ...prev, [fieldName]: value }));
    }, []);
    const handleSubmit = useCallback((outcomeName) => {
        setActiveOutcome(outcomeName);
        const data = formFields.length > 0
            ? Object.fromEntries(Object.entries(formData).filter(([, v]) => v.trim() !== ""))
            : undefined;
        onSubmit(taskName, outcomeName, data && Object.keys(data).length > 0 ? data : undefined, comment.trim() || undefined);
    }, [taskName, formData, comment, formFields.length, onSubmit]);
    return (_jsxs("div", { role: "form", "aria-label": `Approval decision for ${taskName}`, "aria-busy": isSubmitting, 
        // Neutral card + 2px warning left accent — the quiet Cursor-grade chrome
        // shared with ApprovalCard. (Replaces the old amber `bg-warning/5` fill.)
        className: cn("mt-2 rounded-lg border border-border-prominent border-l-2 border-l-warning p-3", className), children: [prompt && (_jsx("div", { className: "mb-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 }) }) })), formFields.length > 0 && (_jsx("div", { className: "mb-3 space-y-2", children: formFields.map((field) => (_jsxs("div", { children: [_jsx("label", { htmlFor: `${taskName}-${field.name}`, className: "mb-1 block text-xs font-medium text-foreground", children: field.label }), _jsx("textarea", { id: `${taskName}-${field.name}`, value: formData[field.name] ?? "", onChange: (e) => handleFieldChange(field.name, e.target.value), placeholder: field.description, disabled: isSubmitting, rows: 2, className: cn("w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground", "placeholder:text-muted-foreground", "focus:outline-none focus:ring-1 focus:ring-ring", "disabled:opacity-50", "resize-y") })] }, field.name))) })), _jsx("div", { className: "mb-2", children: _jsx("textarea", { value: comment, onChange: (e) => setComment(e.target.value), placeholder: "Comment (optional)", disabled: isSubmitting, rows: 1, className: cn("w-full rounded border border-border bg-background px-2 py-1.5 text-xs text-foreground", "placeholder:text-muted-foreground", "focus:outline-none focus:ring-1 focus:ring-ring", "disabled:opacity-50", "resize-y") }) }), _jsx("div", { className: "flex flex-wrap gap-2", children: outcomes.map((outcome, index) => (_jsx(DecisionButton, { label: outcome.label || capitalize(outcome.name), variant: resolveVariant(outcome.name, index, outcomes.length), onClick: () => handleSubmit(outcome.name), isActive: activeOutcome === outcome.name, isSubmitting: isSubmitting }, outcome.name))) }), error && (_jsx("div", { className: "mt-2", children: _jsx(InCardDecisionError, { error: error, leadIn: "submit decision", cursorTarget: "wf-task-approval-error" }) }))] }));
});
function extractFormFields(schema) {
    if (!schema || typeof schema !== "object")
        return [];
    const properties = schema.properties;
    if (!properties || typeof properties !== "object")
        return [];
    return Object.entries(properties).map(([name, prop]) => ({
        name,
        label: capitalize(name.replace(/_/g, " ")),
        description: (typeof prop?.description === "string" ? prop.description : ""),
    }));
}
function resolveVariant(outcomeName, index, total) {
    // The first outcome is the recommended action (the quiet neutral chip).
    if (index === 0)
        return "primary";
    const lower = outcomeName.toLowerCase();
    if (lower === "reject" || lower === "deny" || lower.includes("reject")) {
        return "danger";
    }
    // In a simple two-outcome form, the trailing outcome is the negative one.
    if (index === total - 1 && total === 2) {
        return "danger";
    }
    return "ghost";
}
function capitalize(s) {
    return s.charAt(0).toUpperCase() + s.slice(1);
}
//# sourceMappingURL=WorkflowTaskApprovalCard.js.map