import $i18n from '../../../../../../../locales/i18n.js';
/**
 * 操作列插件
 * 负责在表格最后添加操作列
 */
import * as React from 'react';
import { CnButton, CnMenuButton } from '@cainiaofe/cn-ui';
// ================== 工具函数 ==================
/** 判断值是否已定义 */
function isDef(val) {
    return val !== undefined && val !== null;
}
/** 判断是否为函数 */
function isFunction(val) {
    return typeof val === 'function';
}
/** 判断是否为普通对象 */
function isPlainObject(val) {
    return Object.prototype.toString.call(val) === '[object Object]';
}
/**
 * 将 Proxy/MobX observable 对象转换为普通对象
 * 避免低代码渲染引擎访问 Proxy 对象时报错
 */
function toPlainRecord(record) {
    if (typeof record === 'object' && record !== null) {
        try {
            return JSON.parse(JSON.stringify(record));
        }
        catch {
            return record;
        }
    }
    return record;
}
// ================== 常量 ==================
/** 操作列的唯一标识（稳定常量，避免 Date.now() 导致每次加载不同） */
export const OPERATE_COLUMN_CODE = '__cn_operate_column__';
/** 默认分割符 */
const DEFAULT_SPLIT = null;
/** 更多按钮图标宽度（预留） */
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const _MORE_ICON_WIDTH = 16;
/** 默认操作列宽度 */
const DEFAULT_OPERATE_COLUMN_WIDTH = 150;
// ================== 操作列渲染函数 ==================
/**
 * 创建操作列渲染函数
 */
function createOperateColumnRender(options) {
    const { buttons, showButtonNum = 3, moreBtnProps, render, split, splitWidth = 10 } = options;
    const finalSplit = split || DEFAULT_SPLIT;
    const finalSplitWidth = parseInt(String(splitWidth)) || 10;
    // eslint-disable-next-line react/display-name
    return (val, record, index) => {
        // 将 record 转换为普通对象，避免 Proxy/MobX observable 对象在回调中访问时报错
        const plainRecord = toPlainRecord(record);
        let showButtons = [];
        const hideButtons = [];
        let showButtonNumReality = showButtonNum > 0 ? showButtonNum : (buttons || []).length;
        // 自定义 render 优先级最高
        if (isFunction(render)) {
            const result = render(val, plainRecord, index);
            // 如果返回的是 React 元素，直接返回
            if (result && result.$$typeof) {
                return result;
            }
            showButtons = result;
        }
        // 处理 buttons 数组
        if (Array.isArray(buttons)) {
            // 如果按钮数量只比显示数量多 1，则全部显示
            if (buttons.length - showButtonNumReality === 1) {
                showButtonNumReality += 1;
            }
            buttons.forEach((buttonItem, i) => {
                // 检查可见性
                if (buttonItem &&
                    typeof buttonItem === 'object' &&
                    'visible' in buttonItem &&
                    isFunction(buttonItem.visible) &&
                    !buttonItem.visible(plainRecord, index)) {
                    return;
                }
                const shouldShow = showButtons.length / 2 < showButtonNumReality;
                let item;
                // 处理函数类型的按钮
                if (isFunction(buttonItem)) {
                    const itemTmp = buttonItem(plainRecord, index);
                    if (isPlainObject(itemTmp) && itemTmp.$$typeof) {
                        item = itemTmp;
                    }
                }
                else if (isPlainObject(buttonItem) &&
                    'children' in buttonItem &&
                    isFunction(buttonItem.children)) {
                    const itemTmp = buttonItem.children(plainRecord, index);
                    if (isPlainObject(itemTmp) && itemTmp.$$typeof) {
                        item = itemTmp;
                    }
                }
                else if (isPlainObject(buttonItem)) {
                    // 处理对象类型的按钮
                    const { children, onClick, type = 'primary', btnProps, isDisabled } = buttonItem;
                    const disabled = isFunction(isDisabled) ? !!isDisabled(plainRecord, index) : false;
                    if (shouldShow) {
                        item = (React.createElement(CnButton, { text: true, key: i, type: type, disabled: disabled, className: "cn-table-operate-btn", style: { height: 'auto' }, size: "small", onClick: (e) => {
                                isFunction(onClick) && onClick(e, plainRecord, index);
                            }, ...(btnProps || {}) }, isFunction(children) ? children(plainRecord, index) : children));
                    }
                    else {
                        item = (React.createElement(CnMenuButton.Item, { key: i, onClick: (e) => !disabled && isFunction(onClick) && onClick(e, plainRecord, index) },
                            React.createElement(CnButton, { text: true, disabled: disabled, type: type, className: "cn-table-operate-btn", style: { height: 'auto' }, size: "small", ...(btnProps || {}) }, isFunction(children) ? children(plainRecord, index) : children)));
                    }
                }
                if (isDef(item)) {
                    if (shouldShow) {
                        showButtons.push(item);
                        showButtons.push(React.createElement("div", { key: `split-${i}`, style: { width: finalSplitWidth }, className: "hp-table-split" }, finalSplit));
                    }
                    else {
                        hideButtons.push(item);
                    }
                }
            });
        }
        // 移除最后一个分隔符
        if (showButtons.length > 0) {
            showButtons.pop();
        }
        return (React.createElement("div", { className: "cn-table-operate" },
            showButtons,
            hideButtons.length > 0 ? (React.createElement(React.Fragment, null,
                React.createElement("div", { style: { width: finalSplitWidth }, className: "hp-table-split" }, finalSplit),
                React.createElement(CnMenuButton, { text: true, popupProps: {
                        v2: true,
                    }, style: { height: 'auto' }, size: "small", className: "cn-table-operate-btn", type: "primary", autoWidth: false, label: $i18n.get({ id: 'More', dm: '更多' }), popupClassName: "cn-table-operate-pop", ...(moreBtnProps || {}) }, hideButtons))) : null));
    };
}
/**
 * 创建操作列定义
 */
