import { submitOrderFollowStandardAgentRequest, queryConversation, } from '../../../../../../cn-ai-table/view/services/ai-smart-follow-service';
import { queryResponse as queryAgentResponse } from '../../../../../../cn-ai-agent/services/ai-agent-service';
import { isEditor } from '../../../../../../utils/env/index.js';
/**
 * 从 Agent 返回的 metaData 中提取快捷回复选项。
 * 后端约定在 metaData.suggestedChoices 中以 string[] 形式下发建议选项，
 * 此函数负责过滤无效值并转换为 ChatQuickReply 结构。
 */
function quickRepliesFromMeta(meta) {
    const raw = meta === null || meta === void 0 ? void 0 : meta.suggestedChoices;
    if (!Array.isArray(raw))
        return [];
    return raw
        .filter((item) => typeof item === 'string' && item.trim().length > 0)
        .map((label, index) => {
        const text = label.trim();
        return {
            id: `suggested-choice-${index}`,
            label: text,
            prompt: text,
        };
    });
}
/**
 * 创建 smart-follow 场景的 ChatAdapter
 * 将 submitOrderFollowStandardAgentRequest + queryResponse 映射到 ChatAdapter 接口
 *
 * 闭包内维护 lastConversationId / lastRespMessageId，
 * 保证续聊时 submit 请求体能携带上一轮会话上下文。
 */
