/**
 * Copyright 2025 Vybestack LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { normalizeToHistoryToolId, normalizeToOpenAIToolId, } from './toolIdUtils.js';
import { buildToolResponsePayload, EMPTY_TOOL_RESULT_PLACEHOLDER, } from '../utils/toolResponsePayload.js';
import { extractThinkingBlocks, thinkingToReasoningField, cleanKimiTokensFromThinking, } from '../reasoning/reasoningUtils.js';
function inferMediaEncoding(imageData) {
    const defaultResult = { encoding: 'url', mimeType: 'image/*' };
    if (imageData.startsWith('data:image/') && imageData.includes(';base64,')) {
        const mimeMatch = imageData.slice('data:'.length).match(/^([^;]+);base64,/);
        const mimeType = mimeMatch?.[1] ?? 'image/*';
        return { encoding: 'base64', mimeType };
    }
    if (imageData.startsWith('data:')) {
        return defaultResult;
    }
    if (imageData.startsWith('http://') || imageData.startsWith('https://')) {
        return defaultResult;
    }
    // Fallback: treat as base64 when it is not a recognizable URL
    return { encoding: 'base64', mimeType: 'image/*' };
}
/**
 * Convert IContent array to Vercel AI SDK CoreMessage array
 * @param contents - The contents to convert
 * @param toolIdMapper - Optional mapper for tool IDs (for Kimi K2 format)
 * @param options - Optional conversion options
 */
export function convertToVercelMessages(contents, toolIdMapper, options) {
    const messages = [];
    // Helper to resolve tool call IDs based on format
    const resolveToolCallId = (block) => {
        if (toolIdMapper) {
            return toolIdMapper.resolveToolCallId(block);
        }
        return normalizeToOpenAIToolId(block.id);
    };
    // Helper to resolve tool response IDs based on format
    const resolveToolResponseId = (block) => {
        if (toolIdMapper) {
            return toolIdMapper.resolveToolResponseId(block);
        }
        return normalizeToOpenAIToolId(block.callId || '');
    };
    for (const content of contents) {
        const metadata = content.metadata;
        const metadataRole = metadata?.role;
        if (metadataRole === 'system' ||
            content.speaker === 'system') {
            // Convert system messages
            const textBlocks = content.blocks.filter((b) => b.type === 'text');
            const text = textBlocks
                .map((b) => b.text)
                .filter((t) => t.length > 0)
                .join('\n');
            if (text) {
                messages.push({
                    role: 'system',
                    content: text,
                });
            }
        }
        else if (content.speaker === 'human') {
            // Convert human messages to user messages
            const textBlocks = content.blocks.filter((b) => b.type === 'text');
            const mediaBlocks = content.blocks.filter((b) => b.type === 'media');
            const hasImages = mediaBlocks.length > 0;
            const text = textBlocks
                .map((b) => b.text)
                .filter((t) => t.length > 0)
                .join('\n');
            if (hasImages) {
                const parts = [];
                if (text) {
                    parts.push({ type: 'text', text });
                }
                for (const media of mediaBlocks) {
                    parts.push({
                        type: 'image',
                        image: normalizeImageData(media),
                    });
                }
                if (parts.length > 0) {
                    messages.push({
                        role: 'user',
                        content: parts,
                    });
                }
            }
            else if (text) {
                messages.push({
                    role: 'user',
                    content: text,
                });
            }
        }
        else if (content.speaker === 'ai') {
            // Convert AI messages to assistant messages
            const textBlocks = content.blocks.filter((b) => b.type === 'text');
            const toolCallBlocks = content.blocks.filter((b) => b.type === 'tool_call');
            const thinkingBlocks = extractThinkingBlocks(content);
            const text = textBlocks
                .map((b) => b.text)
                .filter((t) => t.length > 0)
                .join('\n');
            if (toolCallBlocks.length > 0) {
                const contentParts = [];
                if (text) {
                    contentParts.push({ type: 'text', text });
                }
                for (const block of toolCallBlocks) {
                    const toolCall = block;
                    const input = toolCall.input !== undefined ? toolCall.input : block.parameters;
                    contentParts.push({
                        type: 'tool-call',
                        toolCallId: resolveToolCallId(block),
                        toolName: block.name,
                        input,
                    });
                }
                const baseMessage = {
                    role: 'assistant',
                    content: contentParts,
                };
                // Add reasoning_content if includeReasoningInContext is true and thinking blocks exist
                if (options?.includeReasoningInContext && thinkingBlocks.length > 0) {
                    const reasoningText = thinkingToReasoningField(thinkingBlocks);
                    if (reasoningText) {
                        const messageWithReasoning = baseMessage;
                        messageWithReasoning.reasoning_content =
                            cleanKimiTokensFromThinking(reasoningText);
                        messages.push(messageWithReasoning);
                    }
                    else {
                        messages.push(baseMessage);
                    }
                }
                else {
                    messages.push(baseMessage);
                }
            }
            else if (text || thinkingBlocks.length > 0) {
                const baseMessage = {
                    role: 'assistant',
                    content: text,
                };
                // Add reasoning_content if includeReasoningInContext is true and thinking blocks exist
                if (options?.includeReasoningInContext && thinkingBlocks.length > 0) {
                    const reasoningText = thinkingToReasoningField(thinkingBlocks);
                    if (reasoningText) {
                        const messageWithReasoning = baseMessage;
                        messageWithReasoning.reasoning_content =
                            cleanKimiTokensFromThinking(reasoningText);
                        messages.push(messageWithReasoning);
                    }
                    else {
                        messages.push(baseMessage);
                    }
                }
                else if (text) {
                    messages.push(baseMessage);
                }
            }
        }
        else if (content.speaker === 'tool') {
            // Convert tool messages to tool result messages
            const toolResponseBlocks = content.blocks.filter((b) => b.type === 'tool_response');
            if (toolResponseBlocks.length > 0) {
                const toolContent = toolResponseBlocks.map((block) => {
                    const payload = buildToolResponsePayload(block);
                    const extBlock = block;
                    return {
                        type: 'tool-result',
                        toolCallId: resolveToolResponseId(block),
                        toolName: extBlock.name || extBlock.toolName || '',
                        output: {
                            type: 'text',
                            value: payload.result,
                        },
                    };
                });
                const toolMessage = {
                    role: 'tool',
                    content: toolContent,
                };
                messages.push(toolMessage);
            }
        }
    }
    return messages;
}
/**
 * Convert Vercel AI SDK CoreMessage array back to IContent array
 */
