<template>
  <div class="step4">
    <div class="w-3/4 mx-auto">
      <BasicForm @register="register" />
    </div>
    <Divider />
    <div v-for="(tableConfig, index) in generatorConfig?.tableStructureConfigs" :key="index">
      <a-table
        :columns="tableColumns"
        :data-source="[tableConfig]"
        :pagination="false"
        :defaultExpandAllRows="true"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.dataIndex === 'tableName'">
            <a-input
              v-model:value="record.tableName"
              :placeholder="t('请填写数据表名称')"
              @change="changeComponentName(record, 'table')"
              @blur="handleBlur(record)"
            />
          </template>
          <template v-else-if="column.dataIndex === 'isMain'">
            <span>
              <a-tag :color="record.isMain ? 'blue' : 'orange'">
                {{ record.isMain ? t('主表') : t('附表') }}
              </a-tag>
            </span>
          </template>
          <template v-else-if="column.dataIndex === 'tableComment'">
            <a-input v-model:value="record.tableComment" :placeholder="t('请填写备注')" />
          </template>
        </template>
        <template #expandedRowRender>
          <a-table
            :columns="fieldColumns"
            :data-source="tableConfig.tableFieldConfigs"
            :pagination="false"
          >
            <template #bodyCell="{ column, record }">
              <template v-if="column.dataIndex === 'fieldName'">
                <a-input
                  v-model:value="record.fieldName"
                  :placeholder="t(`请填写{title}`, { title: column.title })"
                  @change="changeComponentName(record, 'field')"
                  :disabled="disabledFields.includes(record.key)"
                />
              </template>
              <template v-else-if="column.dataIndex === 'fieldLength'">
                <a-input
                  v-model:value.number="record.fieldLength"
                  :placeholder="t('请填写字段长度')"
                  :disabled="record.fieldType !== 0"
                />
              </template>
              <template v-else-if="column.dataIndex === 'fieldComment'">
                <a-input
                  v-model:value.number="record.fieldComment"
                  :placeholder="t('请填写备注')"
                  :disabled="disabledFields.includes(record.key)"
                />
              </template>
              <template v-else-if="column.dataIndex === 'fieldType'">
                <a-select
                  v-model:value="record.fieldType"
                  style="width: 100%"
                  :placeholder="t('请选择数据格式')"
                  :disabled="disabledFields.includes(record.key)"
                  allowClear
                  @change="(value) => handleTypeChange(value, record)"
                >
                  <a-select-option
                    :value="type.value"
                    v-for="(type, idx) in fieldTypeList"
                    :key="idx"
                  >
                    {{ type.label }}
                  </a-select-option>
                </a-select>
              </template>
            </template>
          </a-table>
        </template>
      </a-table>
    </div>
    <TableNameModal @register="registerTableName" @success="handleEditSuccess" />
  </div>
