import { Fragment, jsx, jsxs } from "react/jsx-runtime";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { connect, mapProps, mapReadPretty, useFieldSchema } from "@tachybase/schema";
import { LoadingOutlined } from "@ant-design/icons";
import { Divider, Tag } from "antd";
import dayjs from "dayjs";
import { uniqBy } from "lodash";
import { useRequest } from "../../../api-client/index.mjs";
import { useCollectionManager_deprecated, useCollection_deprecated } from "../../../collection-manager/index.mjs";
import { useDataSourceKey } from "../../../data-source/data-source/DataSourceProvider.mjs";
import { useDataSourceHeaders } from "../../../data-source/utils.mjs";
import { mergeFilter } from "../../../filter-provider/utils.mjs";
import { useCompile } from "../../hooks/index.mjs";
import { Select, defaultFieldNames } from "../select/index.mjs";
import { ReadPretty } from "./ReadPretty.mjs";
const EMPTY = 'N/A';
const InternalRemoteSelect = connect((props)=>{
    var _fieldSchema_xcomponentprops, _service_params;
    const { fieldNames = {}, service = {}, wait = 300, value, defaultValue, objectValue, manual = true, mapOptions, targetField: _targetField, CustomDropdownRender, optionFilter, ...others } = props;
    const dataSource = useDataSourceKey();
    const headers = useDataSourceHeaders(dataSource);
    const [open, setOpen] = useState(false);
    const firstRun = useRef(false);
    const fieldSchema = useFieldSchema();
    const isQuickAdd = (null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.addMode) === 'quickAdd';
    const { getField } = useCollection_deprecated();
    const searchData = useRef(null);
    const { getCollectionJoinField, getInterface } = useCollectionManager_deprecated();
    const colletionFieldName = fieldSchema['x-collection-field'] || fieldSchema.name;
    const collectionField = getField(colletionFieldName) || getCollectionJoinField(colletionFieldName);
    const targetField = _targetField || (null == collectionField ? void 0 : collectionField.target) && (null == fieldNames ? void 0 : fieldNames.label) && getCollectionJoinField("".concat(collectionField.target, ".").concat(fieldNames.label));
    const operator = useMemo(()=>{
        if (null == targetField ? void 0 : targetField.interface) {
            var _getInterface_filterable_operators_, _getInterface_filterable_operators, _getInterface_filterable, _getInterface;
            return (null == (_getInterface = getInterface(targetField.interface)) ? void 0 : null == (_getInterface_filterable = _getInterface.filterable) ? void 0 : null == (_getInterface_filterable_operators = _getInterface_filterable.operators) ? void 0 : null == (_getInterface_filterable_operators_ = _getInterface_filterable_operators[0]) ? void 0 : _getInterface_filterable_operators_.value) || '$includes';
        }
        return '$includes';
    }, [
        targetField
    ]);
    const compile = useCompile();
    const mapOptionsToTags = useCallback((options)=>{
        try {
            return options.filter((v)=>[
                    'number',
                    'string'
                ].includes(typeof v[fieldNames.value])).map((option)=>{
                var _targetField_uiSchema;
                let label = compile(option[fieldNames.label]);
                if (null == targetField ? void 0 : null == (_targetField_uiSchema = targetField.uiSchema) ? void 0 : _targetField_uiSchema.enum) if (Array.isArray(label)) label = label.map((item, index)=>{
                    const option = targetField.uiSchema.enum.find((i)=>i.value === item);
                    if (option) return /*#__PURE__*/ jsx(Tag, {
                        role: "button",
                        color: option.color,
                        style: {
                            marginRight: 3
                        },
                        children: (null == option ? void 0 : option.label) || item
                    }, index);
                    return /*#__PURE__*/ jsx(Tag, {
                        role: "button",
                        children: item
                    }, item);
                }).reverse();
                else {
                    const item = targetField.uiSchema.enum.find((i)=>i.value === label);
                    if (item) label = /*#__PURE__*/ jsx(Tag, {
                        role: "button",
                        color: item.color,
                        children: item.label
                    });
                }
                if ((null == targetField ? void 0 : targetField.type) === 'date') label = dayjs(label).format('YYYY-MM-DD');
                if (mapOptions) return mapOptions({
                    [fieldNames.label]: label || EMPTY,
                    [fieldNames.value]: option[fieldNames.value]
                });
                return {
                    ...option,
                    [fieldNames.label]: label || EMPTY,
                    [fieldNames.value]: option[fieldNames.value]
                };
            }).filter(Boolean);
        } catch (err) {
            console.error(err);
            return options;
        }
    }, [
        null == targetField ? void 0 : targetField.uiSchema,
        fieldNames
    ]);
    const params = {
        ...null == service ? void 0 : service.params,
        filter: null == service ? void 0 : null == (_service_params = service.params) ? void 0 : _service_params.filter
    };
    if (fieldNames['formula']) params['paginate'] = false;
    else params['pageSize'] = 200;
    const { data, run, loading } = useRequest({
        action: 'list',
        ...service,
        headers,
        params
    }, {
        manual,
        debounceWait: wait
    });
    const runDep = useMemo(()=>JSON.stringify({
            service,
            fieldNames
        }), [
        service,
        fieldNames
    ]);
    const CustomRenderCom = useCallback(()=>{
        if (searchData.current && CustomDropdownRender) return /*#__PURE__*/ jsx(CustomDropdownRender, {
            search: searchData.current,
            callBack: ()=>{
                searchData.current = null;
                setOpen(false);
            }
        });
        return null;
    }, [
        searchData.current
    ]);
    useEffect(()=>{
        if (firstRun.current) run();
    }, [
        runDep
    ]);
    const onSearch = async (search)=>{
        var _service_params;
        run({
            filter: mergeFilter([
                search ? {
                    [fieldNames.label]: {
                        [operator]: search
                    }
                } : {},
                null == service ? void 0 : null == (_service_params = service.params) ? void 0 : _service_params.filter
            ])
        });
        searchData.current = search;
    };
    const options = useMemo(()=>{
        var _data_data;
        const v = value || defaultValue;
        if (!(null == data ? void 0 : null == (_data_data = data.data) ? void 0 : _data_data.length)) return null != v ? Array.isArray(v) ? v : [
            v
        ] : [];
        const valueOptions = null != v && (Array.isArray(v) ? v : [
            {
                ...v,
                [fieldNames.value]: v[fieldNames.value] || v
            }
        ]) || [];
        const filtered = 'function' == typeof optionFilter ? data.data.filter(optionFilter) : data.data;
        return uniqBy(filtered.concat(null != valueOptions ? valueOptions : []), fieldNames.value);
    }, [
        value,
        defaultValue,
        null == data ? void 0 : data.data,
        fieldNames.value,
        optionFilter
    ]);
    const onDropdownVisibleChange = (visible)=>{
        setOpen(visible);
        searchData.current = null;
        if (visible) run();
        firstRun.current = true;
    };
    return /*#__PURE__*/ jsx(Select, {
        open: open,
        popupMatchSelectWidth: false,
        autoClearSearchValue: true,
        filterOption: false,
        filterSort: null,
        fieldNames: fieldNames,
        onSearch: onSearch,
        onDropdownVisibleChange: onDropdownVisibleChange,
        objectValue: objectValue,
        value: value,
        defaultValue: defaultValue,
        ...others,
        loading: data ? loading : true,
        options: mapOptionsToTags(options),
        rawOptions: options,
        dropdownRender: (menu)=>{
            const isFullMatch = options.some((v)=>v[fieldNames.label] === searchData.current);
            return /*#__PURE__*/ jsx(Fragment, {
                children: isQuickAdd ? /*#__PURE__*/ jsxs(Fragment, {
                    children: [
                        !((null == data ? void 0 : data.data.length) === 0 && (null == searchData ? void 0 : searchData.current)) && menu,
                        (null == data ? void 0 : data.data.length) > 0 && (null == searchData ? void 0 : searchData.current) && !isFullMatch && /*#__PURE__*/ jsx(Divider, {
                            style: {
                                margin: 0
                            }
                        }),
                        !isFullMatch && /*#__PURE__*/ jsx(CustomRenderCom, {})
                    ]
                }) : menu
            });
        }
    });
}, mapProps({
    dataSource: 'options'
}, (props, field)=>{
    var _fieldSchema_xcomponentprops;
    const fieldSchema = useFieldSchema();
    return {
        ...props,
        fieldNames: {
            ...defaultFieldNames,
            ...props.fieldNames,
            ...field.componentProps.fieldNames,
            ...null == (_fieldSchema_xcomponentprops = fieldSchema['x-component-props']) ? void 0 : _fieldSchema_xcomponentprops.fieldNames
        },
        suffixIcon: (null == field ? void 0 : field['loading']) || (null == field ? void 0 : field['validating']) ? /*#__PURE__*/ jsx(LoadingOutlined, {}) : props.suffixIcon
    };
}), mapReadPretty(ReadPretty));
const RemoteSelect_RemoteSelect = InternalRemoteSelect;
RemoteSelect_RemoteSelect.ReadPretty = ReadPretty;
const RemoteSelect = RemoteSelect_RemoteSelect;
export { RemoteSelect_RemoteSelect as RemoteSelect, RemoteSelect as default };
