import {ref, Ref} from "vue";
import {Page, PageParams, PageResult} from "@/types/hooks/useTableProMax";
import {FormInstance} from "ant-design-vue";
import {BaseTableRowRecord, RequestApiType} from "@/types/components/table";

/**
 *
 * @param api 查询方法
 * @param searchFormRef 表单校验
 * @param searchParams 查询的参数
 * @param isPageTable 是否分页
 * @param dataCallBack 查询到数据后的回调
 * @param requestError 查询出错回调
 */
export default <T extends BaseTableRowRecord, P extends Record<string, any> | PageParams<P>>(api: RequestApiType<T, P>,
                                                                                             searchFormRef: Ref<FormInstance>,
                                                                                             searchParams: Ref<P>,
                                                                                             isPageTable: boolean = true,
                                                                                             dataCallBack?: (data: T[]) => T[],
                                                                                             requestError?: (errorMsg: any) => void) => {

    const dataSource = ref<T[]>([]) as Ref<T[]>;
    const loading = ref<boolean>(false);
    const pageParams = ref<Page>({
        current: 1,
        size: 10,
        total: 0
    })

    /**
     * 获取表格数据
     */
    const requestGetTableData = async (isInit: boolean = false) => {
        try {
            //校验表单
            !isInit && await searchFormRef.value?.validate();
            //组装参数
            let totalSearchParams;
            if (isPageTable) {
                totalSearchParams = {
                    params: searchParams.value,
                    page: {
                        current: pageParams.value.current,
                        size: pageParams.value.size
                    }
                } as PageParams<P>;
            } else {
                totalSearchParams = searchParams.value
            }

            loading.value = true;

            const resp = await api(totalSearchParams as P);
            let tableData: T[];

            if (isPageTable) {
                const {current, records, size, total} = resp.data as PageResult<T>;
                isPageTable && updatePageParams({
                    current: parseInt(current),
                    size: parseInt(size),
                    total: parseInt(total)
                });
                tableData = records;
            } else {
                tableData = resp.data as T[]
            }
            dataCallBack && (tableData = dataCallBack(tableData));
            dataSource.value = tableData;
        } catch (error) {
            requestError && requestError(error);
        } finally {
            loading.value = false;
        }
    }

    /**
     * 更新分页信息
     */
    const updatePageParams = (ps: Page) => Object.assign(pageParams.value, ps)

    /**
     * 重置表格状态 包括 dataSource loading pageParams
     */
    const resetState = () => {
        dataSource.value = [];
        loading.value = false;
        pageParams.value = {
            current: 1,
            size: 10,
            total: 0
        }
    }

    /**
     * 表格数据查询 与 requestGetTableData 区别是会将页面重置为1
     * 如果只做刷新数据请用 requestGetTableData
     */
    const search = async () => {
        pageParams.value.current = 1;
        await requestGetTableData();
    };

    /**
     * @description 每页条数改变
     * @param _
     * @param {Number} size 页显示数量
     */
    const handleSizeChange = async (_: number, size: number) => {
        pageParams.value.current = 1;
        pageParams.value.size = size;
        await requestGetTableData();
    };

    /**
     * @description 当前页改变
     * @param current 当前页
     */
    const handleCurrentChange = async (current: number) => {
        pageParams.value.current = current;
        await requestGetTableData();
    };

    return {
        dataSource,
        loading,
        pageParams,
        requestGetTableData,
        search,
        handleSizeChange,
        handleCurrentChange,
        resetState
    };

}
