const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
function extractImageUrlFromPart(part) {
    const imageUrlBlock = isRecord(part.image_url)
        ? part.image_url
        : undefined;
    let url;
    if (imageUrlBlock && typeof imageUrlBlock.url === 'string') {
        url = imageUrlBlock.url;
    }
    else if (typeof part.image_url === 'string') {
        url = part.image_url;
    }
    else if (typeof part.url === 'string') {
        url = part.url;
    }
    else if (typeof part.uri === 'string') {
        url = part.uri;
    }
    else if (typeof part.data === 'string') {
        url = part.data;
    }
    const trimmed = (url ?? '').trim();
    return trimmed.length ? trimmed : null;
}
function collectUserTextFromMessage(msg) {
    const content = msg.content;
    if (!Array.isArray(content)) {
        if (typeof content === 'string') {
            return content;
        }
        return '';
    }
    const parts = [];
    for (const entry of content) {
        if (!isRecord(entry))
            continue;
        const text = entry.text;
        if (typeof text === 'string' && text.trim().length) {
            parts.push(text.trim());
        }
    }
    return parts.join('\n');
}
/**
 * GLM 4.6V 专用视觉提示裁剪：
 * - 仅在 model 为 glm-4.6v 且存在携带图片的 user 消息时生效；
 * - 丢弃原有 system 与历史对话，只保留一条新的 system + 一条 user；
 * - system：要求模型以结构化 JSON 描述截图内容、标记（圈/箭头等）及其大致 bbox；
 * - user：保留原始用户文字（如果有）+ 单一 image_url 块。
 *
 * 其他模型（包括 glm-4.7、Gemini 等）不受影响。
 */
export function applyGlmVisionPromptTransform(payload) {
    const root = structuredClone(payload);
    const modelRaw = root.model;
    const model = typeof modelRaw === 'string' ? modelRaw.trim() : '';
    if (!model.startsWith('glm-4.6v')) {
        return root;
    }
    const messagesValue = root.messages;
    if (!Array.isArray(messagesValue)) {
        return root;
    }
    const messages = messagesValue.filter((msg) => isRecord(msg));
    if (!messages.length) {
        return root;
    }
    // 从末尾开始查找最近一条带图片的 user 消息。
    let latestUserWithImage = null;
    let imageUrl = null;
    for (let i = messages.length - 1; i >= 0; i -= 1) {
        const msg = messages[i];
        const role = typeof msg.role === 'string' ? msg.role.toLowerCase() : '';
        if (role !== 'user') {
            continue;
        }
        const content = msg.content;
        if (!Array.isArray(content)) {
            continue;
        }
        for (const part of content) {
            if (!isRecord(part))
                continue;
            const typeValue = typeof part.type === 'string' ? part.type.toLowerCase() : '';
            if (typeValue === 'image' || typeValue === 'image_url' || typeValue === 'input_image') {
                const candidateUrl = extractImageUrlFromPart(part);
                if (candidateUrl) {
                    latestUserWithImage = msg;
                    imageUrl = candidateUrl;
                    break;
                }
            }
        }
        if (latestUserWithImage && imageUrl) {
            break;
        }
    }
    if (!latestUserWithImage || !imageUrl) {
        return root;
    }
    const systemContent = '你是 Codex 的截图理解子系统，专门用于分析 UI 截图和网页图片。请仅根据用户提供的图片，输出一个结构化的 JSON，用于后续自动化处理，不要输出额外解释性文字或自然语言说明。\n' +
        '\n' +
        '输出必须是**单个合法 JSON 对象**，不要包含 Markdown、代码块标记或多余文本。请严格遵循下面的结构（字段可以为空数组，但必须存在）：\n' +
        '{\n' +
        '  "summary": "用 1-3 句整体描述这张图片（例如页面类型、主要区域、核心信息）",\n' +
        '  "marks": [\n' +
        '    {\n' +
        '      "type": "circle | arrow | underline | box | other",\n' +
        '      "color": "red | green | blue | yellow | other",\n' +
        '      "bbox": [x, y, width, height],\n' +
        '      "description": "该标记所圈出/指向/强调的内容，包含相关文字或 UI 元素描述"\n' +
        '    }\n' +
        '  ],\n' +
        '  "regions": [\n' +
        '    {\n' +
        '      "bbox": [x, y, width, height],\n' +
        '      "description": "该区域的可见内容（控件/图标/布局，以及其中出现的所有清晰可辨的文字）",\n' +
        '      "is_marked": true | false\n' +
        '    }\n' +
        '  ],\n' +
        '  "metadata": {\n' +
        '    "image_size_hint": "如果能推断出大致分辨率，请给出类似 1920x1080 的字符串；无法判断时用 null",\n' +
        '    "screenshot": true\n' +
        '  }\n' +
        '}\n' +
        '\n' +
        '细则：\n' +
        '1. 文字提取要求：\n' +
        '   - 如果图片中存在清晰可辨的文字（包括标题、菜单、按钮、标签、提示信息、弹窗、错误信息等），必须在对应的 regions.description 中**完整抄写**这些文字，按自然阅读顺序组织，避免遗漏。\n' +
        '   - 如果有多行文字，可以用换行符分隔，但仍放在同一个 description 字段中。\n' +
        '   - 对确实无法看清的文字，用类似 "（模糊，无法辨认）" 标注即可；没有任何文字也视为正常情况，此时只需描述界面结构。\n' +
        '2. 标记识别（marks）：\n' +
        '   - 对所有明显的圈选、箭头、下划线、高亮框等标记，必须在 marks 中列出，每一项提供大致 bbox、颜色和简短说明，说明其强调或指向的内容。\n' +
        '3. 区域划分（regions）：\n' +
        '   - 将截图拆分为若干有意义的区域：如导航栏、侧边栏、主内容区、弹窗、对话框、表格、代码块、表单等。\n' +
        '   - 每个区域的 description 中，既要描述布局/控件类型，也要包含该区域内的全部清晰文字内容。\n' +
        '   - is_marked 为 true 表示该区域与某个标记（marks）相关或被标记强调。\n' +
        '4. 坐标规范：所有 bbox 使用相对于当前图片的像素坐标，左上角为 (0,0)，width/height 为正数近似值。\n' +
        '5. 无论图片内容如何，最终回答必须是合法 JSON，不能在 JSON 前后添加任何额外文本。';
    const systemMessage = {
        role: 'system',
        content: systemContent
    };
    const originalUserText = collectUserTextFromMessage(latestUserWithImage);
    const userBlocks = [];
    if (originalUserText && originalUserText.trim().length) {
        userBlocks.push({
            type: 'text',
            text: originalUserText.trim()
        });
    }
    else {
        userBlocks.push({
            type: 'text',
            text: '请按照上面的 JSON 结构，详细描述这张图片的内容和标记。'
        });
    }
    userBlocks.push({
        type: 'image_url',
        image_url: {
            url: imageUrl
        }
    });
    const userMessage = {
        role: 'user',
        content: userBlocks
    };
    // 丢弃原有 messages，仅保留新的 system + user。
    root.messages = [systemMessage, userMessage];
    // 对于专用视觉模型，限制 max_tokens，避免过大的 completion 预算进一步触发上下文相关错误。
    const maxTokensValue = root.max_tokens;
    if (typeof maxTokensValue === 'number' && Number.isFinite(maxTokensValue)) {
        // 将超大值收敛到一个相对安全的上限；真实上限由上游再校验。
        root.max_tokens = Math.min(maxTokensValue, 4096);
    }
    return root;
}
