<template>
  <BasicModal @register="registerModal" v-bind="$attrs" wrapClassName="form-modal">
    <template #title>
      <div class="step-form-form">
        <a href="https://www.learun.cn/" target="_blank">
          <DesignLogo />
        </a>
        <span>{{ t('代码生成器 - 数据优先') }}</span>
        <div class="btn-box">
          <a-button @click="handleStepPrev" v-show="current !== 0">{{ t('上一步') }}</a-button>
          <a-button type="primary" @click="handleStepNext" v-show="current < 5">
            {{ t('下一步') }}
          </a-button>
          <a-button type="primary" @click="handleCodeGenerator" v-show="current === 5">
            {{ t('完成') }}
          </a-button>
          <a-button type="primary" @click="handleSaveDraft">{{ t('保存草稿') }}</a-button>
          <a-button type="primary" danger @click="handleClose">{{ t('关闭') }}</a-button>
        </div>
      </div>
      <div class="step-box">
        <a-steps :current="current" size="mini">
          <a-step :title="t('基本信息')" />
          <a-step :title="t('表单设计')" />
          <a-step :title="t('表单事件')" />
          <a-step :title="t('界面设计')" />
          <a-step :title="t('代码预览')" />
          <a-step :title="t('菜单设置')" />
        </a-steps>
      </div>
    </template>
    <div class="step-container">
      <TableConfigStep ref="tableConfigStepRef" v-show="current === 0" :isUpdate="isUpdate" />
      <FormDesignStep ref="formDesignStepRef" v-show="current === 1" />
      <FormEventStep ref="formEventStep" v-show="current === 2" />
      <ViewDesignStep ref="viewDesignStep" :isUpdate="isUpdate" v-show="current === 3" />
      <PreviewCodeStep ref="previewCodeStep" v-show="current === 4" />
      <MenuConfigStep ref="menuConfigStep" v-show="current === 5" />
    </div>
  </BasicModal>
