"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.normalizeLookupSearchConfigs = normalizeLookupSearchConfigs;
exports.mergeLookupSchemaPropertiesToJoinTableParams = mergeLookupSchemaPropertiesToJoinTableParams;
exports.buildLookupJoinSearchPayload = buildLookupJoinSearchPayload;
/**
 * 将未知类型值归一化为布尔值。
 * 主要用于兼容后端/历史配置中 `canSearch` 的多种表达方式。
 *
 * @param value 任意输入值（boolean/string/number/others）
 * @returns 归一化后的布尔结果
 */
function toBoolean(value) {
    if (typeof value === 'boolean')
        return value;
    if (typeof value === 'string')
        return value.toLowerCase() === 'true';
    if (typeof value === 'number')
        return value > 0;
    return false;
}
/**
 * 根据 lookup 配置生成在 Formily 中的嵌套路径。
 * 形如：`joinTableParams.<sourceTableId>.<targetFieldCode>`
 *
 * @param config 单个 lookup 搜索配置
 * @returns 对应字段路径
 */
function getLookupFieldPath(config) {
    return `joinTableParams.${config.sourceTableId}.${config.targetFieldCode}`;
}
/**
 * 按点路径读取对象值（安全读取，不抛错）。
 *
 * @param target 被读取对象
 * @param path 点路径，如 `a.b.c`
 * @returns 路径值，不存在时返回 `undefined`
 */
function getValueByPath(target, path) {
    if (!target || !path)
        return undefined;
    return path.split('.').reduce((acc, key) => {
        if (!acc || typeof acc !== 'object')
            return undefined;
        return acc[key];
    }, target);
}
/**
 * 归一化 lookup 输入值，统一清洗空值：
 * - `null/undefined` -> `undefined`
 * - 空字符串（含空白）-> `undefined`
 * - 数组递归清洗，清空后返回 `undefined`
 * - 其他类型原样返回
 *
 * @param input 原始输入值
 * @returns 清洗后的值；无效值返回 `undefined`
 */
function normalizeLookupValue(input) {
    if (input === undefined || input === null)
        return undefined;
    if (typeof input === 'string') {
        const trimmed = input.trim();
        return trimmed === '' ? undefined : trimmed;
    }
    if (Array.isArray(input)) {
        const normalized = input
            .map((item) => normalizeLookupValue(item))
            .filter((item) => item !== undefined);
        if (normalized.length === 0)
            return undefined;
        if (normalized.length === 1)
            return normalized[0];
        return normalized;
    }
    return input;
}
/**
 * 归一化 lookup 配置集合：
 * - 接受 map 或 array 两种输入
 * - 过滤缺失关键字段（`columnCode/sourceTableId/targetFieldCode`）的项
 * - 标准化 `canSearch` 为 boolean
 *
 * @param input lookup 配置输入（可能来自 props 或事件 payload）
 * @returns 统一后的 map（key 为 `columnCode`）
 */
function normalizeLookupSearchConfigs(input) {
    if (!input)
        return {};
    const list = Array.isArray(input) ? input : Object.values(input);
    return list.reduce((acc, config) => {
        const columnCode = config === null || config === void 0 ? void 0 : config.columnCode;
        const sourceTableId = config === null || config === void 0 ? void 0 : config.sourceTableId;
        const targetFieldCode = config === null || config === void 0 ? void 0 : config.targetFieldCode;
        if (!columnCode || !sourceTableId || !targetFieldCode)
            return acc;
        acc[columnCode] = {
            ...config,
            canSearch: toBoolean(config.canSearch),
        };
        return acc;
    }, {});
}
/**
 * 将可搜索 lookup 字段合并进 Formily schema 的 `joinTableParams` 嵌套结构。
 *
 * 该函数只做「字段路径与渲染协议」的注入，不生成 `joinTableColumns`。
 * 目标结构：
 * `schema.properties.joinTableParams.properties.<subTable>.properties.<targetField>`
 *
 * @param schema 原始筛选 schema（通常来自业务传入）
 * @param lookupConfigMap 归一化后的 lookup 配置 map
 * @returns 合并后的新 schema（浅拷贝 + 局部扩展）
 */
