import { jsx, jsxs } from "react/jsx-runtime";
import react, { createContext, useContext, useEffect, useMemo, useState } from "react";
import { RecursionField, useField, useFieldSchema } from "@tachybase/schema";
import { Col, Row } from "antd";
import { createStyles } from "antd-style";
import deepmerge from "deepmerge";
import template from "lodash/template";
import { Link } from "react-router-dom";
import { ACLCollectionProvider, DataBlockProvider, TableFieldResource, WithoutTableFieldResource, useCollectionManager, useCollectionParentRecord, useCollectionParentRecordData, useCollectionRecord, useDataBlockProps, useDataBlockRequest, useDataBlockResource, useDesignable, useRecord } from "../index.mjs";
import { CollectionProvider_deprecated, useCollectionManager_deprecated, useCollection_deprecated } from "../collection-manager/index.mjs";
import { DataBlockCollector } from "../filter-provider/FilterProvider.mjs";
import { RecordProvider, useRecordIndex } from "../record-provider/index.mjs";
import { useAssociationNames } from "./hooks/index.mjs";
import { useDataBlockParentRecord } from "./hooks/useDataBlockSourceId.mjs";
function _tagged_template_literal(strings, raw) {
    if (!raw) raw = strings.slice(0);
    return Object.freeze(Object.defineProperties(strings, {
        raw: {
            value: Object.freeze(raw)
        }
    }));
}
function _templateObject() {
    const data = _tagged_template_literal([
        "\n      height: 100%;\n    "
    ]);
    _templateObject = function() {
        return data;
    };
    return data;
}
function _templateObject1() {
    const data = _tagged_template_literal([
        "\n      width: 200px;\n      flex: 0 0 auto;\n    "
    ]);
    _templateObject1 = function() {
        return data;
    };
    return data;
}
function _templateObject2() {
    const data = _tagged_template_literal([
        "\n      flex: 1 1 auto;\n      min-width: 0;\n    "
    ]);
    _templateObject2 = function() {
        return data;
    };
    return data;
}
function _templateObject3() {
    const data = _tagged_template_literal([
        "\n      display: flex;\n      flex-direction: column;\n      height: 100%;\n    "
    ]);
    _templateObject3 = function() {
        return data;
    };
    return data;
}
const BlockResourceContext = /*#__PURE__*/ createContext(null);
BlockResourceContext.displayName = 'BlockResourceContext';
const BlockAssociationContext = /*#__PURE__*/ createContext(null);
BlockAssociationContext.displayName = 'BlockAssociationContext';
const BlockRequestContext_deprecated = /*#__PURE__*/ createContext({});
BlockRequestContext_deprecated.displayName = 'BlockRequestContext_deprecated';
const useBlockResource = ()=>{
    const resource = useDataBlockResource();
    return useContext(BlockResourceContext) || resource;
};
const MaybeCollectionProvider = (props)=>{
    const { collection } = props;
    return collection ? /*#__PURE__*/ jsx(CollectionProvider_deprecated, {
        collection: collection,
        children: /*#__PURE__*/ jsx(ACLCollectionProvider, {
            children: props.children
        })
    }) : props.children;
};
const BlockRequestProvider_deprecated = (props)=>{
    var _service_data_meta, _service_data;
    const field = useField();
    const resource = useDataBlockResource();
    const [allowedActions, setAllowedActions] = useState({});
    const service = useDataBlockRequest();
    const record = useCollectionRecord();
    const parentRecord = useCollectionParentRecord();
    const serviceAllowedActions = null == service ? void 0 : null == (_service_data = service.data) ? void 0 : null == (_service_data_meta = _service_data.meta) ? void 0 : _service_data_meta.allowedActions;
    useEffect(()=>{
        if (!serviceAllowedActions) return;
        setAllowedActions((last)=>deepmerge(last, null != serviceAllowedActions ? serviceAllowedActions : {}));
    }, [
        serviceAllowedActions
    ]);
    const __parent = useBlockRequestContext();
    return /*#__PURE__*/ jsx(BlockRequestContext_deprecated.Provider, {
        value: {
            allowedActions,
            block: props.block,
            props,
            field,
            service,
            resource,
            __parent,
            updateAssociationValues: (null == props ? void 0 : props.updateAssociationValues) || []
        },
        children: /*#__PURE__*/ jsx(RecordProvider, {
            isNew: null == record ? void 0 : record.isNew,
            record: null == record ? void 0 : record.data,
            parent: null == parentRecord ? void 0 : parentRecord.data,
            children: props.children
        })
    });
};
const useBlockRequestContext = ()=>useContext(BlockRequestContext_deprecated);
const useStyles = createStyles((param)=>{
    let { css } = param;
    return {
        row: css(_templateObject()),
        left: css(_templateObject1()),
        right: css(_templateObject2()),
        rightContainer: css(_templateObject3())
    };
});
const RenderChildrenWithAssociationFilter = (props)=>{
    var _field_component;
    const fieldSchema = useFieldSchema();
    const { findComponent } = useDesignable();
    const { styles } = useStyles();
    const field = useField();
    const Component = findComponent(null == (_field_component = field.component) ? void 0 : _field_component[0]) || react.Fragment;
    const associationFilterSchema = fieldSchema.reduceProperties((buf, s)=>{
        if ('AssociationFilter' === s['x-component']) return s;
        return buf;
    }, null);
    if (associationFilterSchema) return /*#__PURE__*/ jsx(Component, {
        ...field.componentProps,
        children: /*#__PURE__*/ jsxs(Row, {
            className: styles.row,
            gutter: 16,
            wrap: false,
            children: [
                /*#__PURE__*/ jsx(Col, {
                    className: styles.left,
                    style: props.associationFilterStyle,
                    children: /*#__PURE__*/ jsx(RecursionField, {
                        schema: fieldSchema,
                        onlyRenderProperties: true,
                        filterProperties: (s)=>'AssociationFilter' === s['x-component']
                    })
                }),
                /*#__PURE__*/ jsx(Col, {
                    className: styles.right,
                    children: /*#__PURE__*/ jsx("div", {
                        className: styles.rightContainer,
                        children: /*#__PURE__*/ jsx(RecursionField, {
                            schema: fieldSchema,
                            onlyRenderProperties: true,
                            filterProperties: (s)=>'AssociationFilter' !== s['x-component']
                        })
                    })
                })
            ]
        })
    });
    return props.children;
};
const BlockContext = /*#__PURE__*/ createContext(null);
BlockContext.displayName = 'BlockContext';
const useBlockContext = ()=>useContext(BlockContext);
const useCompatDataBlockParentRecord = (props)=>{
    const fieldSchema = useFieldSchema();
    if (fieldSchema['x-use-decorator-props']) return props.parentRecord;
    return useDataBlockParentRecord(props);
};
const BlockProvider = (props)=>{
    const { name, dataSource, useParams, parentRecord } = props;
    const parentRecordFromHook = useCompatDataBlockParentRecord(props);
    const paramsFromHook = null == useParams ? void 0 : useParams();
    const { getAssociationAppends } = useAssociationNames(dataSource);
    const { appends, updateAssociationValues } = getAssociationAppends();
    const params = useMemo(()=>{
        var _props_params;
        if (!(null == (_props_params = props.params) ? void 0 : _props_params['appends'])) return {
            ...props.params,
            appends,
            ...paramsFromHook
        };
        return {
            ...props.params,
            ...paramsFromHook
        };
    }, [
        appends,
        paramsFromHook,
        props.params
    ]);
    const blockValue = useMemo(()=>({
            name
        }), [
        name
    ]);
    return /*#__PURE__*/ jsx(BlockContext.Provider, {
        value: blockValue,
        children: /*#__PURE__*/ jsx(DataBlockProvider, {
            ...props,
            params: params,
            parentRecord: parentRecord || parentRecordFromHook,
            children: /*#__PURE__*/ jsx(BlockRequestProvider_deprecated, {
                ...props,
                updateAssociationValues: updateAssociationValues,
                params: params,
                children: /*#__PURE__*/ jsx(DataBlockCollector, {
                    ...props,
                    params: params,
                    children: props.children
                })
            })
        })
    });
};
const useBlockAssociationContext = ()=>{
    const { association } = useDataBlockProps() || {};
    return useContext(BlockAssociationContext) || association;
};
const useFilterByTk = ()=>{
    const { resource, __parent } = useBlockRequestContext();
    const recordIndex = useRecordIndex();
    const record = useRecord();
    const collection = useCollection_deprecated();
    const { getCollectionField } = useCollectionManager_deprecated();
    const assoc = useBlockAssociationContext();
    const withoutTableFieldResource = useContext(WithoutTableFieldResource);
    if (!withoutTableFieldResource) {
        if (resource instanceof TableFieldResource || (null == __parent ? void 0 : __parent.block) === 'TableField') return recordIndex;
    }
    if (assoc) {
        const association = getCollectionField(assoc);
        return null == record ? void 0 : record[association.targetKey || 'id'];
    }
    return null == record ? void 0 : record[collection.filterTargetKey || 'id'];
};
const useSourceIdFromRecord = ()=>{
    const record = useRecord();
    const { getCollectionField } = useCollectionManager_deprecated();
    const association = useBlockAssociationContext();
    if (association) {
        const collectionField = getCollectionField(association);
        return null == record ? void 0 : record[collectionField.sourceKey || 'id'];
    }
};
const useSourceIdFromParentRecord = ()=>{
    const cm = useCollectionManager();
    const parentRecordData = useCollectionParentRecordData();
    const { getCollectionField } = useCollectionManager_deprecated();
    const association = useBlockAssociationContext();
    if (association) {
        const collectionField = getCollectionField(association);
        const collection = cm.getCollection(collectionField.collectionName);
        return null == parentRecordData ? void 0 : parentRecordData[collectionField.sourceKey || collection.filterTargetKey || collection.getPrimaryKey() || 'id'];
    }
};
const useParamsFromRecord = ()=>{
    var _fieldSchema_xdecoratorprops, _fieldSchema_xdecoratorprops1;
    const filterByTk = useFilterByTk();
    const record = useRecord();
    const { fields } = useCollection_deprecated();
    const fieldSchema = useFieldSchema();
    const { getCollectionJoinField } = useCollectionManager_deprecated();
    const collectionField = getCollectionJoinField((null == fieldSchema ? void 0 : null == (_fieldSchema_xdecoratorprops = fieldSchema['x-decorator-props']) ? void 0 : _fieldSchema_xdecoratorprops.resource) || (null == fieldSchema ? void 0 : null == (_fieldSchema_xdecoratorprops1 = fieldSchema['x-decorator-props']) ? void 0 : _fieldSchema_xdecoratorprops1.association));
    const filterFields = fields.filter((v)=>[
            'boolean',
            'date',
            'integer',
            'radio',
            'sort',
            'string',
            'time',
            'uid',
            'uuid'
        ].includes(v.type)).map((v)=>v.name);
    const filter = Object.keys(record).filter((key)=>filterFields.includes(key)).reduce((result, key)=>{
        result[key] = record[key];
        return result;
    }, {});
    const obj = {
        filterByTk: filterByTk
    };
    if (record.__collection && collectionField && ![
        'oho',
        'm2o',
        'obo'
    ].includes(collectionField.interface)) obj['targetCollection'] = record.__collection;
    if (!filterByTk && Object.keys(filter).length > 0) obj['filter'] = filter;
    return obj;
};
const RecordLink = (props)=>{
    const field = useField();
    const record = useRecord();
    const { title, to, ...others } = props;
    const compiled = template(to || '');
    return /*#__PURE__*/ jsx(Link, {
        ...others,
        to: compiled({
            record: record || {}
        }),
        children: field.title
    });
};
export { BlockAssociationContext, BlockProvider, BlockRequestContext_deprecated, BlockRequestProvider_deprecated, BlockResourceContext, MaybeCollectionProvider, RecordLink, RenderChildrenWithAssociationFilter, useBlockAssociationContext, useBlockContext, useBlockRequestContext, useBlockResource, useFilterByTk, useParamsFromRecord, useSourceIdFromParentRecord, useSourceIdFromRecord };
