import { useEffect, useRef } from 'react';
import isFunction from 'lodash/isFunction';
import isPlainObject from 'lodash/isPlainObject';
// 其他组件
import { safeCallFunction } from '../utils/safe-call-function';
import { useLatest } from 'ahooks';
import { setInnerInfo } from '../utils';
import { isBirda } from '../../../utils/env/index.js';
// 当前目录的相对依赖
import { MAX_API_PAGE_SIZE, executeBatchRequests, } from './batch/batch-request';
import { mergeBatchResponses } from './batch/batch-response-merger';
import { fetchSingleBatch } from './batch/single-batch-fetcher';
import { executeSingleRequest } from './single-request';
import { createErrorHandler } from './utils/error-handler';
import { getResponseTransform } from './utils/response-transform';
import { parseRequestParams } from './utils/request-params-parser';
function setRemoteInstance(instance, fetchData) {
    var _a;
    // @ts-ignore
    if (isPlainObject((_a = instance === null || instance === void 0 ? void 0 : instance.remoteOperation) === null || _a === void 0 ? void 0 : _a.current)) {
        // @ts-ignore
        instance.remoteOperation.current.fetchData = fetchData;
    }
}
// ==================== 常量配置 ====================
// 常量已移至 batch-request.ts
export function useRemote(state, callback) {
    var _a;
    const { pageRenderInfo, setLoading, remote, innerParams, innerInfo } = state;
    const fetchCallRef = useLatest(fetchData);
    const isInitFetch = useRef(false);
    const lockRef = useRef(false);
    const immediateRef = useRef((_a = remote === null || remote === void 0 ? void 0 : remote.immediate) !== null && _a !== void 0 ? _a : true);
    // 存储已获取的 tableCount，用于计算分批次请求
    const tableCountRef = useRef(null);
    setRemoteInstance(remote === null || remote === void 0 ? void 0 : remote.instance, fetchData);
    setInnerInfo(remote === null || remote === void 0 ? void 0 : remote.instance, innerInfo);
    useEffect(() => {
        // 是否首次render禁止请求
        if (!immediateRef.current) {
            return;
        }
        // 如果是第一次请求需要保存defaultCurrentPage等参数
        if (isInitFetch.current === false) {
            safeCallFunction(fetchCallRef.current('load'));
        }
        else {
            // 如果不是在第一页点查询就算参数没变也需要回归到第一页
            safeCallFunction(fetchCallRef.current('refresh'));
        }
        isInitFetch.current = true;
        // isFunction(fetchCallRef.current) && fetchCallRef.current(true);
    }, [remote === null || remote === void 0 ? void 0 : remote.url, remote === null || remote === void 0 ? void 0 : remote.params, remote === null || remote === void 0 ? void 0 : remote.immediate]);
    // 该锁顺序必须在 上面两个Effect之后
    useEffect(() => {
        immediateRef.current = true;
    }, []);
    // 注意：fetchData 函数会在下面定义，setTableCount 方法会在函数定义之后附加
    // 这里先返回 fetchData，但实际返回会在文件末尾
    /**
     * 请求远程数据
     * @param params
     * @returns
     */
    function fetchData(params) {
        var _a, _b, _c, _d;
        const { clearDataType, paramsData } = parseRequestParams(params);
        // 前置判断
        if (!(remote === null || remote === void 0 ? void 0 : remote.url) && !isFunction(remote === null || remote === void 0 ? void 0 : remote.fetch)) {
            return Promise.reject();
        }
        if (lockRef.current) {
            lockRef.current = false;
            return Promise.reject();
        }
        // 设置请求锁
        setLoading(true);
        lockRef.current = true;
        // 优先使用传入的参数，如果没有则使用 pageRenderInfo 中的值
        // 重要：如果 paramsData 中传入了 pageSize，优先使用传入的值
        const userPageSize = (_b = (_a = paramsData.pageSize) !== null && _a !== void 0 ? _a : pageRenderInfo === null || pageRenderInfo === void 0 ? void 0 : pageRenderInfo.pageSize) !== null && _b !== void 0 ? _b : MAX_API_PAGE_SIZE;
        const userCurrentPage = (_d = (_c = paramsData.currentPage) !== null && _c !== void 0 ? _c : pageRenderInfo === null || pageRenderInfo === void 0 ? void 0 : pageRenderInfo.currentPage) !== null && _d !== void 0 ? _d : 1;
        // ==================== 分批次请求逻辑 ====================
        // 专业版场景（!isBirda()）不进行分批次请求，直接使用用户设置的 pageSize
        // 只有当用户设置的 pageSize > 100 且 totalCount > 100 时才需要分批次请求
        // 如果 totalCount <= 100，即使 userPageSize > 100，也不需要分批次请求
        if (isBirda() &&
            userPageSize > MAX_API_PAGE_SIZE &&
            tableCountRef.current !== null &&
            tableCountRef.current > MAX_API_PAGE_SIZE) {
            const batchParams = {
                userPageSize,
                userCurrentPage,
                clearDataType,
                paramsData,
                totalCount: tableCountRef.current,
            };
            const batchOptions = {
                fetchSingleBatch: (batchPage) => fetchSingleBatch({
                    remote,
                    innerParams,
                    batchPage,
                    userPageSize,
                    userCurrentPage,
                    clearDataType,
                    paramsData,
                }),
                responseTransform: getResponseTransform(remote),
                mergeBatchResponses,
                callback,
                errorHandler: createErrorHandler({
                    remote,
                    innerInfo,
                    setLoading,
                    releaseLock: () => {
                        lockRef.current = false;
                    },
                }),
                onFinally: remote === null || remote === void 0 ? void 0 : remote.onFinally,
                setLoading,
                releaseLock: () => {
                    lockRef.current = false;
                },
            };
            return executeBatchRequests(batchParams, batchOptions);
        }
        // ==================== 普通请求逻辑 ====================
        return executeSingleRequest({
            remote,
            innerParams,
            userPageSize,
            userCurrentPage,
            clearDataType,
            paramsData,
            setLoading,
            releaseLock: () => {
                lockRef.current = false;
            },
            callback,
            errorHandler: createErrorHandler({
                remote,
                innerInfo,
                setLoading,
                releaseLock: () => {
                    lockRef.current = false;
                },
            }),
        });
    }
    // 将设置 tableCount 的方法附加到 fetchData 上（在函数定义之后，return 之前）
    fetchData.setTableCount = (tableCount) => {
        tableCountRef.current = tableCount;
    };
    return fetchData;
}
