import { useMemo, useRef, useCallback, useState, useEffect } from 'react';
import flip from 'lodash/flip';
import isFunction from 'lodash/isFunction';
import isPlainObject from 'lodash/isPlainObject';
import { DEFAULT_PRIMARY_KEY, safeGetRowKey, } from '../../../../../../cn-ai-table/view/utils/primary-key';
/**
 * 提取主键值（支持函数类型 primaryKey）
 */
const extractPrimaryKey = (item, primaryKey) => {
    return isPlainObject(item) ? safeGetRowKey(item, primaryKey) : item;
};
/**
 * 用于处理表格行选择的 hook
 * 支持受控和非受控模式
 *
 * @example
 * ```tsx
 * const { hasSelect, selectKeys, setSelectKeys } = useSelect({
 *   showSelect: true,
 *   rowSelection: { selectedRowKeys: [] },
 *   primaryKey: 'id',
 * });
 * ```
 */
export function useSelect(props) {
    var _a;
    const { showSelect, rowSelection, primaryKey = DEFAULT_PRIMARY_KEY, onSelectChange } = props;
    // 判断是否为受控模式（外部传入 selectedRowKeys）
    const isControlled = (rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.selectedRowKeys) !== undefined;
    // 默认值
    const defaultValue = (_a = rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.defaultValue) !== null && _a !== void 0 ? _a : [];
    // 内部状态（非受控模式使用）
    const [internalKeys, setInternalKeys] = useState(defaultValue);
    // 当前选中的 keys：受控模式用外部值，非受控模式用内部值
    const selectKeys = useMemo(() => {
        var _a;
        return isControlled ? ((_a = rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.selectedRowKeys) !== null && _a !== void 0 ? _a : []) : internalKeys;
    }, [isControlled, rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.selectedRowKeys, internalKeys]);
    // 同步外部受控值变化
    useEffect(() => {
        if (isControlled && (rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.selectedRowKeys)) {
            setInternalKeys(rowSelection.selectedRowKeys);
        }
    }, [isControlled, rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.selectedRowKeys]);
    // 存储每次的 selection 信息
    const storeSelectInfo = useRef([]);
    // 是否启用选择功能
    // showSelect === false 时显式关闭，优先级高于 rowSelection
    const hasSelect = useMemo(() => {
        if (showSelect === false)
            return false;
        return !!(showSelect || rowSelection);
    }, [showSelect, rowSelection]);
    /**
     * 设置选中的行
     */
    const setSelectKeys = useCallback((selectedRowKeys, selectedRows = []) => {
        // 存储选中信息
        storeSelectInfo.current = [selectedRowKeys, selectedRows];
        // 非受控模式：更新内部状态
        if (!isControlled) {
            setInternalKeys(selectedRowKeys);
        }
        // 触发 rowSelection.onChange 回调
        if (isFunction(rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.onChange)) {
            if (rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.useDetailValue) {
                // useDetailValue 模式：参数顺序翻转
                const flippedCallback = flip(rowSelection.onChange);
                flippedCallback(selectedRowKeys, selectedRows);
            }
            else {
                rowSelection.onChange(selectedRowKeys, selectedRows);
            }
        }
        // 触发 onSelectChange 回调（showSelect 模式）
        if (showSelect && isFunction(onSelectChange)) {
            if (rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.useDetailValue) {
                const flippedCallback = flip(onSelectChange);
                flippedCallback(selectedRowKeys, selectedRows);
            }
            else {
                onSelectChange(selectedRowKeys, selectedRows);
            }
        }
    }, [isControlled, rowSelection, showSelect, onSelectChange]);
    // 处理 useDetailValue 模式下的 selectKeys 转换
    const normalizedSelectKeys = useMemo(() => {
        if (!(rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.useDetailValue)) {
            return selectKeys;
        }
        // useDetailValue 模式：从详细数据中提取主键值
        return selectKeys.map((item) => extractPrimaryKey(item, primaryKey));
    }, [selectKeys, rowSelection === null || rowSelection === void 0 ? void 0 : rowSelection.useDetailValue, primaryKey]);
    return {
        hasSelect,
        storeSelectInfo,
        selectKeys: normalizedSelectKeys,
        setSelectKeys,
    };
}
