import { storeAssistantMessage } from "./message-store.js";
const accumulators = new Map();
function getAccumulator(runId) {
    return accumulators.get(runId);
}
export function createAccumulator(runId, deviceId, sessionKey) {
    accumulators.set(runId, {
        runId,
        deviceId: deviceId.toUpperCase(),
        sessionKey,
        deliverText: "",
        thinkingEvents: [],
        toolCalls: [],
        lifecyclePhase: null,
        pendingToolCalls: new Map(),
    });
}
export function feedDeliver(runId, text, _kind) {
    const acc = getAccumulator(runId);
    if (!acc)
        return;
    // Final text replaces; partial accumulates
    if (text)
        acc.deliverText = text;
}
export function feedThinking(runId, data) {
    const acc = getAccumulator(runId);
    if (!acc)
        return;
    const delta = typeof data.delta === "string" && data.delta ? data.delta : (typeof data.text === "string" ? data.text : "");
    if (!delta)
        return;
    if (acc.thinkingEvents.length > 0 &&
        acc.thinkingEvents[acc.thinkingEvents.length - 1].kind === "thinking") {
        // Append to the last thinking event
        const last = acc.thinkingEvents[acc.thinkingEvents.length - 1];
        last.thinkingText = (last.thinkingText ?? "") + delta;
    }
    else {
        acc.thinkingEvents.push({ kind: "thinking", thinkingText: delta });
    }
}
export function feedToolHook(runId, event) {
    const acc = getAccumulator(runId);
    if (!acc)
        return;
    const name = event.toolName ?? "unknown";
    const toolCallId = event.toolCallId ?? `${name}_${Date.now()}`;
    if (event.when === "before") {
        const displayLabel = typeof event.params === "object" && event.params !== null
            ? extractDisplayLabel(event.params)
            : undefined;
        acc.pendingToolCalls.set(toolCallId, {
            name,
            startTs: Date.now(),
            displayLabel,
            displayEmoji: event.displayEmoji,
        });
        // Add thought event
        acc.thinkingEvents.push({
            kind: "toolCall",
            toolName: name,
            toolCallId,
            phase: "running",
            startTs: Date.now(),
            displayLabel: displayLabel ?? event.displayLabel,
            displayEmoji: event.displayEmoji,
        });
        // Add tool call entry
        acc.toolCalls.push({
            id: toolCallId,
            name,
            phase: "running",
            displayLabel: displayLabel ?? event.displayLabel,
            displayEmoji: event.displayEmoji,
            toolCallId,
            startTs: Date.now(),
        });
    }
    else {
        // after
        const pending = acc.pendingToolCalls.get(toolCallId);
        const durationMs = event.durationMs ?? (pending ? Date.now() - pending.startTs : undefined);
        const hasError = typeof event.error === "string" && event.error.length > 0;
        // Update tool call entry
        const existing = acc.toolCalls.find((t) => t.toolCallId === toolCallId);
        if (existing) {
            existing.phase = hasError ? "failed" : "completed";
            existing.result = event.result;
            existing.error = event.error ?? null;
            existing.durationMs = durationMs;
        }
        // Add thought event
        acc.thinkingEvents.push({
            kind: "toolResult",
            toolName: name,
            toolCallId,
            phase: hasError ? "failed" : "completed",
            result: event.result,
            error: typeof event.error === "string" ? event.error : undefined,
            durationMs,
        });
        acc.pendingToolCalls.delete(toolCallId);
    }
}
function extractDisplayLabel(params) {
    // Common patterns: query, path, url, message, name
    const str = params.query ?? params.path ?? params.url ?? params.message ?? params.name ?? params.text;
    if (typeof str !== "string" || !str.trim())
        return undefined;
    if (str.length <= 80)
        return str;
    return str.slice(0, 77) + "...";
}
export function feedMetadata(runId, meta) {
    const acc = getAccumulator(runId);
    if (!acc)
        return;
    if (meta.modelName)
        acc.modelName = meta.modelName;
    if (typeof meta.totalTokens === "number")
        acc.totalTokens = meta.totalTokens;
    if (typeof meta.contextTokensUsed === "number")
        acc.contextTokensUsed = meta.contextTokensUsed;
    if (typeof meta.contextWindowMax === "number")
        acc.contextWindowMax = meta.contextWindowMax;
}
export function feedLifecycle(runId, phase, _data) {
    const acc = getAccumulator(runId);
    if (!acc)
        return;
    acc.lifecyclePhase = phase;
}
export function finalizeAndStore(runId) {
    const acc = getAccumulator(runId);
    if (!acc)
        return null;
    console.error(`[Friday-ACCUM] finalize runId=${runId} deliverText="${acc.deliverText.substring(0, 80)}" thinkingEvents=${acc.thinkingEvents.length} toolCalls=${acc.toolCalls.length}`);
    const message = {
        id: "",
        content: acc.deliverText,
        sender: { assistant: { name: "Claude" } },
        timestamp: new Date().toISOString(),
        seq: 0,
        status: "sent",
        isFromCurrentUser: false,
        toolCalls: acc.toolCalls.length > 0 ? acc.toolCalls.map(normalizeToolCall) : null,
        attachment: null,
        extraAttachments: null,
        thoughtEvents: acc.thinkingEvents.length > 0 ? acc.thinkingEvents : null,
        ttsAttachment: null,
        commandTerminals: null,
        isInternalTrace: false,
        modelName: acc.modelName ?? null,
        totalTokens: acc.totalTokens ?? null,
        contextWindowMax: acc.contextWindowMax ?? null,
        contextTokensUsed: acc.contextTokensUsed ?? null,
        runId: acc.runId,
    };
    const serverId = storeAssistantMessage({
        sessionKey: acc.sessionKey,
        deviceId: acc.deviceId,
        message,
        runId: acc.runId,
    });
    return serverId;
}
function normalizeToolCall(tc) {
    return {
        id: tc.id,
        name: tc.name,
        phase: tc.phase,
        displayLabel: tc.displayLabel ?? null,
        displayEmoji: tc.displayEmoji ?? null,
        result: tc.result ?? null,
        error: tc.error ?? null,
        toolCallId: tc.toolCallId,
        durationMs: tc.durationMs ?? null,
        startTs: tc.startTs ?? null,
    };
}
export function disposeAccumulator(runId) {
    accumulators.delete(runId);
}
/** Vitest-only: clear all accumulators */
export function resetAccumulatorsForTest() {
    accumulators.clear();
}
