<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    title="推单"
    @ok="handleSubmit"
    @cancel="handleClose"
    :paddingRight="15"
    :bodyStyle="{ minHeight: '400px !important' }"
  >
    <component
      v-if="visible"
      :is="componentName"
      ref="formRef"
      :formProps="state.formProps"
      :formModel="state.formModel"
      :fromPage="FromPageType.PREVIEW"
      class="pt-4"
    />
    <div class="hint" v-else>表单不存在</div>
  </BasicModal>
</template>
<script lang="ts" setup>
  import { ref, reactive, defineAsyncComponent, watch, nextTick } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { FromPageType } from '/@/enums/workflowEnum';
  import { getFormTemplate, addFormInfo } from '/@/api/form/design';
  import { buildOption } from '/@/utils/helper/designHelper';
  import { camelCaseString } from '/@/utils/event/design';
  import { FormSettingItem } from '/@/model/workflow/formSetting';
  import { useMessage } from '/@/hooks/web/useMessage';

  const { notification } = useMessage();

  const formRef = ref();
  const visible = ref(false);
  const componentName = ref('');
  const state = reactive({
    formModel: {},
    formProps: {},
    rowInfo: {},
    dataInfo: {} as FormSettingItem,
    isCustom: false,
  });

  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
    state.rowInfo = data.rowInfo;
    state.dataInfo = data.info;
    state.isCustom = !!data.isCustom;
    visible.value = true;
    componentName.value = getComponentName();
    setModalProps({
      destroyOnClose: true,
      maskClosable: false,
      canFullscreen: true,
      width: 900,
    });
  });
  watch(
    () => formRef.value,
    (val) => {
      if (val) {
        nextTick(() => {
          getFormInfo();
        });
      }
    },
  );
  const getComponentName = () => {
    return defineAsyncComponent({
      loader: () => {
        const systemModules: any = import.meta.glob('../../../../views/**/**/components/Form.vue');
        const customModules: any = import.meta.glob(
          '../../../../components/SimpleForm/src/SimpleForm.vue',
        );
        const path =
          state.dataInfo.formType === 0
            ? systemModules[
                `../../../${state.dataInfo.functionalModule}/${state.dataInfo.functionName}/components/Form.vue`
              ]
            : customModules['../../../../components/SimpleForm/src/SimpleForm.vue'];
        return path();
      },
      onError: function () {
        visible.value = false;
      },
    });
  };

  const getValue = (isCamelCase) => {
    const config = state.dataInfo.config;
    let fieldsValue = {};
    config.forEach((item) => {
      const targetArr = item.target.split(',');
      const fromArr = item.from.split(',');

      const mainTableTarget = isCamelCase ? camelCaseString(item.target) : item.target;
      const mainTableFrom = state.isCustom ? item.from : camelCaseString(item.from);
      const fromTableName = (state.isCustom ? fromArr[0] : camelCaseString(fromArr[0])) + 'List';
      const targetTableName = (isCamelCase ? camelCaseString(targetArr[0]) : targetArr[0]) + 'List';

      if (targetArr.length === 1 && fromArr.length === 1) {
        //主表推主表
        fieldsValue[mainTableTarget!] = state.rowInfo[mainTableFrom!];
      } else if (
        (targetArr.length === 1 && fromArr.length === 2) ||
        (targetArr.length === 2 && fromArr.length === 1)
      ) {
        if (targetArr.length === 1 && fromArr.length === 2) {
          //单表推主表
          const from = state.isCustom ? fromArr[1] : camelCaseString(fromArr[1]);
          fieldsValue[mainTableTarget!] = state.rowInfo[fromTableName]?.length
            ? state.rowInfo[fromTableName][0][from]
            : '';
        } else {
          //主表推单表
          const target = isCamelCase ? camelCaseString(targetArr[1]) : targetArr[1];
          if (!fieldsValue[targetTableName!]) {
            fieldsValue[targetTableName!] = [];
          }
          fieldsValue[targetTableName!].push({
            [target]: state.rowInfo[mainTableFrom!],
          });
        }
      } else {
        //子表推子表
        state.rowInfo[fromTableName]?.forEach((_, index) => {
          const target = isCamelCase ? camelCaseString(targetArr[1]) : targetArr[1];
          const from = state.isCustom ? fromArr[1] : camelCaseString(fromArr[1]);
          if (fieldsValue[targetTableName!]?.length && fieldsValue[targetTableName!][index]) {
            fieldsValue[targetTableName!][index][target] =
              state.rowInfo[fromTableName][index][from];
          } else {
            if (!fieldsValue[targetTableName!]) fieldsValue[targetTableName!] = [];
            fieldsValue[targetTableName!].push({
              [target]: state.rowInfo[fromTableName][index][from],
            });
          }
        });
      }
    });
    return fieldsValue;
  };

  const getFormInfo = async () => {
    let fieldsValue = {};
    if (state.dataInfo.formType === 0) {
      fieldsValue = getValue(true);
    } else {
      const data = await getFormTemplate(state.dataInfo.formId);
      if (data) {
        const json = JSON.parse(data.formJson);
        state.formProps = await buildOption(json.formJson, false);
      }
      formRef.value.setProps(state.formProps);
      await formRef.value.setDefaultValue();
      fieldsValue = await getValue(false);
    }
    nextTick(() => {
      formRef.value?.setFieldsValue(fieldsValue);
    });
  };

  async function handleSubmit() {
    if (!visible.value) return;
    try {
      const formData = await formRef.value?.validate();
      if (state.dataInfo.formType === 0) {
        await formRef.value.add(formData);
      } else {
        await addFormInfo({
          formId: state.dataInfo.formId,
          formData,
        });
      }
      closeModal();
      formRef.value.resetFields();
      notification.success({
        message: 'Tip',
        description: '推单成功',
      });
    } catch (error) {
      notification.error({
        message: 'Tip',
        description: '推单失败',
      });
    } finally {
      setModalProps({ confirmLoading: false });
    }
  }

  function handleClose() {
    if (!visible.value) return;
    formRef.value?.resetFields();
  }
</script>
<style lang="less" scoped>
  .hint {
    height: 200px;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 20px;
    color: #999;
  }
</style>
