/**
 * 文本提取器模块
 *
 * 提供从原始数据中直接提取显示文本的能力，避免 React 渲染开销。
 * 用于 AI 数据消费、导出等场景。
 */
import { renderToString } from 'react-dom/server';
import isFunction from 'lodash/isFunction';
import { safeGetRowKey, } from '../../../../../../../cn-ai-table/view/utils/primary-key';
import isNil from 'lodash/isNil';
import { extractDateText, extractDateTimeText, extractUserText, extractNumberText, extractCurrencyText, extractCurrencyWithUnitText, extractPercentText, extractMicrometerText, extractTagText, extractFileText, extractTextValue, extractEllipsisText, extractMultipleTextValue, extractImageTextValue, extractProgressText, extractGraphicsPercentText, extractBankText, } from './extractors';
import { AI_GENERATING_MARKER } from '../../../../../../../cn-ai-table/view/constants/ai-cell-constants';
export * from './types';
/**
 * AI 生成字段文本提取器
 * 空值或生成中状态返回空字符串（不返回 EMPTY_VALUE_DISPLAY，也不提取按钮文字）
 */
function extractAiGenerateText(value) {
    // 空值或生成中状态返回空字符串
    if (isNil(value) || value === '' || value === AI_GENERATING_MARKER) {
        return '';
    }
    // 有值时返回文本
    return typeof value === 'string' ? value : String(value);
}
/**
 * 创建带本地化的提取器
 */
function createLocalizedExtractor(baseExtractor, localeKey, localeConfig) {
    return (value, column, record) => baseExtractor(value, column, record, localeConfig[localeKey]);
}
/**
 * 获取默认的文本提取器注册表
 */
function getDefaultExtractorRegistry(localeConfig = {}) {
    return {
        // 文本类
        text: { extractor: extractTextValue, priority: 10 },
        ellipsis: { extractor: extractEllipsisText, priority: 10 },
        'multiple-text': { extractor: extractMultipleTextValue, priority: 10 },
        'image-text': { extractor: extractImageTextValue, priority: 10 },
        // 日期类
        date: {
            extractor: createLocalizedExtractor(extractDateText, 'dateAdapterLocale', localeConfig),
            priority: 5,
        },
        'date-time': {
            extractor: createLocalizedExtractor(extractDateTimeText, 'dateAdapterLocale', localeConfig),
            priority: 5,
        },
        // 数字类
        number: {
            extractor: createLocalizedExtractor(extractNumberText, 'numAdapterLocale', localeConfig),
            priority: 5,
        },
        currency: {
            extractor: createLocalizedExtractor(extractCurrencyText, 'numAdapterLocale', localeConfig),
            priority: 5,
        },
        'currency-with-unit': {
            extractor: createLocalizedExtractor(extractCurrencyWithUnitText, 'numAdapterLocale', localeConfig),
            priority: 5,
        },
        percent: {
            extractor: createLocalizedExtractor(extractPercentText, 'numAdapterLocale', localeConfig),
            priority: 5,
        },
        micrometer: {
            extractor: createLocalizedExtractor(extractMicrometerText, 'numAdapterLocale', localeConfig),
            priority: 5,
        },
        progress: {
            extractor: createLocalizedExtractor(extractProgressText, 'numAdapterLocale', localeConfig),
            priority: 5,
        },
        'graphics-percent': {
            extractor: createLocalizedExtractor(extractGraphicsPercentText, 'numAdapterLocale', localeConfig),
            priority: 5,
        },
        // 特殊类型
        user: { extractor: extractUserText, priority: 5 },
        tag: { extractor: extractTagText, priority: 5 },
        file: { extractor: extractFileText, priority: 5 },
        bank: { extractor: extractBankText, priority: 5 },
        // AI 字段类型
        'ai-generate': { extractor: extractAiGenerateText, priority: 5 },
    };
}
// 自定义提取器注册表
let customExtractorRegistry = {};
/**
 * 注册自定义文本提取器
 */
export function registerTextExtractor(format, extractor, priority = 10) {
    customExtractorRegistry[format.toLowerCase()] = { extractor, priority };
}
/**
 * 清除自定义提取器
 */
export function clearCustomExtractors() {
    customExtractorRegistry = {};
}
/**
 * 从 React 节点中提取文本内容
 * 作为 fallback 方案
 */
