<template>
    <!-- 表单信息 -->
    <div class="form-container">
        <div class="box">
            <div :style="{}" class="form-right">
                <div v-for="(item, index) in forms.configs" :key="index" :tab="item.formName">
                    <div v-show="activeIndex == index">
                        <!-- 如果是生成文件模式 formType = 0，也就是FormType.SYSTEM，会加载对应项目的Form.vue-->
                        <SystemForm v-if="item.formType == FormType.SYSTEM" :ref="setItemRef" :formModel="item.formModel" :isViewProcess="props.disabled" :systemComponent="item.systemComponent" :workflowConfig="item" class="form-box" />
                        <SimpleForm v-else-if="item.formType == FormType.CUSTOM" :ref="setItemRef" :formModel="item.formModel" :formProps="item.formProps" :isWorkFlow="true" class="form-box" />
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script lang="ts" setup>
    import SimpleForm from '/@/components/SimpleForm/src/SimpleForm.vue';
    import { onBeforeUpdate, nextTick, onMounted, reactive, ref } from 'vue';
    import { TaskApproveOpinion, ValidateForms } from '/@/model/workflow/bpmnConfig';
    import { cloneDeep } from 'lodash-es';
    import { GeneratorConfig } from '/@/model/generator/generatorConfig';
    import { FormEventColumnConfig } from '/@/model/generator/formEventConfig';
    import { changeFormJson } from '/@/hooks/web/useWorkFlowForm';
    import { SystemForm } from '/@/components/SystemForm/index';
    import { FormType } from '/@/enums/workflowEnum';
    import { createFormEvent, loadFormEvent, submitFormEvent } from '/@/hooks/web/useFormEvent';

    const props = withDefaults(
        defineProps<{
            disabled: boolean | undefined;
            formInfos: Array<any>;
            opinions?: Array<TaskApproveOpinion> | undefined;
            opinionsComponents?: Array<string> | undefined;
            formAssignmentData?: null | Recordable;
        }>(),
        {
            disabled: false,
            formInfos: () => {
                return [];
            }
        }
    );

    const emits = defineEmits(['getFormConfigs']);

    let uploadComponent: { ids: Array<string> } = reactive({ ids: [] });

    let activeIndex = ref(0);
    let itemRefs = ref([]) as any;
    const setItemRef = (el: never) => {
        itemRefs.value.push(el);
    };

    onBeforeUpdate(() => {
        itemRefs.value = [];
    });

    let forms: {
        formModels: Array<Recordable>;
        configs: Array<{
            formName: string;
            formProps: {};
            formModel: Recordable;
            formKey: string;
            validate: boolean;
            formType: FormType;
            workflowPermissions?: Array<any>;
            opinions?: Array<any>;
            opinionsComponents?: Array<any>;
            systemComponent?: {
                functionalModule: string;
                functionName: string;
                functionFormName: string;
            };
            formJson?: Array<any>;
            isOldSystem?: boolean;
        }>;
        formEventConfigs: FormEventColumnConfig[];
    } = reactive({
        formModels: [],
        configs: [],
        formEventConfigs: []
    });
    onMounted(async () => {
        for await (let element of props.formInfos) {
            let formModels = {};
            if (element.formData) {
                formModels = cloneDeep(element.formData);
            }
            // 参数赋值[赋值权限最大]
            if (props.formAssignmentData) {
                if (props.formAssignmentData[element.formConfig.formId]) {
                    formModels = { ...formModels, ...props.formAssignmentData[element.formConfig.formId] };
                }
            }
            forms.formModels.push(formModels);
            // 系统表单
            if (element.formType == FormType.SYSTEM) {
                forms.configs.push({
                    formName: element.formConfig.formName,
                    formProps: {},
                    formModel: formModels,
                    formKey: element.formConfig.key,
                    validate: true,
                    formType: element.formType,
                    workflowPermissions: element.formConfig.children,
                    opinions: props.opinions,
                    opinionsComponents: props.opinionsComponents,
                    systemComponent: {
                        functionalModule: element.functionalModule,
                        functionName: element.functionName,
                        functionFormName: 'Form'
                    },
                    formJson: element.formJson,
                    isOldSystem: false
                });
                // 上传组件Id集合
                setTimeout(() => {
                    getSystemUploadComponentIds();
                }, 0);
            } else {
                const model = JSON.parse(element.formJson) as GeneratorConfig;
                const { formJson, formEventConfig } = model;
                if (formEventConfig) {
                    forms.formEventConfigs.push(formEventConfig);

                    //初始化表单
                    await createFormEvent(formEventConfig, formModels, true);
                    //加载表单
                    await loadFormEvent(formEventConfig, formModels, true);

                    //TODO 暂不放开 工作流没有获取表单数据这个步骤 获取表单数据
                    // getFormDataEvent(formEventConfig, formModels,true);
                }
                let formKey = element.formConfig.key;

                let config = {
                    formName: element.formConfig.formName,
                    formProps: {},
                    formModel: {},
                    formKey,
                    validate: true,
                    formType: element.formType
                };
                let isViewProcess = props.disabled;
                let { buildOptionJson, uploadComponentIds } = changeFormJson(
                    {
                        formJson,
                        formConfigChildren: element.formConfig.children,
                        formConfigKey: element.formConfig.key,
                        opinions: props.opinions,
                        opinionsComponents: props.opinionsComponents
                    },
                    isViewProcess,
                    uploadComponent.ids
                );
                uploadComponent.ids = uploadComponentIds;
                if (buildOptionJson.schemas) {
                    config.formProps = buildOptionJson;
                    forms.configs.push(config);
                }
            }
            // });
        }

        await nextTick();
        setTimeout(() => {
            setFormModel();
        }, 0);
        emits('getFormConfigs', forms.configs.length ? forms.configs[activeIndex.value] : null);
    });

    function setFormModel() {
        for (let index = 0; index < itemRefs.value.length; index++) {
            if (itemRefs.value[index]) {
                itemRefs.value[index].setFieldsValue(forms.formModels[index]);
            }
        }
    }

    async function setFormData(formData) {
        await nextTick();
        forms.formModels = formData;
        setFormModel();
    }

    function getSystemUploadComponentIds() {
        for (let index = 0; index < itemRefs.value.length; index++) {
            if (itemRefs.value[index] && itemRefs.value[index].getUploadComponentIds) {
                let ids = itemRefs.value[index].getUploadComponentIds();
                uploadComponent.ids = [...uploadComponent.ids, ...ids];
            }
        }
    }

    // 获取上传组件的字段值集合
    function getUploadComponentIds() {
        return uploadComponent.ids;
    }

    async function validateForm() {
        let validateForms: ValidateForms = [];
        for (let index = 0; index < itemRefs.value.length; index++) {
            if (itemRefs.value[index]) {
                try {
                    await itemRefs.value[index]?.validate();
                    validateForms.push({
                        validate: true,
                        msgs: [],
                        isOldSystem: forms.configs[index].isOldSystem
                    });
                    forms.configs[index].validate = true;
                } catch (error: any | Array<{ errors: Array<string>; name: Array<string> }>) {
                    validateForms.push({
                        validate: false,
                        msgs: error?.errorFields
                    });
                    forms.configs[index].validate = false;
                }
            }
        }
        return validateForms;
    }

    async function saveDraftData() {
        let formModes = {};

        for (let index = 0; index < forms.configs.length; index++) {
            const ele = forms.configs[index];
            if (ele.formType == FormType.SYSTEM) {
                let values = await itemRefs.value[index].validate();
                formModes[ele.formKey] = values;
            } else {
                formModes[ele.formKey] = ele.formModel;
            }
        }
        return formModes;
    }

    async function getFormModels() {
        let formModes = {};

        for (let index = 0; index < forms.configs.length; index++) {
            const ele = forms.configs[index];
            if (ele.formType == FormType.SYSTEM) {
                let values = await itemRefs.value[index].workflowSubmit();
                formModes[ele.formKey] = values;
            } else {
                formModes[ele.formKey] = ele.formModel;
            }
        }

        // forms.configs.forEach((ele) => {
        //   formModes[ele.formKey] = ele.formModel;
        // });
        forms.formEventConfigs.forEach(async (ele, i) => {
            //此组件 获取数据 就是为了提交表单 所以 表单提交数据 事件 就此处执行
            await submitFormEvent(ele, forms.configs[i]?.formModel);
        });
        return formModes;
    }

    function getSystemType() {
        let system = {};
        for (let index = 0; index < forms.configs.length; index++) {
            const ele = forms.configs[index];
            if (ele.formType == FormType.SYSTEM) {
                system[ele.formKey] = itemRefs.value[index].getIsOldSystem();
            }
        }
        return system;
    }

    defineExpose({
        validateForm,
        getFormModels,
        saveDraftData,
        setFormData,
        getUploadComponentIds,
        getSystemType
    });
