<template>
  <BasicModal
    v-bind="$attrs"
    @register="registerModal"
    :centered="true"
    :canFullscreen="false"
    :defaultFullscreen="false"
    :showCancelBtn="!isDetail"
    :showOkBtn="!isDetail"
    :draggable="false"
    :title="getTitle"
    :useWrapper="true"
    :width="900"
    :maskClosable="false"
    @ok="handleOk"
  >
    <div class="box-container">
      <div class="flex mb-3">
        <div class="tab-label"><span class="red">*</span>表名：</div>
        <a-input v-model:value="tableName" placeholder="请输入表名" :disabled="isUpdate" />
      </div>
    </div>
    <BasicTable class="w-3/4 xl:w-5/5" @register="registerTable">
      <template #toolbar>
        <a-button type="primary" @click="handleAdd" v-if="!isDetail"> 新增 </a-button>
        <a-button type="primary" @click="handleAddGeom" v-if="!isUpdate && !isDetail">
          空间建表
        </a-button>
      </template>
      <template #bodyCell="{ column, record }">
        <template v-if="column.key === 'name' && !isDetail">
          <a-input
            v-model:value="record.name"
            placeholder="请输入字段名"
            :disabled="record.name == 'geom' || isBasic"
            @change="
              if (changeNameAndType()) {
                if (record.name == 'geom' && record.type != 'geometry(GEOMETRY)') {
                  record.type = 'geometry(GEOMETRY)';
                }
              }
            "
          />
        </template>
        <template v-if="column.key === 'type' && !isDetail">
          <a-select
            style="width: 100%"
            ref="select"
            placeholder="请选择"
            v-model:value="record.type"
            :options="codesTypeArr"
            :disabled="isBasic"
            @change="
              if (changeNameAndType()) {
                if (record.type == 'geometry(GEOMETRY)') {
                  record.name = 'geom';
                } else if (record.name && record.name == 'geom') {
                  record.name = '';
                }
              }
            "
          />
        </template>
        <template v-if="column.key === 'type' && isDetail">
          {{ getCodesTypeArrByType(record.type) }}
        </template>
        <template v-if="column.key === 'explanation' && !isDetail">
          <a-input v-model:value="record.explanation" placeholder="不能含有英文字符的,和:" />
        </template>
        <template v-if="column.key === 'action' && (!record.isOldColumn || !isUpdate)">
          <TableAction
            :actions="[
              {
                label: '删除',
                color: 'error',
                onClick: () => {
                  handleDelete(record);
                },
              },
            ]"
          />
        </template>
      </template>
    </BasicTable>
  </BasicModal>
