"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AiRequestError = void 0;
exports.aiRequest = aiRequest;
const i18n_1 = __importDefault(require("../locales/i18n.js"));
const cn_request_1 = require("@cainiaofe/cn-request");
const domain_service_1 = require("./domain-service.js");
const types_1 = require("./types/index.js");
/**
 * 业务请求失败时抛出的标准化错误。
 * 调用方可通过 `instanceof AiRequestError` 区分业务失败与网络异常。
 */
class AiRequestError extends Error {
    constructor(opts) {
        var _a;
        const msg = opts.errorMsg ||
            i18n_1.default.get({ id: 'RequestFailed', dm: '请求失败' }) +
                ` (errorCode: ${(_a = opts.errorCode) !== null && _a !== void 0 ? _a : 'unknown'})`;
        super(msg);
        this.name = 'AiRequestError';
        this.errorCode = opts.errorCode;
        this.errorMsg = opts.errorMsg;
        this.raw = opts.raw;
    }
}
exports.AiRequestError = AiRequestError;
// ==================== 内部工具 ====================
function isObject(v) {
    return typeof v === 'object' && v !== null && !Array.isArray(v);
}
function isAxiosLike(v) {
    if (!isObject(v))
        return false;
    if (!('status' in v) || typeof v.status !== 'number')
        return false;
    return 'headers' in v || 'config' in v;
}
function isEnvelope(v) {
    return isObject(v) && ('success' in v || 'errorCode' in v);
}
function isEnvelopeSuccess(env) {
    if (env.success === false)
        return false;
    if (env.success === true)
        return true;
    if (env.errorCode !== undefined) {
        return String(env.errorCode) === '0000';
    }
    return true;
}
function buildUrl(path) {
    const origin = (0, domain_service_1.getCachedHostDomain)();
    if (!origin) {
        return `${types_1.AI_TABLE_API_BASE_URL}${path}`;
    }
    return `${origin}${types_1.AI_TABLE_API_BASE_URL}${path}`;
}
function resolveUrl(config) {
    if (config.url)
        return config.url;
    if (config.path)
        return buildUrl(config.path);
    throw new Error(i18n_1.default.get({
        id: 'TheURLOrPathOfTheAiRequestMust',
        dm: 'aiRequest 的 url 或 path 至少需要提供一个',
    }));
}
/**
 * 统一请求入口（data-only 契约）。
 *
 * 所有 AI 相关 service（agent / smart-follow / ai-column 等）均通过此函数发请求。
 * 本文件是整个组件库唯一直接依赖 `@cainiaofe/cn-request` 的位置（domain-service 除外）。
 *
 * 归一化流程：
 * 1. 若返回值为 Axios-like（跨域场景），取 `.data` 得到 HTTP body
 * 2. 若 HTTP body 为信封结构（含 `success`/`errorCode`）：
 *    - 失败（`success === false` 或失败码）→ 抛 `AiRequestError`
 *    - 成功 → 返回 `envelope.data`
 * 3. 非信封场景直接返回 HTTP body
 *
 * 调用方只需处理正常数据，失败统一走 catch。
 */
async function aiRequest(config) {
    var _a;
    const finalConfig = {
        ...config,
        url: resolveUrl(config),
        withCredentials: (_a = config.withCredentials) !== null && _a !== void 0 ? _a : (0, domain_service_1.isUsingDynamicDomain)(),
    };
    const raw = await (0, cn_request_1.request)(finalConfig);
    const httpBody = isAxiosLike(raw) ? raw.data : raw;
    if (isEnvelope(httpBody)) {
        if (!isEnvelopeSuccess(httpBody)) {
            throw new AiRequestError({
                errorCode: httpBody.errorCode,
                errorMsg: httpBody.errorMsg,
                raw,
            });
        }
        return (httpBody.data !== undefined ? httpBody.data : httpBody);
    }
    return httpBody;
}