</template>
<script lang="ts" setup>
  import { ref, reactive, provide, Ref, defineAsyncComponent } from 'vue';
  import { BasicModal, useModalInner } from '/@/components/Modal';
  import { GeneratorConfig } from '/@/model/generator/generatorConfig';
  import { TableInfo } from '/@/components/Designer';
  import {
    dataFirstGeneratorCode,
    getCodeTemplateInfo,
    saveDraftGeneratorCode,
    updateDraftGeneratorCode,
  } from '/@/api/system/generator';
  import { FormProps } from '/@/components/Form';
  import { buildOption } from '/@/utils/helper/designHelper';
  import { buildCode } from '/@/utils/helper/generatorHelper';
  import { GeneratorModel, SaveDraftGeneratorModel } from '/@/api/system/generator/model';
  import { useUserStore } from '/@/store/modules/user';
  import { LoadingBox } from '/@/components/ModalPanel/index';
  import { MenuConfig } from '/@/model/generator/menuConfig';
  import { FormJson } from '/@/model/generator/codeGenerator';
  import { FormEventColumnConfig } from '/@/model/generator/formEventConfig';
  import * as antd from '/@/components/Designer/src/types';
  import { useI18n } from '/@/hooks/web/useI18n';
  import DesignLogo from '/@/components/ModalPanel/src/DesignLogo.vue';
  import { TreeStructureType } from '/@/enums/treeStructure';
  import { useMessage } from '/@/hooks/web/useMessage';
  const { notification } = useMessage();
  const { t } = useI18n();
  const TableConfigStep = defineAsyncComponent({
    loader: () => import('/@/components/CreateCodeStep/src/TableConfigStep.vue'),
    loadingComponent: LoadingBox,
  });
  const FormDesignStep = defineAsyncComponent({
    loader: () => import('/@/components/CreateCodeStep/src/FormDesignStep.vue'),
    loadingComponent: LoadingBox,
  });
  const FormEventStep = defineAsyncComponent({
    loader: () => import('/@/components/CreateCodeStep/src/FormEventStep.vue'),
    loadingComponent: LoadingBox,
  });
  const ViewDesignStep = defineAsyncComponent({
    loader: () => import('/@/components/CreateCodeStep/src/ViewDesignStep.vue'),
    loadingComponent: LoadingBox,
  });
  const MenuConfigStep = defineAsyncComponent({
    loader: () => import('/@/components/CreateCodeStep/src/MenuConfigStep.vue'),
    loadingComponent: LoadingBox,
  });
  const PreviewCodeStep = defineAsyncComponent({
    loader: () => import('./PreviewCodeStep.vue'),
    loadingComponent: LoadingBox,
  });

  const userStore = useUserStore();
  const templateId = ref();
  const current = ref(0);
  const isUpdate = ref(false);
  const tableConfigStepRef = ref();
  const formDesignStepRef = ref();
  const formEventStep = ref();
  const viewDesignStep = ref();
  const previewCodeStep = ref();
  const menuConfigStep = ref();
  const widgetForm = ref(JSON.parse(JSON.stringify(antd.widgetForm))); //FormDesignStep -> designer和StructureConfigStep页面使用
  const tableInfo = ref<TableInfo[]>([]);

  const emit = defineEmits(['close', 'register', 'success']);
  let generatorConfig = reactive<GeneratorConfig>({
    databaseId: null, //数据库id
    listConfig: {
      isLeftMenu: false,
      queryConfigs: [],
      isAdvancedQuery: false, //是否配置高级搜索
      leftMenuConfig: [
        {
          datasourceType: 'tree',
          listFieldName: undefined,
          apiConfig: {},
          dictionaryItemId: undefined,
          menuName: '',
          parentIcon: '',
          childIcon: '',
          staticData: [],
          treeConfig: {
            id: '',
            name: '',
            type: TreeStructureType.STATIC,
            config: [],
            configTip: '',
            isMultiple: false,
          },
        },
      ],
      columnConfigs: [],
      buttonConfigs: [],
      defaultOrder: true,
      listStyle: 'default',
      isPage: true,
      pageSize: 10,
      querySelectOption: '', //所有查询配置
      objectId: '', //系统表单formId,自定义表单releaseId的id值
    },
    tableConfigs: [],
    formJson: {} as FormJson,
    menuConfig: {} as MenuConfig,
    outputConfig: {
      creator: userStore.getUserInfo.name,
      isMenu: true,
      type: 0,
    },
    formEventConfig: {} as FormEventColumnConfig,
    isDataAuth: false,
    dataAuthList: [],
  });

  provide<GeneratorConfig>('generatorConfig', generatorConfig);
  provide<Ref<TableInfo[]>>('tableInfo', tableInfo);
  provide<Ref<number>>('current', current); //当前步骤
  provide<string>('designType', 'data');
  provide('widgetForm', widgetForm);

  let timer: any = null;

  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
    setModalProps({
      confirmLoading: false,
      canFullscreen: false,
      defaultFullscreen: true,
      maskClosable: false,
      destroyOnClose: true,
      draggable: false,
      showOkBtn: false,
      showCancelBtn: false,
      footer: null,
      closable: false,
    });
    isUpdate.value = data.isUpdate || false;
    templateId.value = data.isUpdate ? data.id : '';
    if (data.isUpdate) {
      let res = await getCodeTemplateInfo(data.id);

      if (res.content) {
        let content = JSON.parse(res.content);
        const {
          databaseId,
          listConfig,
          formJson,
          tableConfigs,
          menuConfig,
          outputConfig,
          formEventConfig,
        } = content;
        if (!Array.isArray(listConfig.leftMenuConfig)) {
          listConfig.leftMenuConfig = [listConfig.leftMenuConfig];
        }
        generatorConfig.databaseId = databaseId;
        generatorConfig.listConfig = listConfig;
        formJson.list = formJson?.list?.filter((x) => x.type !== 'hiddenComponent') || [];
        generatorConfig.formJson = formJson;
        generatorConfig.tableConfigs = tableConfigs;
        generatorConfig.menuConfig = menuConfig;
        generatorConfig.outputConfig = outputConfig;
        generatorConfig.formEventConfig = formEventConfig || ({} as FormEventColumnConfig);
        widgetForm.value = formJson;
        //用于解决打包部署后 TableConfigStep页面加载顺序问题
        tableConfigStepRef.value?.editFieldsValue();
      }
    }
    timer = setInterval(() => {
      handleSaveDraft();
    }, 1000 * 60 * 30);
  });

  //上一步
  function handleStepPrev() {
    current.value--;
  }
  //下一步
  async function handleStepNext() {
    const isOk = await stepValidate[current.value]();
    if (!isOk) {
      return;
    }
    current.value++;
  }

  async function handleSaveDraft() {
    menuConfigStep.value.getFormData();
    const data = generatorConfig as GeneratorModel;
    if (current.value > 3) {
      data.frontCode = buildCode(
        generatorConfig,
        tableInfo.value,
        buildOption(generatorConfig.formJson) as FormProps,
      );
    }

    const params: SaveDraftGeneratorModel = {
      name: generatorConfig!.outputConfig!.className!,
      type: 0, // 0-数据优先 1-界面优先 2-简易模板 3-无表表单
      content: JSON.stringify(data),
      remark: generatorConfig!.outputConfig!.comment!,
    };
    let res = false;
    if (templateId.value) {
      params.id = templateId.value;
      res = await updateDraftGeneratorCode(params);
    } else {
      res = await saveDraftGeneratorCode(params);
      if (res) {
        templateId.value = res;
        isUpdate.value = true;
      }
    }
    notification.success({
      message: t('提示'),
      description: t(`保存${res ? '成功' : '失败'}`),
    });
    if (res) emit('success');
  }
  async function handleCodeGenerator() {
    const isOk = await stepValidate[5]();
    if (
      generatorConfig.formJson?.hiddenComponent &&
      generatorConfig.formJson?.hiddenComponent.length
    ) {
      generatorConfig.formJson.list.push(...generatorConfig.formJson.hiddenComponent);
    }

    if (!isOk) {
      return;
    }
    const data = generatorConfig as GeneratorModel;
    data.frontCode = buildCode(
      generatorConfig,
      tableInfo.value,
      buildOption(generatorConfig.formJson) as FormProps,
    );
    if (templateId.value) data.id = templateId.value;
    await dataFirstGeneratorCode(data);
    handleClose();
    emit('success');
  }

  const handleClose = () => {
    closeModal();
    emit('close');
    clearInterval(timer);
    timer = null;
  };

  const stepValidate = {
    //数据表配置 验证
    0: () => tableConfigStepRef.value.validateStep(),
    1: () => formDesignStepRef.value.validateStep(),
    2: () => formEventStep.value.validateStep(),
    3: () => viewDesignStep.value.validateStep(),
    4: () => previewCodeStep.value.validateStep(),
    5: () => menuConfigStep.value.validateStep(),
  };
</script>
<style lang="less" scoped></style>