function createOperateColumn(options) {
    const { width = DEFAULT_OPERATE_COLUMN_WIDTH, columnsProps, lock = 'right' } = options;
    const operateColumn = {
        name: $i18n.get({ id: 'ActionsOperation', dm: '操作' }),
        lock,
        sizeFixed: true,
        maxWidth: false,
        code: OPERATE_COLUMN_CODE,
        ...((isFunction(columnsProps) && columnsProps()) || {}),
        width,
        getCellProps() {
            return {
                className: 'cn-table-cell-operate',
            };
        },
        render: createOperateColumnRender(options),
    };
    return operateColumn;
}
// ================== Pipeline 插件 ==================
/**
 * 操作列插件
 * @param options 插件配置
 */
export function operateColumnPlugin(options) {
    return (pipeline) => {
        if (!options || !options.buttons || options.buttons.length === 0) {
            return pipeline;
        }
        // 更新 Pipeline 配置
        const operateColumnConfig = {
            enabled: true,
            options,
        };
        // 创建操作列渲染函数
        const renderFn = createOperateColumnRender(options);
        // 创建操作列定义
        const operateColumn = createOperateColumn(options);
        // 创建处理函数
        const handlers = {
            getOperateColumn: () => operateColumn,
            renderOperateCell: (record, index) => {
                return renderFn(null, record, index);
            },
            getOperateColumnWidth: () => options.width || DEFAULT_OPERATE_COLUMN_WIDTH,
            getOperateColumnTitle: () => $i18n.get({ id: 'ActionsOperation', dm: '操作' }),
        };
        // 存储处理函数到 context
        pipeline.setContext('operateColumnHandlers', handlers);
        pipeline.setContext('operateColumn', operateColumn);
        // 更新配置
        return pipeline.setConfig({
            operateColumn: operateColumnConfig,
        });
    };
}