export function convertFromVercelMessages(messages) {
    const contents = [];
    for (const message of messages) {
        if (message.role === 'user') {
            // Convert user messages to human messages
            if (Array.isArray(message.content)) {
                const blocks = [];
                for (const part of message.content) {
                    const partType = part.type;
                    if (typeof part === 'string') {
                        if (part) {
                            blocks.push({ type: 'text', text: part });
                        }
                        continue;
                    }
                    if (partType === 'text') {
                        const text = part.text;
                        if (text) {
                            blocks.push({ type: 'text', text });
                        }
                    }
                    else if (partType === 'image') {
                        const imageData = part.image ??
                            part.url;
                        if (imageData) {
                            const { encoding, mimeType } = inferMediaEncoding(imageData);
                            blocks.push({
                                type: 'media',
                                data: imageData,
                                encoding,
                                mimeType,
                            });
                        }
                    }
                }
                if (blocks.length > 0) {
                    contents.push({
                        speaker: 'human',
                        blocks,
                    });
                }
            }
            else {
                const text = typeof message.content === 'string' ? message.content : '';
                if (text) {
                    contents.push({
                        speaker: 'human',
                        blocks: [
                            {
                                type: 'text',
                                text,
                            },
                        ],
                    });
                }
            }
        }
        else if (message.role === 'assistant') {
            // Convert assistant messages to AI messages
            const blocks = [];
            if (typeof message.content === 'string') {
                if (message.content) {
                    blocks.push({
                        type: 'text',
                        text: message.content,
                    });
                }
            }
            else if (Array.isArray(message.content)) {
                for (const part of message.content) {
                    const partType = part.type;
                    if (typeof part === 'string') {
                        if (part) {
                            blocks.push({
                                type: 'text',
                                text: part,
                            });
                        }
                    }
                    else if (partType === 'text') {
                        const text = part.text;
                        if (text) {
                            blocks.push({
                                type: 'text',
                                text,
                            });
                        }
                    }
                    else if (partType === 'image') {
                        const imageData = part.image ??
                            part.url;
                        if (imageData) {
                            const { encoding, mimeType } = inferMediaEncoding(imageData);
                            blocks.push({
                                type: 'media',
                                data: imageData,
                                encoding,
                                mimeType,
                            });
                        }
                    }
                    else if (partType === 'tool-call') {
                        const toolPart = part;
                        const parameters = toolPart.input !== undefined ? toolPart.input : toolPart.args;
                        const toolCallBlock = {
                            type: 'tool_call',
                            id: normalizeToHistoryToolId(toolPart.toolCallId),
                            name: toolPart.toolName,
                            parameters,
                        };
                        if (toolPart.input !== undefined) {
                            toolCallBlock.input = toolPart.input;
                        }
                        blocks.push(toolCallBlock);
                    }
                }
            }
            // Handle toolInvocations if present (extended message format)
            const extendedMessage = message;
            if (extendedMessage.toolInvocations &&
                extendedMessage.toolInvocations.length > 0) {
                for (const invocation of extendedMessage.toolInvocations) {
                    if (invocation.state === 'call') {
                        blocks.push({
                            type: 'tool_call',
                            id: normalizeToHistoryToolId(invocation.toolCallId),
                            name: invocation.toolName,
                            parameters: invocation.args,
                        });
                    }
                }
            }
            if (blocks.length > 0) {
                contents.push({
                    speaker: 'ai',
                    blocks,
                });
            }
        }
        else if (message.role === 'tool') {
            // Convert tool messages to tool response messages
            const blocks = [];
            for (const part of message.content) {
                if (part.type === 'tool-result') {
                    const output = part.output;
                    const isErrorOutput = output &&
                        typeof output === 'object' &&
                        'type' in output &&
                        typeof output.type === 'string' &&
                        output.type?.startsWith('error');
                    const resultValue = output &&
                        typeof output === 'object' &&
                        'value' in output
                        ? output.value
                        : output;
                    let parsedResult = resultValue;
                    if (typeof resultValue === 'string') {
                        if (resultValue === EMPTY_TOOL_RESULT_PLACEHOLDER) {
                            parsedResult = undefined;
                        }
                        else {
                            try {
                                parsedResult = JSON.parse(resultValue);
                            }
                            catch {
                                parsedResult = resultValue;
                            }
                        }
                    }
                    const toolResponseBlock = {
                        type: 'tool_response',
                        callId: normalizeToHistoryToolId(part.toolCallId),
                        toolName: part.toolName,
                        result: parsedResult,
                    };
                    if (isErrorOutput) {
                        toolResponseBlock.isError = true;
                        if (typeof resultValue === 'string') {
                            toolResponseBlock.error = resultValue;
                        }
                    }
                    blocks.push(toolResponseBlock);
                }
            }
            if (blocks.length > 0) {
                contents.push({
                    speaker: 'tool',
                    blocks,
                });
            }
        }
        else if (message.role === 'system') {
            // Convert system messages
            const systemContent = message.content;
            const text = typeof systemContent === 'string'
                ? systemContent
                : Array.isArray(systemContent)
                    ? systemContent
                        .map((part) => {
                        if (typeof part === 'string')
                            return part;
                        if (part.type === 'text')
                            return part.text || '';
                        return '';
                    })
                        .join('\n')
                    : '';
            if (text) {
                const systemContentObj = {
                    speaker: 'ai',
                    blocks: [
                        {
                            type: 'text',
                            text,
                        },
                    ],
                    metadata: {
                        role: 'system',
                    },
                };
                contents.push(systemContentObj);
            }
        }
    }
    return contents;
}
function normalizeImageData(media) {
    if (media.data.startsWith('data:')) {
        return media.data;
    }
    if (media.encoding === 'url') {
        return media.data;
    }
    const prefix = media.mimeType
        ? `data:${media.mimeType};base64,`
        : 'data:image/*;base64,';
    return `${prefix}${media.data}`;
}
//# sourceMappingURL=messageConversion.js.map