/* eslint-disable react-hooks/exhaustive-deps */ import { useMemo, isValidElement } from 'react' import { isAhooksUseRequestResult } from '@fexd/pro-utils' import { useRequest } from 'ahooks' import { Result } from 'ahooks/es/useRequest/src/types' import { run, isArray, isString, isObject, isNumber, isBoolean } from '@fexd/tools' const adaptOptions = (rawOptions: any[] = [], adapConfig: { keyMap?: Record } = {}): any[] => { let options = rawOptions // console.log('options', options) if (isObject(options)) { options = Object.entries(rawOptions).map(([key, value]) => isObject(value) && !isValidElement(value) ? { ...value, value: key, } : { label: value, value: key, }, ) } const mapKey = (obj) => ({ ...obj, ...Object.fromEntries( Object.entries(adapConfig?.keyMap ?? {}).map(([key, value]) => { return [value, obj?.[key] ?? obj?.[value]] }), ), }) return [ ...new Set( isArray(options) ? options .map((opt: any) => { if ([isString, isNumber, isBoolean].some((is) => is(opt))) { return { title: String(opt), label: String(opt), value: opt, } } if (isArray(opt?.children)) { return { ...mapKey(opt), children: adaptOptions(opt?.children, adapConfig), } } return mapKey(opt) }) .filter(isObject) : [], ), ] } export default function useRemoteOptions(optionConfigs: any, adapConfig: { keyMap?: Record } = {}) { const isService = useMemo(() => isAhooksUseRequestResult(optionConfigs), [optionConfigs]) const isRemote = !((isObject(optionConfigs) && !isService) || Array.isArray(optionConfigs)) const insideService = useRequest( async (...args: any[]) => { const response: any = await run(optionConfigs, undefined, ...args) if (Array.isArray(response)) { return response } const { success, data } = response ?? {} if (success) { return data } return [] }, { manual: !isRemote, }, ) const service: Result = isService ? (optionConfigs as Result) : insideService const options = useMemo( () => adaptOptions(!isRemote ? optionConfigs : (service?.data ?? []), adapConfig), [isRemote, optionConfigs, service?.data], ) return { service, options, loading: !isRemote ? false : service.loading, isRemote, } }