</script>

<style lang="less" scoped>
    .form-container {
        display: flex;
        margin-top: -10px;
    }

    .box {
        .form-left {
            float: left;
            height: 100vh;
            box-shadow: 5px 5px 5px rgb(0 0 0 / 10%);
            z-index: 9998;

            .resize-shrink-sidebar {
                cursor: col-resize;
                display: flex;
                justify-content: center;
                align-items: center;
                position: absolute;
                top: 0;
                bottom: 0;
                right: 0;
                z-index: 9999;

                .shrink-sidebar-text {
                    padding: 0 2px;
                    background: #f2f2f2;
                    border-radius: 10px;
                }
            }

            .left-box {
                margin-right: 10px;
                border-right: 1px solid #f0f0f0;
                height: 80vh;
            }

            span {
                font-size: 16px;
                font-weight: 500;
                padding-left: 4px;
            }

            .form-name {
                height: 36px;
                display: flex;
                align-items: center;
                font-size: 14px;
                cursor: pointer;
                color: rgb(102 102 102 / 99.6%);
                margin-right: -2px;
                padding-left: 4px;
            }

            .actived {
                border-right: 1px solid #5e95ff;
            }

            .dot {
                width: 10px;
                height: 10px;
                border-radius: 50%;
                background-color: transparent;
                margin-right: 4px;
            }

            .validate {
                background-color: @clear-color;
            }

            .icon-box {
                font-size: 16px;
                margin-right: 4px;
            }

            .left-title {
                display: flex;
                justify-content: space-between;
                align-items: center;
                position: relative;
                padding: 10px 4px 10px 0;
                top: 0;
                left: 0;

                .in-or-out {
                    position: absolute;
                    right: 10px;
                }
            }
        }

        .form-right {
            padding-top: 20px;
        }
    }
</style>