function mergeLookupSchemaPropertiesToJoinTableParams(schema, lookupConfigMap) {
    if (!schema || typeof schema !== 'object')
        return schema;
    const mergedSchema = {
        ...schema,
        properties: {
            ...(schema.properties || {}),
        },
    };
    const joinTableParamsNode = mergedSchema.properties.joinTableParams || {
        type: 'object',
        properties: {},
    };
    if (!joinTableParamsNode.properties) {
        joinTableParamsNode.properties = {};
    }
    mergedSchema.properties.joinTableParams = joinTableParamsNode;
    Object.values(lookupConfigMap).forEach((config) => {
        var _a, _b;
        if (!config.canSearch)
            return;
        const path = getLookupFieldPath(config);
        const tableNode = joinTableParamsNode.properties[config.sourceTableId] || {
            type: 'object',
            properties: {},
        };
        if (!tableNode.properties) {
            tableNode.properties = {};
        }
        tableNode.properties[config.targetFieldCode] = {
            title: config.fieldName || config.targetFieldName || config.targetFieldCode,
            _name: path,
            type: 'string',
            'x-component': (_a = config.model) === null || _a === void 0 ? void 0 : _a.type,
            // 'x-component': toFormilyComponentName(config.model),
            'x-component-props': ((_b = config.model) === null || _b === void 0 ? void 0 : _b.props) || {},
            'x-data': {
                lookup: true,
                sourceTableId: config.sourceTableId,
                targetFieldCode: config.targetFieldCode,
                columnCode: config.columnCode,
            },
        };
        joinTableParamsNode.properties[config.sourceTableId] = tableNode;
    });
    return mergedSchema;
}
/**
 * 基于 lookup 配置清洗并生成最终 join 查询协议：
 * - `joinTableParams`：仅保留当前有值且 `canSearch=true` 的引用字段条件
 * - `joinTableColumns`：收敛全部有效 lookup 字段（与 `canSearch` 解耦），按子表聚合并去重
 *
 * 同时会从 `searchParams` 中移除点路径字段，避免平铺参数污染最终请求体。
 *
 * @param params.lookupConfigMap 可搜索 lookup 配置 map
 * @param params.searchParams 非 lookup + lookup 平铺路径混合参数
 * @param params.formValue 可选的表单值（优先使用，兼容标签表单结构）
 * @returns 最终提交给 `onSearch` 的查询参数对象
 */
function buildLookupJoinSearchPayload(params) {
    const { lookupConfigMap, searchParams, formValue } = params;
    const finalSearchParams = { ...searchParams };
    const joinTableParams = {};
    const joinTableColumnsMap = {};
    Object.values(lookupConfigMap).forEach((config) => {
        var _a, _b, _c, _d;
        if (!(config === null || config === void 0 ? void 0 : config.sourceTableId) || !(config === null || config === void 0 ? void 0 : config.targetFieldCode))
            return;
        const path = getLookupFieldPath(config);
        const fromForm = (_a = getValueByPath(formValue, path)) !== null && _a !== void 0 ? _a : formValue === null || formValue === void 0 ? void 0 : formValue[path];
        const fromSearch = (_b = getValueByPath(searchParams, path)) !== null && _b !== void 0 ? _b : searchParams[path];
        const rawFieldValue = (_d = (_c = fromForm === null || fromForm === void 0 ? void 0 : fromForm.values) !== null && _c !== void 0 ? _c : fromForm) !== null && _d !== void 0 ? _d : fromSearch;
        const normalizedFieldValue = normalizeLookupValue(rawFieldValue);
        const { sourceTableId, targetFieldCode } = config;
        if (!joinTableColumnsMap[sourceTableId]) {
            joinTableColumnsMap[sourceTableId] = new Set();
        }
        joinTableColumnsMap[sourceTableId].add(targetFieldCode);
        delete finalSearchParams[path];
        if (!config.canSearch) {
            return;
        }
        if (normalizedFieldValue !== undefined) {
            if (!joinTableParams[sourceTableId]) {
                joinTableParams[sourceTableId] = {};
            }
            joinTableParams[sourceTableId][targetFieldCode] = normalizedFieldValue;
        }
    });
    const joinTableColumns = Object.entries(joinTableColumnsMap).reduce((acc, [sourceTableId, fieldSet]) => {
        acc[sourceTableId] = Array.from(fieldSet);
        return acc;
    }, {});
    if (Object.keys(joinTableColumns).length > 0) {
        finalSearchParams.joinTableColumns = [joinTableColumns];
    }
    else {
        delete finalSearchParams.joinTableColumns;
    }
    if (Object.keys(joinTableParams).length > 0) {
        finalSearchParams.joinTableParams = joinTableParams;
    }
    else {
        delete finalSearchParams.joinTableParams;
    }
    return finalSearchParams;
}