export function createSmartFollowChatAdapter(bizRequestConfig) {
    let lastConversationId = null;
    // let lastRespMessageId: string | null = null;
    return {
        /**
         * 提交用户消息到跟单标准 Agent。
         *
         * - `init: false` 表示这是一次用户主动提问（区别于 init 方法的系统初始化）
         * - `class` 字段是 Java 后端 Jackson 多态反序列化所需的类型标识
         * - conversationId 优先使用上层传入的值，兜底使用闭包中缓存的上一轮会话 ID，
         *   确保在 CnAiChatShell 未传入 conversationId 时仍能保持续聊上下文
         */
        async submit(input) {
            var _a, _b, _c, _d;
            if (isEditor) {
                throw new Error('smart-follow chat disabled in lowcode editor');
            }
            const ctx = ((_a = input.context) !== null && _a !== void 0 ? _a : {});
            const conversationId = input.conversationId || lastConversationId;
            const requestBody = {
                init: false,
                userPrompt: input.userPrompt,
                columnDefinitions: (_b = ctx.columnDefinitions) !== null && _b !== void 0 ? _b : [],
                tableId: (_c = ctx.tableId) !== null && _c !== void 0 ? _c : '',
                userId: (_d = ctx.userId) !== null && _d !== void 0 ? _d : '',
                class: 'com.cainiao.aitable.api.domain.CnAiTableAgentPromptRequest',
            };
            if (conversationId) {
                requestBody.conversationId = conversationId;
            }
            // if (lastRespMessageId) {
            //   requestBody.respMessageId = lastRespMessageId;
            // }
            const result = await submitOrderFollowStandardAgentRequest([requestBody], bizRequestConfig);
            if (!result) {
                throw new Error('submitOrderFollowStandardAgentRequest failed');
            }
            // 缓存会话 ID，后续 submit 续聊时可自动携带
            lastConversationId = result.conversationId;
            // lastRespMessageId = result.respMessageId;
            return {
                conversationId: result.conversationId,
                respMessageId: result.respMessageId,
            };
        },
        /**
         * 轮询 AI 回复。
         * 复用通用 AI Agent 的 queryResponse 接口（而非跟单专属接口），
         * 因为跟单 Agent 的流式回复走的是统一的 Agent 消息通道。
         */
        async query(input) {
            var _a, _b;
            if (isEditor) {
                return { text: '', onGoing: false };
            }
            const res = await queryAgentResponse({
                conversationId: input.conversationId,
                messageId: input.messageId,
            }, bizRequestConfig ? { agent: bizRequestConfig.agent } : undefined);
            const meta = res.metaData;
            const quickReplies = quickRepliesFromMeta(meta);
            return {
                text: (_a = res.text) !== null && _a !== void 0 ? _a : '',
                onGoing: (_b = res.onGoing) !== null && _b !== void 0 ? _b : false,
                meta,
                quickReplies: quickReplies.length ? quickReplies : undefined,
            };
        },
        /**
         * 会话初始化——用户首次进入跟单标准页面时由系统自动触发。
         * `init: true` 会让后端使用预设的初始化 prompt 发起提问（无需 userPrompt），
         * 返回的 conversationId/respMessageId 供后续 query 轮询首条 AI 回复。
         * 初始化失败时静默返回 void，由上层决定是否重试。
         */
        async init(context) {
            var _a, _b, _c;
            if (isEditor) {
                return undefined;
            }
            const ctx = (context !== null && context !== void 0 ? context : {});
            const result = await submitOrderFollowStandardAgentRequest([
                {
                    init: true,
                    columnDefinitions: (_a = ctx.columnDefinitions) !== null && _a !== void 0 ? _a : [],
                    tableId: (_b = ctx.tableId) !== null && _b !== void 0 ? _b : '',
                    userId: (_c = ctx.userId) !== null && _c !== void 0 ? _c : '',
                    class: 'com.cainiao.aitable.api.domain.CnAiTableAgentPromptRequest',
                },
            ], bizRequestConfig);
            if (!result) {
                return;
            }
            lastConversationId = result.conversationId;
            // lastRespMessageId = result.respMessageId;
            return {
                conversationId: result.conversationId,
                respMessageId: result.respMessageId,
            };
        },
        /**
         * 加载历史会话记录，支持向上滚动分页加载。
         *
         * 后端返回的会话列表按创建时间倒序排列（最新的在前），
         * 但 ChatAdapter 协议要求消息按时间升序（最早的在前），
         * 因此需要对 conversations 做 reverse() 处理。
         *
         * cursor 用页码字符串实现分页（首次 "1"，下一页 "2" ...），
         * 与 ChatAdapter 协议中 cursor 的 opaque-string 约定兼容。
         */
        async queryHistory(input) {
            var _a;
            if (isEditor) {
                return { messages: [], hasMore: false };
            }
            const ctx = ((_a = input.context) !== null && _a !== void 0 ? _a : {});
            if (!ctx.tableId) {
                return { messages: [], hasMore: false };
            }
            // 每页拉取 3 轮会话（每轮包含多条消息），控制单次请求量
            const CONV_PAGE_SIZE = 3;
            const pageIndex = input.cursor ? parseInt(input.cursor, 10) : 1;
            try {
                const result = await queryConversation({
                    pageIndex,
                    pageSize: CONV_PAGE_SIZE,
                    type: 'orderFollowStandardConversation',
                    tableId: ctx.tableId,
                    status: 'USER_PROMPTED',
                }, bizRequestConfig);
                if (!result) {
                    return { messages: [], hasMore: false };
                }
                const { conversations, pagination } = result;
                // 排除当前正在进行的会话，避免与实时消息重复
                const filtered = conversations.filter((c) => !input.conversationId || c.conversationId !== input.conversationId);
                // 倒序 → 升序：后端按时间倒序返回，这里翻转后按时间从早到晚排列
                const chatMessages = [];
                for (const conv of [...filtered].reverse()) {
                    for (const msg of conv.messages) {
                        chatMessages.push({
                            id: `history-${conv.conversationId}-${msg.id}`,
                            role: msg.messageType === 'ASSISTANT' ? 'assistant' : 'user',
                            content: msg.text,
                            status: 'done',
                            time: conv.gmtCreate,
                        });
                    }
                }
                const hasMore = pageIndex * CONV_PAGE_SIZE < pagination.total;
                const nextCursor = hasMore ? String(pageIndex + 1) : undefined;
                return { messages: chatMessages, nextCursor, hasMore };
            }
            catch {
                return { messages: [], hasMore: false };
            }
        },
    };
}