</template>
<script lang="ts" setup>
  import { ref, onMounted, defineEmits } from 'vue';
  import { BasicModal, useModalInner } from '@/components/Modal';
  import { BasicTable, useTable, TableAction } from '@/components/Table';
  import { columns, columns_isDetail } from './modal.data';
  import { useMessage } from '@/hooks/web/useMessage';
  // api
  import { createPicTable, updateTable, CheckTableExist } from '@/api/database/index';
  import { getLoad } from '@/api/sys/sysDataItemDetail';

  const emit = defineEmits(['submit']);
  const { createMessage } = useMessage();

  // 是否是修改
  const isUpdate = ref(false);
  // 是否是详情
  const isDetail = ref(false);
  // 是否是标准化
  const isBasic = ref(false);
  const tableName: any = ref('');
  const getTitle: any = ref('');
  const tableColumns: any = ref([]);
  const codesTypeArr: any = ref([
    { label: 'varchar', value: 'varchar' },
    { label: 'int', value: 'int' },
    { label: 'date', value: 'date' },
  ]);

  // 窗口
  const [registerModal, { setModalProps, closeModal }] = useModalInner((data) => {
    setModalProps({ confirmLoading: false });
    isUpdate.value = data.isUpdate;
    isDetail.value = data.isDetail;

    // 新增
    if (!data.record) {
      getTitle.value = '新增';
      tableName.value = null;
      setTableData([]);
      handleAdd();
      reload();
    } else {
      // 编辑、详情
      getTitle.value = '详情';
      tableName.value = data.record.tableName;
      const lines = data.record.columnJson.split(':');
      let arr: any = [];
      for (const line of lines) {
        const i = line.split(',');
        arr.push({
          name: i[0],
          yuanName: i[0],
          type: i[1],
          explanation: i[2],
          length: 255,
          id: new Date().getTime(),
          isOldColumn: true,
        });
      }
      isBasic.value = false;
      setTableData(arr);
      reload();
    }
    // 详情隐藏按钮
    if (isDetail.value) {
      tableColumns.value = columns_isDetail;
    } else {
      tableColumns.value = columns;
    }
  });

  // 表格
  const [registerTable, { reload, setTableData, getDataSource }] = useTable({
    rowKey: '',
    columns: tableColumns,
    formConfig: {
      labelWidth: 120,
    },
    canResize: false,
    useSearchForm: false,
    showTableSetting: false,
    showIndexColumn: true,
    bordered: true,
    handleSearchInfoFn(info) {
      return info;
    },
  });
  // 新增
  function handleAdd() {
    let viesObj: any = getDataSource() || [];
    viesObj.push({ name: '', type: '', explanation: '', length: 255, id: new Date().getTime() });
    isBasic.value = false;
    setTableData(viesObj);
    reload();
  }
  // 新增
  function handleAddGeom() {
    let viesObj: any = [];
    viesObj.push(
      {
        name: 'gid',
        type: 'varchar',
        explanation: '',
        length: 255,
        id: new Date().getTime(),
      },
      {
        name: 'geom',
        type: 'geometry(GEOMETRY)',
        explanation: '',
        length: 255,
        id: new Date().getTime(),
      },
    );
    isBasic.value = true;
    setTableData(viesObj);
    reload();
  }
  // 删除
  function handleDelete(record: Recordable) {
    let arr = getDataSource();
    let newArr: any = [];
    arr.forEach((item) => {
      if (item.id !== record.id) {
        newArr.push(item);
      }
    });
    if (
      newArr.length == 2 &&
      newArr[0].name == 'gid' &&
      newArr[0].type == 'varchar' &&
      newArr[1].name == 'geom' &&
      newArr[1].type == 'geometry(GEOMETRY)'
    ) {
      isBasic.value = true;
    } else {
      isBasic.value = false;
    }
    setTableData(newArr);
    reload();
  }
  // 提交
  async function handleOk() {
    // 检测：表名
    if (!tableName.value) {
      createMessage.warn('表名是必填项!');
      return;
    }
    // 删除两端空格、制表符和换行符
    tableName.value = tableName.value.trim();
    // 检测：数据库表名的命名规则
    if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(tableName.value)) {
      createMessage.warn('表名不符合数据库表名的命名规则!');
      return;
    }
    // 检测：数据库是否有此表
    let query: any = { tableName: tableName.value };
    let res = await CheckTableExist(query);
    if (res) {
      createMessage.warn('数据库已有此表名!');
      return;
    }
    let arr = getDataSource();
    // 检测：字段行
    if (!arr || arr.length == 0) {
      createMessage.warn('至少输入一行字段!');
      return;
    }
    let flag = true;
    if (arr) {
      arr.forEach((item) => {
        // 检测：字段名和字段类型不为空
        if (item.name == '' || item.type == '') {
          createMessage.warn('字段名和字段类型都是必填项!');
          flag = false;
        }
        // 检测：字段名中不能含有中文!
        if (/[\u4e00-\u9fa5]/.test(item.name)) {
          createMessage.warn('字段名中不能含有中文!');
          flag = false;
        }
        // 检测：数据库字段名的命名规则
        if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(item.name)) {
          createMessage.warn('字段名不符合数据库字段名的命名规则!');
          flag = false;
        }
        // 检测：备注不能含有英文字符的,和:
        if (
          item.explanation &&
          (item.explanation.indexOf(':') > -1 || item.explanation.indexOf(',') > -1)
        ) {
          createMessage.warn('备注内不能含有英文字符的,和:');
          flag = false;
        }
      });
    }
    // 无错误才能继续进行
    if (flag) {
      let newArr: any = [];
      arr.forEach((item) => {
        newArr.push({
          name: item.name,
          yuanName: item.name,
          type: item.type,
          explanation: item.explanation,
        });
      });
      const param: any = {
        tableName: tableName.value,
        tableInfos: newArr,
      };
      // console.log('param', param);
      if (isUpdate.value) {
        updateTable(param).then((res: Recordable) => {
          console.log('res', res);
          setTableData([]);
          tableName.value = null;
          emit('submit');
          closeModal();
        });
      } else {
        createPicTable(param).then((res: Recordable) => {
          console.log('res', res);
          setTableData([]);
          tableName.value = null;
          emit('submit');
          closeModal();
        });
      }
    }
  }
  // 字典类型
  async function getCodesTypeArr() {
    getLoad({ code: 'clounm_type' }).then((res) => {
      if (res) {
        codesTypeArr.value = [];
        res.forEach((item) => {
          codesTypeArr.value.push({ label: item.itemName, value: item.itemValue });
        });
      }
    });
  }
  // 详情情况下的类型
  function getCodesTypeArrByType(type) {
    for (const codesType of codesTypeArr.value) {
      if (codesType.value === type) {
        return codesType.label;
      }
    }
    return '';
  }
  // 检测：只能有一个geom和geometry(GEOMETRY)
  function changeNameAndType() {
    let arr = getDataSource();
    // geom出现的次数
    let geomNumber = 0;
    // geom当前出现的数组
    let geomShowIndex = 0;
    arr.forEach((item, index) => {
      if (item.name == 'geom' || item.type == 'geometry(GEOMETRY)') {
        geomNumber++;
        geomShowIndex = index;
      }
    });
    if (geomNumber < 2) {
      return true;
    } else {
      createMessage.warn('一个表同时只能有一个geom和空间类型！');
      // 赋值
      arr[geomShowIndex] = {
        name: '',
        yuanName: arr[geomShowIndex].yuanName,
        type: '',
        explanation: arr[geomShowIndex].explanation,
        length: arr[geomShowIndex].length,
        id: arr[geomShowIndex].id,
      };
      setTableData(arr);
      return false;
    }
  }

  onMounted(() => {
    getCodesTypeArr();
  });
</script>
<style>
  .box-container {
    width: 80%;
    margin: 20px auto 0;
  }
  .tab-label {
    width: 100px;
    display: flex;
    align-items: center;
    justify-content: end;
  }
  .red {
    color: red;
  }
</style>
