/**
 * ToolGroupComponent — groups concurrent tool calls into a single visual container.
 *
 * When a ToolDefinition provides `renderGroup`, the framework creates one of these
 * instead of adding individual ToolExecutionComponents to the chat. The group owns
 * the member components, delegates all rendering to `renderGroup`, and re-renders
 * whenever any member is updated.
 *
 * Each member ToolExecutionComponent is a child of the group (so the framework's
 * existing updateResult/setExpanded calls still work), but they render zero lines
 * individually — the group's Box renders the unified tree.
 */
import { Box, Container, Text } from '../../../tui/index.js';
import { PREFIX_WIDTH, prefixLines, toolPrefix } from '../../layout.js';
import { theme } from '../../theme/runtime.js';
import { getToolPresentation } from '../presentation/index.js';
import { ToolExecutionComponent } from './tool-execution.js';
/**
 * A Container that groups multiple tool calls and renders them as one unit.
 */
export class ToolGroupComponent extends Container {
    contentBox;
    members = [];
    toolDefinition;
    expanded = false;
    ui;
    isPending = true;
    hasError = false;
    blinkOn = true;
    blinkTimer;
    suppressOuterPrefix = false;
    constructor(toolDefinition, ui) {
        super();
        this.toolDefinition = toolDefinition;
        this.ui = ui;
        this.contentBox = new Box(0, 0);
        this.addChild(this.contentBox);
        this.blinkTimer = setInterval(() => {
            this.blinkOn = !this.blinkOn;
            ui.requestRender();
        }, 500);
        this.updateGroupDisplay();
    }
    /**
     * Add a new member tool call to the group.
     * Returns the ToolExecutionComponent (so interactive-mode can track it in pendingTools).
     */
    addMember(toolCallId, toolName, args, options, cwd) {
        const component = new ToolExecutionComponent(toolName, args, options, this.toolDefinition, this.ui, cwd);
        // Hide the individual component — the group renders everything
        component.setGrouped(true);
        component.setExpanded(this.expanded);
        // Listen for updates from this member
        component.onGroupUpdate = () => this.updateGroupDisplay();
        this.members.push({ toolCallId, component });
        // Add as child so Container.render includes it (but it renders 0 lines when grouped)
        this.addChild(component);
        this.updateGroupDisplay();
        return component;
    }
    /** True when any member is still waiting for a result. */
    hasPendingMembers() {
        return this.isPending;
    }
    setSuppressOuterPrefix(suppress) {
        this.suppressOuterPrefix = suppress;
    }
    render(width) {
        if (this.suppressOuterPrefix) {
            return super.render(width);
        }
        const prefix = toolPrefix(this.isPending, this.hasError, this.blinkOn);
        return prefixLines(super.render(width - PREFIX_WIDTH), prefix);
    }
    stopBlink() {
        if (this.blinkTimer) {
            clearInterval(this.blinkTimer);
            this.blinkTimer = undefined;
            this.blinkOn = true;
        }
    }
    dispose() {
        this.stopBlink();
        for (const member of this.members) {
            member.component.dispose();
        }
    }
    setExpanded(expanded) {
        this.expanded = expanded;
        for (const m of this.members) {
            m.component.setExpanded(expanded);
        }
        this.updateGroupDisplay();
    }
    /** Build member snapshots and call renderGroup */
    updateGroupDisplay() {
        const allDone = this.members.length > 0 && this.members.every((m) => !m.component.getIsPartial());
        this.hasError = this.members.some((m) => m.component.getResult()?.isError);
        this.isPending = !allDone && !this.hasError;
        if (!this.isPending) {
            this.stopBlink();
        }
        this.contentBox.clear();
        const presentation = getToolPresentation(this.toolDefinition);
        if (!presentation?.renderGroup) {
            // Shouldn't happen, but fallback
            this.contentBox.addChild(new Text(theme.fg('toolTitle', theme.bold(this.toolDefinition.name)), 0, 0));
            return;
        }
        const memberSnapshots = this.members.map((m) => ({
            toolCallId: m.toolCallId,
            args: m.component.getArgs(),
            result: m.component.getResult(),
            isPartial: m.component.getIsPartial()
        }));
        const component = presentation.renderGroup(memberSnapshots, { expanded: this.expanded }, theme);
        this.contentBox.addChild(component);
    }
}
//# sourceMappingURL=tool-group.js.map