</template>
<script lang="ts" setup>
  import { BasicForm, FormSchema, useForm } from '/@/components/Form/index';
  import { Divider } from 'ant-design-vue';
  import { TableNameModal } from '/@/components/CreateCodeStep';
  import { inject, ref, Ref } from 'vue';
  import { debounce, cloneDeep, random, snakeCase } from 'lodash-es';
  import { QuestionnaireConfig } from '/@/model/generator/generatorConfig';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { validateTableName } from '/@/api/system/generator';
  import { useI18n } from '/@/hooks/web/useI18n';
  import { useModal } from '/@/components/Modal';
  const { t } = useI18n();
  const [registerTableName, { openModal, closeModal }] = useModal();
  const validateTable = ref(false);
  const emit = defineEmits(['validateTable']);
  const { notification } = useMessage();

  const commonHelpMessage = `
    1.审计字段包括创建人、创建时间、最后修改人、最后修改时间、逻辑删除、标记字段。
    2.如果开启“审计字段”开关，则系统会自动实现相关操作，就是在新增时操作创建人、创建时间，编辑时操作最后修改人、最后修改时间，删除时改为逻辑删除，标记字段则标记字段是否有效。
    `;

  const commonFields = [
    {
      key: 'create_user_id',
      fieldName: 'create_user_id',
      fieldType: 6,
      fieldLength: null,
      fieldComment: t('创建人'),
    },
    {
      key: 'modify_user_id',
      fieldName: 'modify_user_id',
      fieldType: 6,
      fieldLength: null,
      fieldComment: t('修改人'),
    },
    {
      key: 'modify_date',
      fieldName: 'modify_date',
      fieldType: 5,
      fieldLength: null,
      fieldComment: t('修改时间'),
    },
    {
      key: 'delete_mark',
      fieldName: 'delete_mark',
      fieldType: 2,
      fieldLength: null,
      fieldComment: t('删除字段'),
    },
    {
      key: 'enabled_mark',
      fieldName: 'enabled_mark',
      fieldType: 2,
      fieldLength: null,
      fieldComment: t('标记字段'),
    },
  ];
  const handleCommonChange = (val) => {
    const fields = [
      'create_user_id',
      'modify_user_id',
      'modify_date',
      'delete_mark',
      'enabled_mark',
    ];
    if (!val) {
      if (generatorConfig?.tableStructureConfigs?.length) {
        generatorConfig.tableStructureConfigs[0].tableFieldConfigs =
          generatorConfig?.tableStructureConfigs[0].tableFieldConfigs.filter(
            (x) => !fields.includes(x.key!),
          );
      }
    } else {
      const hasCommonField =
        generatorConfig?.tableStructureConfigs?.length &&
        generatorConfig?.tableStructureConfigs[0].tableFieldConfigs.find((x) =>
          fields.includes(x.key!),
        );
      if (hasCommonField) return;
      generatorConfig?.tableStructureConfigs?.length &&
        generatorConfig?.tableStructureConfigs[0].tableFieldConfigs.push(...commonFields);
    }
    generatorConfig!.isCommonFields = val;
  };

  const formSchema: FormSchema[] = [
    {
      field: 'name',
      label: t('问卷名称'),
      required: true,
      component: 'Input',
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写问卷名称'),
        onChange: debounce((val: ChangeEvent) => {
          generatorConfig!.name = val.target.value;
        }, 200),
      },
    },
    {
      field: 'category',
      label: t('问卷分类'),
      component: 'DicSelect',
      required: true,
      componentProps: {
        placeholder: t('请选择问卷分类'),
        itemId: '1825816954386677762',
        isShowAdd: false,
        onChange: debounce((_, obj) => {
          if (obj) {
            generatorConfig!.category = obj.id;
          }
        }, 200),
      },
      colProps: { span: 12 },
    },
    {
      field: 'className',
      label: t('功能名称'),
      required: true,
      component: 'Input',
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写功能名称'),
        isShowAdd: false,
        onChange: debounce((val: ChangeEvent) => {
          generatorConfig!.className = val.target.value;
          const { className, tableStructureConfigs } = generatorConfig!;
          tableStructureConfigs?.map((item) => {
            const name = snakeCase(className!);
            const tableName = isFieldUpper.value ? name.toUpperCase() : name;
            item.tableName = item.isMain
              ? tableName
              : isFieldUpper.value
              ? `${tableName}_CHILD_${random(1000, 9999)}`
              : `${tableName}_child_${random(1000, 9999)}`;
            changeComponentName(item, 'table');
          });
        }, 200),
      },
    },
    {
      field: 'comment',
      label: t('功能描述'),
      required: true,
      component: 'Input',
      colProps: { span: 12 },
      componentProps: {
        placeholder: t('请填写功能描述'),
        onChange: debounce((val: ChangeEvent) => {
          generatorConfig!.comment = val.target.value;
        }, 200),
      },
    },
    {
      field: 'outputArea',
      label: t('功能模块'),
      component: 'DicSelect',
      required: true,
      componentProps: {
        placeholder: t('请选择功能模块'),
        itemId: '1419276800524423333',
        onChange: debounce((_, obj) => {
          if (obj) {
            generatorConfig!.outputArea = obj.id;
          }
        }, 200),
        getPopupContainer: () => document.body,
      },
      colProps: { span: 12 },
    },
    {
      field: 'isCommonFields',
      label: t('审计字段'),
      component: 'Switch',
      required: false,
      colProps: { span: 12 },
      helpMessage: commonHelpMessage,
      helpComponentProps: { maxWidth: '400px' },
      componentProps: {
        checkedValue: true,
        unCheckedValue: false,
        onChange: handleCommonChange,
      },
    },
    {
      field: 'remark',
      label: t('备注'),
      component: 'Input',
      required: false,
      colProps: { span: 24 },
      componentProps: {
        placeholder: t('请填写备注'),
        onChange: debounce((val) => {
          generatorConfig!.remark = val.target.value;
          generatorConfig!.tableStructureConfigs?.map(
            (item) => (item.tableComment = item.isMain ? val.target.value : item.tableComment),
          );
        }, 200),
      },
    },
  ];

  const tableColumns = [
    {
      title: t('数据表名称'),
      dataIndex: 'tableName',
      align: 'center',
    },
    {
      title: t('数据表类别'),
      dataIndex: 'isMain',
      align: 'center',
      width: 200,
    },
    {
      title: t('备注'),
      dataIndex: 'tableComment',
      align: 'center',
    },
  ];

  const fieldColumns = [
    {
      title: t('字段名'),
      dataIndex: 'fieldName',
      align: 'center',
    },
    {
      title: t('字段长度'),
      dataIndex: 'fieldLength',
      align: 'center',
    },
    {
      title: t('数据格式'),
      dataIndex: 'fieldType',
      align: 'center',
    },
    {
      title: t('备注'),
      dataIndex: 'fieldComment',
      align: 'center',
    },
  ];

  const fieldTypeList = [
    {
      label: t('短文本'),
      value: 0,
    },
    {
      label: t('长文本（适用于多行文本等组件）'),
      value: 1,
    },
    {
      label: t('整数'),
      value: 2,
    },
    {
      label: t('小数'),
      value: 3,
    },
    {
      label: t('日期'),
      value: 4,
    },
    {
      label: t('日期时间'),
      value: 5,
    },
    {
      label: t('外键'),
      value: 6,
    },
    {
      label: t('长整数'),
      value: 7,
    },
    {
      label: t('时间'),
      value: 8,
    },
  ];

  const generatorConfig = inject<QuestionnaireConfig>('generatorConfig');
  const widgetForm = inject<any>('widgetForm');
  let mainTableName = inject<any>('mainTableName', '');
  const isFieldUpper = inject<Ref<boolean>>('isFieldUpper', ref(false));
  const disabledFields = [
    'create_user_id',
    'create_date',
    'modify_user_id',
    'modify_date',
    'delete_mark',
    'enabled_mark',
    'rule_user_id',
  ];
  const props = defineProps({
    //是否是编辑状态
    isUpdate: {
      type: Boolean,
      default: false,
    },
    //新增时的表名集合
    beforeTableNames: {
      type: Array,
      default: () => [],
    },
  });

  const [register, { validate, setFieldsValue }] = useForm({
    schemas: formSchema,
    showActionButtonGroup: false,
    layout: 'vertical',
    rowProps: { gutter: 32 },
  });

  const changeComponentInfo = (list, type, fieldKey, name) => {
    const isTable = type === 'table';
    list?.map((component: any) => {
      if (component.key === fieldKey) {
        //修改主表名
        mainTableName!.value = name;
        isTable ? (component.bindTable = name) : (component.bindField = name);
      }
    });
    widgetForm!.value.list = cloneDeep(generatorConfig!.formJson.list);
  };

  const changeComponentName = (record, type) => {
    if (type === 'table') {
      const name = snakeCase(record.tableName);
      record.tableFieldConfigs.forEach((item) => {
        changeComponentInfo(
          generatorConfig?.formJson.list,
          'table',
          item.key,
          isFieldUpper.value ? name.toUpperCase() : name,
        );
      });
    } else {
      changeComponentInfo(generatorConfig?.formJson.list, 'field', record.key, record.fieldName);
    }
  };

  const handleBlur = (record) => {
    const name = snakeCase(record.tableName);
    record.tableName = isFieldUpper.value ? name.toUpperCase() : name;
  };

  const handleTypeChange = (value, record) => {
    if (value !== 0) {
      record.fieldLength = null;
    } else {
      record.fieldLength = 500;
    }
  };

  //验证当前步骤的数据
  const validateStep = async (): Promise<boolean> => {
    try {
      const { tableStructureConfigs, className } = generatorConfig!;
      const sunFormList = tableStructureConfigs!.filter((x) => x.parentKey);
      sunFormList.forEach((item) => {
        tableStructureConfigs!.forEach((config) => {
          if (item.parentKey === config.key) {
            item.parentTable = config.tableName;
          }
        });
      });

      await validate();

      if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(className!)) {
        notification.error({
          message: t('提示'),
          description: t('功能名称只能是数字和字母组成，必须以英文字母开头'),
        });
        return false;
      }
      const tableNames: string[] = tableStructureConfigs!.map((x) => x.tableName);

      const reg = /^[a-zA-Z0-9_]*$/;
      //判断表名是否符合要求
      const isTableNotSuccess = tableStructureConfigs?.some((config: any) => {
        return !reg.test(config.tableName);
      });
      if (isTableNotSuccess) {
        notification.error({
          message: t('提示'),
          description: '表名只能包括字母、数字、下划线',
        }); //提示消息
        return false;
      }
      //判断字段名是否符合要求
      const isFieldNotSuccess = tableStructureConfigs?.some((config: any) => {
        const isNotPassValidation = config.tableFieldConfigs.some((fieldConfig: any) => {
          return !reg.test(fieldConfig.fieldName) || fieldConfig.fieldName.length > 30;
        });
        return isNotPassValidation;
      });
      if (isFieldNotSuccess) {
        notification.error({
          message: t('提示'),
          description:
            '字段名必须以小写字母开头，只能包括小写字母、数字、下划线，并且不能超过30个字符',
        }); //提示消息
        return false;
      }
      const notHasRepeatName = tableStructureConfigs?.every((config) => {
        const nameArr = config.tableFieldConfigs.map((x) => x.fieldName);
        return [...new Set(nameArr)].length === nameArr.length;
      });
      if (!notHasRepeatName) {
        notification.error({
          message: t('提示'),
          description: t('同一个表内，不能有相同字段名'),
        }); //提示消息
        return false;
      }
      const testTableNames = tableNames.filter((x) => {
        return !props.beforeTableNames.includes(x);
      });
      const params = {
        id: generatorConfig!.databaseId!,
        tableNames: props.isUpdate ? testTableNames.toString() : tableNames.toString(),
      };
      if (!props.isUpdate || (!props.isUpdate && testTableNames.length)) {
        await validateTableName(params);
      }

      if (props.isUpdate) {
        if (!validateTable.value) {
          openModal();
          return false;
        }
      }
    } catch (error) {
      return false;
    }
    validateTable.value = false;
    return true;
  };
  async function handleEditSuccess() {
    validateTable.value = true;
    closeModal();
    emit('validateTable');
  }
  defineExpose({ validateStep, setFieldsValue });
</script>
<style lang="less" scoped>
  .step4 {
    padding: 14px;

    p {
      color: @text-color;
    }
  }

  :deep(.ant-tag-orange),
  :deep(.ant-tag-blue) {
    background: #fff;
    font-size: 13px;
  }

  :deep(.ant-spin-nested-loading) {
    overflow: hidden; //去掉表格嵌套子表滚动条
  }
</style>
