// 界面优先
<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">
      <FormDesignStep ref="formDesignStepRef" v-show="current === 0" />
      <FormEventStep ref="formEventStepRef" v-show="current === 1" />
      <StructureConfigStep
        ref="structureConfigStepRef"
        :isUpdate="isUpdate"
        v-show="current === 2"
        @validate-table="handleStepNext"
      />
      <ViewDesignStep ref="viewDesignStepRef" :isUpdate="isUpdate" v-show="current === 3" />
      <PreviewCodeStep ref="previewCodeStepRef" v-show="current === 4" />
      <MenuConfigStep ref="menuConfigStepRef" 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, noHaveTableAndField } from '/@/components/Designer';
  import {
    codeFirstGeneratorCode,
    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 * as antd from '/@/components/Designer/src/types';
  import { random } from 'lodash-es';
  import { LoadingBox } from '/@/components/ModalPanel/index';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { FormEventColumnConfig } from '/@/model/generator/formEventConfig';
  import { MenuConfig } from '/@/model/generator/menuConfig';
  import { FormJson } from '/@/model/generator/codeGenerator';
  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 StructureConfigStep = defineAsyncComponent({
    loader: () => import('/@/components/CreateCodeStep/src/StructureConfigStep.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 formDesignStepRef = ref();
  const formEventStepRef = ref();
  const structureConfigStepRef = ref();
  const viewDesignStepRef = ref();
  const previewCodeStepRef = ref();
  const menuConfigStepRef = ref();
  const widgetForm = ref(JSON.parse(JSON.stringify(antd.widgetForm))); //FormDesignStep -> designer和StructureConfigStep页面使用
  const mainTableName = ref('table_' + random(10000, 99999));
  const emit = defineEmits(['close', 'register', 'success']);

  const tableInfo = ref<TableInfo[]>([]);
  let generatorConfig = reactive<GeneratorConfig>({
    databaseId: '', //数据库id
    listConfig: {
      isLeftMenu: false,
      queryConfigs: [],
      leftMenuConfig: [
        {
          // isTree: false,
          datasourceType: 'tree',
          listFieldName: undefined,
          apiConfig: {},
          dictionaryItemId: undefined,
          menuName: '',
          parentIcon: '',
          childIcon: '',
          staticData: [],
          treeConfig: {
            id: '',
            name: '',
            type: TreeStructureType.STATIC,
            configTip: '',
            config: [],
            isMultiple: false,
          },
        },
      ],
      columnConfigs: [],
      buttonConfigs: [],
      defaultOrder: true,
      listStyle: 'default',
      isPage: true,
      pageSize: 10,
    },
    tableStructureConfigs: [],
    formJson: {} as FormJson,
    menuConfig: {} as MenuConfig,
    outputConfig: {
      creator: userStore.getUserInfo.name,
      isMenu: true,
      type: 1,
    },
    formEventConfig: {} as FormEventColumnConfig,
    isDataAuth: false,
    dataAuthList: [],
  });

  provide<GeneratorConfig>('generatorConfig', generatorConfig);
  provide<Ref<TableInfo[]>>('tableInfo', tableInfo);
  provide<Ref<number>>('current', current); //当前步骤
  provide<string>('designType', 'code');
  provide('widgetForm', widgetForm);
  provide<Ref<string>>('mainTableName', mainTableName);
  provide<Ref<boolean>>('isFieldUpper', ref(false));

  let timer: any = null;

  const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
    setModalProps({
      confirmLoading: false,
      canFullscreen: false,
      defaultFullscreen: true,
      maskClosable: false,
      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,
          tableStructureConfigs,
          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.tableStructureConfigs = tableStructureConfigs;
        generatorConfig.menuConfig = menuConfig;
        generatorConfig.outputConfig = outputConfig;
        generatorConfig.formEventConfig = formEventConfig || ({} as FormEventColumnConfig);
        widgetForm.value = formJson;
        getMainTableFirst(formJson.list);
      }
    }
    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() {
    if (current.value === 0) {
      await formDesignStepRef.value?.setStructureConfig();
    }
    menuConfigStepRef.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: 1, // 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 appGeneratorCode(
    //   buildAppCode(generatorConfig, buildAppFormProps(generatorConfig.formJson)),
    // );

    await codeFirstGeneratorCode(data);

    handleClose();
    emit('success');
  }

  const stepValidate = {
    //数据表配置 验证
    0: () => formDesignStepRef.value.validateStep(),
    1: () => formEventStepRef.value.validateStep(),
    2: () => structureConfigStepRef.value.validateStep(),
    3: () => viewDesignStepRef.value.validateStep(),
    4: () => previewCodeStepRef.value.validateStep(),
    5: () => menuConfigStepRef.value.validateStep(),
  };

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

  function getMainTableFirst(list) {
    list.some((x) => {
      if (['tab', 'grid', 'card'].includes(x.type)) {
        for (const child of x.layout!) {
          return getMainTableFirst(child.list);
        }
      } else if (x.type == 'table-layout') {
        for (const child of x.layout!) {
          for (const el of child.list) {
            return getMainTableFirst(el.children);
          }
        }
      } else {
        if (
          x.type !== 'form' &&
          x.type !== 'one-for-one' &&
          !noHaveTableAndField.includes(x.type)
        ) {
          mainTableName.value = x.bindTable;
          return true;
        }
      }
    });
  }
</script>
<style lang="less" scoped></style>