function extractTextFromReactNode(reactNode) {
    var _a;
    if (reactNode === null || reactNode === undefined) {
        return '';
    }
    // 如果是字符串或数字，直接返回
    if (typeof reactNode === 'string' || typeof reactNode === 'number') {
        return String(reactNode);
    }
    // 如果是布尔值，返回空字符串
    if (typeof reactNode === 'boolean') {
        return '';
    }
    // 如果是数组，递归处理每个元素
    if (Array.isArray(reactNode)) {
        return reactNode.map((node) => extractTextFromReactNode(node)).join(' ');
    }
    // 如果是 React 元素，使用 renderToString 转换为 HTML，然后提取文本
    try {
        const htmlString = renderToString(reactNode);
        // 创建一个临时 DOM 元素来提取文本
        const tempDiv = document.createElement('div');
        tempDiv.innerHTML = htmlString;
        // 使用 TreeWalker 遍历所有文本节点
        let text = '';
        const walker = document.createTreeWalker(tempDiv, NodeFilter.SHOW_TEXT, null);
        let node = walker.nextNode();
        while (node) {
            const textContent = (_a = node.textContent) === null || _a === void 0 ? void 0 : _a.trim();
            if (textContent) {
                text = `${text}${textContent} `;
            }
            node = walker.nextNode();
        }
        return text.trim();
    }
    catch {
        return '';
    }
}
/**
 * 核心提取函数 - 从单元格提取文本
 *
 * 提取策略（按优先级）：
 * 1. 使用注册的纯文本提取器（最高效）
 * 2. 调用 cell 函数，如果返回字符串直接使用
 * 3. 调用 cell 函数返回 ReactNode，通过 renderToString 提取文本
 * 4. Fallback 到原始值
 *
 * @param value 原始值
 * @param column 列配置
 * @param record 行数据
 * @param processedColumn 处理后的列配置（包含 cell 函数）
 * @param context 本地化上下文
 * @param rowIndex 行索引
 */
export function extractCellTextValue(value, column, record, processedColumn, context, rowIndex = 0) {
    var _a, _b;
    const format = (column.format || (processedColumn === null || processedColumn === void 0 ? void 0 : processedColumn.format) || 'text').toLowerCase();
    // 本地化配置
    const localeConfig = {
        numAdapterLocale: (_a = column === null || column === void 0 ? void 0 : column.adapterLocale) !== null && _a !== void 0 ? _a : context === null || context === void 0 ? void 0 : context.numAdapterLocale,
        dateAdapterLocale: (_b = column === null || column === void 0 ? void 0 : column.adapterLocale) !== null && _b !== void 0 ? _b : context === null || context === void 0 ? void 0 : context.dateAdapterLocale,
    };
    // 获取提取器注册表
    const defaultRegistry = getDefaultExtractorRegistry(localeConfig);
    const combinedRegistry = { ...defaultRegistry, ...customExtractorRegistry };
    // 策略1: 使用注册的纯文本提取器
    const extractorConfig = combinedRegistry[format];
    if (extractorConfig) {
        try {
            const text = extractorConfig.extractor(value, column, record);
            if (text !== null) {
                return { text, method: 'extractor', format };
            }
        }
        catch {
            // 提取器失败，继续下一个策略
        }
    }
    // 获取 cell 函数
    const cellFn = (processedColumn === null || processedColumn === void 0 ? void 0 : processedColumn.cell) || column.cell;
    const renderFn = (processedColumn === null || processedColumn === void 0 ? void 0 : processedColumn.render) || column.render;
    const fn = cellFn || renderFn;
    // 策略2&3: 使用 cell/render 函数
    if (isFunction(fn)) {
        try {
            const result = fn(value, rowIndex, record);
            // 如果返回字符串，直接使用
            if (typeof result === 'string') {
                return { text: result, method: 'cell-string', format };
            }
            // 如果返回数字，转换为字符串
            if (typeof result === 'number') {
                return { text: String(result), method: 'cell-string', format };
            }
            // 如果返回 ReactNode，提取文本
            if (result !== null && result !== undefined) {
                const extractedText = extractTextFromReactNode(result);
                if (extractedText) {
                    return { text: extractedText, method: 'react-render', format };
                }
            }
        }
        catch {
            // cell 函数执行失败，继续下一个策略
        }
    }
    // 策略4: Fallback 到原始值
    if (value === null || value === undefined) {
        return { text: '', method: 'fallback', format };
    }
    if (typeof value === 'object') {
        // 尝试提取常见属性
        const fallbackText = value.label || value.text || value.name || value.value || JSON.stringify(value);
        return { text: String(fallbackText), method: 'fallback', format };
    }
    return { text: String(value), method: 'fallback', format };
}
/**
 * 批量提取行数据
 *
 * @param viewData 视图数据数组
 * @param allColumns 全量列定义数组
 * @param processedColumnMap 处理后的列定义映射
 * @param primaryKey 主键（字段名或函数），用于生成 id
 * @param context 本地化上下文
 */
export function extractRowsData(viewData, allColumns, processedColumnMap, primaryKey, context) {
    return viewData.map((row, rowIndex) => {
        const rowKey = safeGetRowKey(row, primaryKey, rowIndex);
        const rowData = {
            id: rowKey !== undefined && rowKey !== null ? String(rowKey) : '',
        };
        allColumns.forEach((col) => {
            const value = row[col.dataIndex];
            const processedCol = processedColumnMap.get(col.dataIndex);
            const result = extractCellTextValue(value, col, row, processedCol, context, rowIndex);
            rowData[col.dataIndex] = result.text;
        });
        return rowData;
    });
}
/**
 * 获取所有支持的格式类型
 */
export function getSupportedFormats(context) {
    const localeConfig = {
        numAdapterLocale: context === null || context === void 0 ? void 0 : context.numAdapterLocale,
        dateAdapterLocale: context === null || context === void 0 ? void 0 : context.dateAdapterLocale,
    };
    const defaultRegistry = getDefaultExtractorRegistry(localeConfig);
    return [...Object.keys(defaultRegistry), ...Object.keys(customExtractorRegistry)];
}
