import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check";
import { _ as _create_class } from "@swc/helpers/_/_create_class";
import { _ as _define_property } from "@swc/helpers/_/_define_property";
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
import { _ as _to_consumable_array } from "@swc/helpers/_/_to_consumable_array";
import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
import { useEffect, useRef, useState } from "react";
import Schema from "async-validator";
import { merge, recursive } from "../../utils/merge";
export var SECRET = 'NUT_FORM_INTERNAL';
/**
 * 用于存储表单的数据
 */ var FormStore = /*#__PURE__*/ function() {
    "use strict";
    function FormStore() {
        var _this = this;
        var _this1 = this;
        _class_call_check(this, FormStore);
        // 初始化数据
        _define_property(this, "initialValues", {});
        _define_property(this, "updateList", []);
        // 存放表单中所有的数据 eg. {password: "ddd",username: "123"}
        _define_property(this, "store", {});
        // 所有的组件实例
        _define_property(this, "fieldEntities", []);
        // 校验成功或失败的回调，onFinish、onFinishFailed
        _define_property(this, "callbacks", {});
        _define_property(this, "errors", {});
        /**
   * 注册组件实例
   * @param field
   */ _define_property(this, "registerField", function(field) {
            _this.fieldEntities.push(field);
            return function() {
                _this.fieldEntities = _this.fieldEntities.filter(function(item) {
                    return item !== field;
                });
            };
        });
        /**
   * 获取 formItem 的值
   * @param name
   */ _define_property(this, "getFieldValue", function(name) {
            var _this_store;
            return (_this_store = _this.store) === null || _this_store === void 0 ? void 0 : _this_store[name];
        });
        /**
   * 获取全部字段
   */ _define_property(this, "getFieldsValue", function(nameList) {
            if (typeof nameList === 'boolean') {
                return JSON.parse(JSON.stringify(_this.store));
            }
            var fieldsValue = {};
            nameList.forEach(function(field) {
                fieldsValue[field] = _this.getFieldValue(field);
            });
            return fieldsValue;
        });
        /**
   * 设置 form 的初始值，之后在 reset 的时候使用
   * @param values
   * @param init
   */ _define_property(this, "setInitialValues", function(initialValues, init) {
            _this.initialValues = initialValues || {};
            if (init) {
                var nextStore = merge(initialValues, _this.store);
                _this.updateStore(nextStore);
                _this.notifyWatch();
            }
        });
        /**
   * 存储组件数据
   * @param newStore { [name]: newValue }
   */ _define_property(this, "setFieldsValue", function(newStore) {
            var nextStore = recursive(true, _this.store, newStore);
            _this.updateStore(nextStore);
            _this.fieldEntities.forEach(function(entity) {
                var name = entity.props.name;
                Object.keys(newStore).forEach(function(key) {
                    if (key === name) {
                        entity.onStoreChange('update');
                    }
                });
            });
            _this.updateList.forEach(function(item) {
                var shouldUpdate = item.condition;
                if (typeof item.condition === 'function') {
                    shouldUpdate = item.condition();
                }
                if (shouldUpdate) {
                    item.entity.onStoreChange('update');
                }
            });
            _this.notifyWatch();
        });
        _define_property(this, "setFieldValue", function(name, value) {
            var store = _define_property({}, name, value);
            _this.setFieldsValue(store);
            _this.notifyWatch([
                name
            ]);
        });
        _define_property(this, "setCallback", function(callback) {
            _this.callbacks = _object_spread({}, _this.callbacks, callback);
        });
        _define_property(this, "validateEntities", function(entity, errs) {
            return _async_to_generator(function() {
                var _entity_props, name, _entity_props_rules, rules, descriptor, validator, _this_store, param, errors, _errs;
                return _ts_generator(this, function(_state) {
                    switch(_state.label){
                        case 0:
                            _entity_props = entity.props, name = _entity_props.name, _entity_props_rules = _entity_props.rules, rules = _entity_props_rules === void 0 ? [] : _entity_props_rules;
                            if (!name) {
                                console.warn('Form field missing name property');
                                return [
                                    2
                                ];
                            }
                            descriptor = {};
                            if (rules.length) {
                                // 多条校验规则
                                if (rules.length > 1) {
                                    descriptor[name] = [];
                                    rules.forEach(function(v) {
                                        descriptor[name].push(v);
                                    });
                                } else {
                                    descriptor[name] = rules[0];
                                }
                            }
                            validator = new Schema(descriptor);
                            _state.label = 1;
                        case 1:
                            _state.trys.push([
                                1,
                                3,
                                4,
                                5
                            ]);
                            return [
                                4,
                                validator.validate(_define_property({}, name, (_this_store = this.store) === null || _this_store === void 0 ? void 0 : _this_store[name]))
                            ];
                        case 2:
                            _state.sent();
                            return [
                                3,
                                5
                            ];
                        case 3:
                            param = _state.sent();
                            errors = param.errors;
                            if (errors) {
                                ;
                                (_errs = errs).push.apply(_errs, _to_consumable_array(errors));
                                this.errors[name] = errors;
                            }
                            return [
                                3,
                                5
                            ];
                        case 4:
                            if (!errs || errs.length === 0) {
                                this.errors[name] = [];
                            }
                            return [
                                7
                            ];
                        case 5:
                            entity.onStoreChange('validate');
                            return [
                                2
                            ];
                    }
                });
            }).call(_this);
        });
        _define_property(this, "validateFields", function(nameList) {
            return _async_to_generator(function() {
                var _this, filterEntities, errs;
                return _ts_generator(this, function(_state) {
                    switch(_state.label){
                        case 0:
                            _this = this;
                            filterEntities = [];
                            // this.errors.length = 0
                            if (!nameList || nameList.length === 0) {
                                filterEntities = this.fieldEntities;
                            } else {
                                filterEntities = this.fieldEntities.filter(function(param) {
                                    var name = param.props.name;
                                    return nameList.includes(name);
                                });
                            }
                            errs = [];
                            return [
                                4,
                                Promise.all(filterEntities.map(function(entity) {
                                    return _async_to_generator(function() {
                                        return _ts_generator(this, function(_state) {
                                            switch(_state.label){
                                                case 0:
                                                    return [
                                                        4,
                                                        this.validateEntities(entity, errs)
                                                    ];
                                                case 1:
                                                    _state.sent();
                                                    return [
                                                        2
                                                    ];
                                            }
                                        });
                                    }).call(_this);
                                }))
                            ];
                        case 1:
                            _state.sent();
                            return [
                                2,
                                errs
                            ];
                    }
                });
            }).call(_this);
        });
        _define_property(this, "submit", function() {
            return _async_to_generator(function() {
                var errors, _this_callbacks_onFinish, _this_callbacks, _this_callbacks_onFinishFailed, _this_callbacks1;
                return _ts_generator(this, function(_state) {
                    switch(_state.label){
                        case 0:
                            return [
                                4,
                                this.validateFields()
                            ];
                        case 1:
                            errors = _state.sent();
                            if (errors.length === 0) {
                                ;
                                (_this_callbacks_onFinish = (_this_callbacks = this.callbacks).onFinish) === null || _this_callbacks_onFinish === void 0 ? void 0 : _this_callbacks_onFinish.call(_this_callbacks, this.store);
                            } else if (errors.length > 0) {
                                ;
                                (_this_callbacks_onFinishFailed = (_this_callbacks1 = this.callbacks).onFinishFailed) === null || _this_callbacks_onFinishFailed === void 0 ? void 0 : _this_callbacks_onFinishFailed.call(_this_callbacks1, this.store, errors);
                            }
                            return [
                                2
                            ];
                    }
                });
            }).call(_this);
        });
        _define_property(this, "resetFields", function(namePaths) {
            if (namePaths && namePaths.length) {
                namePaths.forEach(function(path) {
                    _this.errors[path] = null;
                    _this.fieldEntities.forEach(function(entity) {
                        var name = entity.props.name;
                        if (name === path) {
                            if (path in _this.initialValues) {
                                _this.updateStore(_define_property({}, path, _this.initialValues[path]));
                            } else {
                                delete _this.store[path];
                            }
                            entity.onStoreChange('reset');
                        }
                    });
                });
            } else {
                var nextStore = merge({}, _this.initialValues);
                _this.updateStore(nextStore);
                _this.fieldEntities.forEach(function(entity) {
                    entity.onStoreChange('reset');
                });
            }
        });
        // 监听事件
        _define_property(this, "registerUpdate", function(field, shouldUpdate) {
            _this.updateList.push({
                entity: field,
                condition: shouldUpdate
            });
            return function() {
                _this.updateList = _this.updateList.filter(function(i) {
                    return i.entity !== field;
                });
            };
        });
        _define_property(this, "dispatch", function(param) {
            var name = param.name;
            _this.validateFields([
                name
            ]);
        });
        _define_property(this, "getInternal", function(key) {
            if (key === SECRET) {
                return {
                    registerField: _this.registerField,
                    setCallback: _this.setCallback,
                    setInitialValues: _this.setInitialValues,
                    dispatch: _this.dispatch,
                    store: _this.store,
                    fieldEntities: _this.fieldEntities,
                    registerUpdate: _this.registerUpdate,
                    registerWatch: _this.registerWatch
                };
            }
        });
        _define_property(this, "getForm", function() {
            return {
                getFieldValue: _this.getFieldValue,
                getFieldsValue: _this.getFieldsValue,
                setFieldsValue: _this.setFieldsValue,
                setFieldValue: _this.setFieldValue,
                resetFields: _this.resetFields,
                validateFields: _this.validateFields,
                submit: _this.submit,
                errors: _this.errors,
                getInternal: _this.getInternal
            };
        });
        _define_property(this, "watchList", []);
        _define_property(this, "registerWatch", function(callback) {
            _this.watchList.push(callback);
            return function() {
                _this.watchList = _this.watchList.filter(function(fn) {
                    return fn !== callback;
                });
            };
        });
        _define_property(this, "notifyWatch", function() {
            var namePath = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : [];
            if (_this1.watchList.length) {
                var allValues;
                if (!namePath || namePath.length === 0) {
                    allValues = _this1.getFieldsValue(true);
                } else {
                    allValues = _this1.getFieldsValue(namePath);
                }
                _this1.watchList.forEach(function(callback) {
                    callback(allValues, namePath);
                });
            }
        });
        this.callbacks = {
            onFinish: function() {},
            onFinishFailed: function() {}
        };
    }
    _create_class(FormStore, [
        {
            key: "updateStore",
            value: function updateStore(nextStore) {
                this.store = nextStore;
            }
        }
    ]);
    return FormStore;
}();
export var useForm = function(form) {
    var formRef = useRef();
    if (!formRef.current) {
        if (form) {
            formRef.current = form;
        } else {
            var formStore = new FormStore();
            formRef.current = formStore.getForm();
        }
    }
    return [
        formRef.current
    ];
};
export var useWatch = function(path, form) {
    var formInstance = form.getInternal(SECRET);
    var _useState = _sliced_to_array(useState(), 2), value = _useState[0], setValue = _useState[1];
    useEffect(function() {
        var unsubscribe = formInstance.registerWatch(function(data, namePath) {
            var value = data[path];
            setValue(value);
        });
        var initialValue = form.getFieldsValue(true);
        if (value !== initialValue[path]) {
            setValue(initialValue[path]);
        }
        return function() {
            return unsubscribe();
        };
    }, [
        form
    ]);
    return value;
};
