
import { ref, unref, nextTick, watch } from "vue";
import { FormActionType, FormPropsSchema, getDynamicProps, SchemasForm, UseFormReturnType } from "../types";

/**
 * 表单
 */
export function useForm(prpos?: FormPropsSchema): UseFormReturnType {
    const formRef = ref<Nullable<FormActionType>>(null);
    async function getForm() {
        const form = unref(formRef);
        if (!form) {
            console.error('没有获得表单实例，请确保在执行表单操作时表单已经呈现!');
        }
        await nextTick();
        return form as FormActionType;
    }
    // 注册事件
    function register(instance: FormActionType) {
        if (instance === unref(formRef)) return;
        formRef.value = instance;
        watch(
            () => prpos,
            () => {
                prpos && instance.setProps(getDynamicProps(prpos));
            },
            {
                immediate: true,
                deep: true,
            },
        );
    }
    // 表单默认事件
    const methods: FormActionType = {
        // 设置表单
        setProps: async (formProps: SchemasForm) => {
            const form = await getForm();
            form.setProps(formProps);
        },
        // 获取交互的表单内容
        getVaule: async () => {
            const form = await getForm();
            return form.getVaule();
        },
        // 表单校验
        getFieldsValue: async <T>() => {
            const form = await getForm();
            return form.getFieldsValue() as T;
        },
        // 重置表单
        resetForm: async () => {
            const form = await getForm();
            form.resetForm()
        },
        // 设置表单默认值
        setDefaultValue: async (data: Recordable) => {
            const form = await getForm();
            form.setDefaultValue(data);
        },
        // 清除校验
        clearValidate: async () => {
            const form = await getForm();
            form.clearValidate()
        },
        // 校验指定字段
        validateFieldForm: async (list) => {
            const form = await getForm();
            return form.validateFieldForm(list)
        },
    }

    return [register, methods]
}