"use client";
import { jsx as _jsx } from "react/jsx-runtime";
import { memo, useMemo } from "react";
import { cn } from "@stigmer/theme";
import { useRenderTracer } from "../internal/dev/index.js";
import { ToolCallItem } from "./ToolCallItem.js";
import { ToolRunGroup } from "./ToolRunGroup.js";
import { segmentToolCalls } from "./segment-tool-calls.js";
import { isCollapsedToolCall } from "./tool-categories.js";
/**
 * Shallow comparison for `ToolCallGroupProps`.
 *
 * The `toolCalls` array may be a newly allocated subset (e.g.
 * `buildThreadItems` filters out `task` calls). Structural sharing
 * (T04) keeps individual `ToolCall` objects stable, so we compare
 * array elements by reference rather than the array itself.
 *
 * @internal Exported for testing — not part of the public API.
 */
export function toolCallGroupPropsEqual(prev, next) {
    if (prev.toolCalls.length !== next.toolCalls.length)
        return false;
    for (let i = 0; i < prev.toolCalls.length; i++) {
        if (prev.toolCalls[i] !== next.toolCalls[i])
            return false;
    }
    return (prev.subAgentExecutions === next.subAgentExecutions &&
        prev.formatSummary === next.formatSummary &&
        prev.defaultExpanded === next.defaultExpanded &&
        prev.className === next.className);
}
/**
 * Renders one AI turn's tool activity as a **persistent-row timeline** rather
 * than a collapsible "Ran N tools" box. Each call stays visible after it
 * settles, so completed work is never hidden behind a pill — the thread reads
 * like a virtual human at work.
 *
 * The turn is segmented by {@link segmentToolCalls}:
 * - high-signal calls (edits, shell, MCP, sub-agents, …) render as persistent
 *   {@link ToolCallItem} rows; a content-bearing call shows its body inline
 *   (no card chevron), bounded by a single in-place reveal;
 * - runs of consecutive low-signal same-category calls (read / list / search)
 *   fold into one collapsible {@link ToolRunGroup} chip — the *only* collapse,
 *   because that is the only genuine noise.
 *
 * The rows are clustered under a light left rail (the neutral counterpart to
 * {@link SubAgentSection}'s primary-tinted rail for delegated work), keeping a
 * turn's tools visually associated with their AI message without a tab that
 * hides things.
 *
 * Wrapped in `React.memo` with a custom comparator that checks `toolCalls`
 * elements by reference (structural sharing keeps individual `ToolCall` objects
 * stable for unchanged calls), so settled rows skip re-renders while siblings
 * stream (DD-009/010).
 *
 * @example
 * ```tsx
 * <ToolCallGroup toolCalls={message.toolCalls} />
 * ```
 */
export const ToolCallGroup = memo(function ToolCallGroup({ toolCalls, subAgentExecutions, formatSummary, className, }) {
    useRenderTracer("ToolCallGroup", { toolCallCount: toolCalls.length });
    // Drop runner-collapsed duplicates (a superseded same-turn denial twin of an
    // approval gate) so one gated resource renders one card, not two. The blanked
    // twin is kept in the persisted transcript (the backend's append-only guard
    // forbids dropping it); it is simply not drawn.
    const visibleToolCalls = useMemo(() => toolCalls.filter((tc) => !isCollapsedToolCall(tc)), [toolCalls]);
    const segments = useMemo(() => segmentToolCalls(visibleToolCalls), [visibleToolCalls]);
    const subAgentMap = useMemo(() => {
        if (!subAgentExecutions || subAgentExecutions.length === 0)
            return null;
        const map = new Map();
        for (const sub of subAgentExecutions) {
            map.set(sub.id, sub);
        }
        return map;
    }, [subAgentExecutions]);
    if (visibleToolCalls.length === 0)
        return null;
    const ariaLabel = `${visibleToolCalls.length} tool ${visibleToolCalls.length === 1 ? "call" : "calls"}`;
    return (_jsx("div", { role: "group", "aria-label": ariaLabel, "data-cursor-target": "tool-call-group", className: cn(
        // Cursor-style: each tool call (and folded run chip) is its own
        // self-contained card; the turn's tools stack with a small gap between
        // them rather than sharing a left rail, so the thread reads as a column
        // of discrete cards.
        "flex flex-col gap-2", className), children: segments.map((segment) => segment.kind === "run" ? (_jsx(ToolRunGroup, { category: segment.category, toolCalls: segment.toolCalls, formatLabel: formatSummary }, segment.key)) : (_jsx(ToolCallItem, { toolCall: segment.toolCall, subAgentExecution: subAgentMap?.get(segment.toolCall.id) ?? null }, segment.key))) }));
}, toolCallGroupPropsEqual);
//# sourceMappingURL=ToolCallGroup.js.map