<template>
  <div :class="prefixCls">
    <div :class="`${prefixCls}__content`">
      <BasicForm ref="myDataBaseFormRef" @register="registerForm">
        <template #addDatabaseTableSlot>
          <div>添加数据库表（请先选择数据库）</div>
          <BasicTable @register="registerDataBaseTable">
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'fieldAction'">
                <div v-if="record.type == 'chlid'">
                  <a-select
                    ref="select"
                    placeholder="请选择"
                    size="small"
                    v-model:value="record.field"
                    :options="record.outColumnKey"
                    :field-names="{ label: 'dbColumnName', value: 'dbColumnName' }"
                  />
                </div>
              </template>
              <template v-if="column.key === 'relationTabAction'">
                <div v-if="record.type == 'chlid'">
                  <a-select
                    ref="select1"
                    size="small"
                    placeholder="请选择"
                    v-model:value="record.relationName"
                    :options="record.relationalTable"
                    :field-names="{ label: 'name', value: 'name' }"
                    @change="handleRelationalTableChange(record)"
                  />
                </div>
              </template>
              <template v-if="column.key === 'relationFieldAction'">
                <div v-if="record.type == 'chlid' && record.relationalTieldTable">
                  <a-select
                    ref="select2"
                    size="small"
                    placeholder="请选择"
                    v-model:value="record.relationField"
                    :options="record.relationalTieldTable"
                    :field-names="{ label: 'dbColumnName', value: 'dbColumnName' }"
                  />
                </div>
              </template>
              <template v-if="column.key === 'action'">
                <TableAction
                  :actions="[
                    {
                      label: '删除',
                      color: 'error',
                      onClick: () => {
                        handleDelete(record);
                      },
                    },
                  ]"
                />
              </template>
            </template>
          </BasicTable>
          <div :class="`${prefixCls}__content-addbtn`" @click="handleAddDataBase">
            <a-button size="small" type="link"
              ><template #icon><PlusOutlined /></template>添加</a-button
            >
          </div>
        </template>
        <template #addDatabaseContantSlot>
          <div :class="`${prefixCls}__content-title`">
            添加数据库关联表，只用来做数据权限设置（请先选择数据库）
          </div>
          <BasicTable @register="registerContanctTable">
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'fname'">
                <div>
                  <a-input v-model:value="record.fname" placeholder="" size="small" />
                </div>
              </template>
              <template v-if="column.key === 'cfield'">
                <div>
                  <a-select
                    ref="select2"
                    size="small"
                    placeholder="请选择"
                    v-model:value="record.cfield"
                    :options="record.FieldTablesArr"
                    :field-names="{ label: 'dbColumnName', value: 'dbColumnName' }"
                  />
                </div>
              </template>
              <template v-if="column.key === 'field'">
                <div>
                  <a-select
                    ref="select2"
                    size="small"
                    placeholder="请选择"
                    v-model:value="record.field"
                    :options="record.FieldTablesArr"
                    :field-names="{ label: 'dbColumnName', value: 'dbColumnName' }"
                  />
                </div>
              </template>
              <template v-if="column.key === 'relationName'">
                <div>
                  <a-select
                    ref="select2"
                    size="small"
                    placeholder="请选择"
                    v-model:value="record.relationName"
                    :options="record.relationalTable"
                    :field-names="{ label: 'label', value: 'value' }"
                    @change="handleConnectNameChange(record)"
                  />
                </div>
              </template>
              <template v-if="column.key === 'relationField'">
                <div v-if="record.relationalTieldTable">
                  <a-select
                    ref="select2"
                    size="small"
                    placeholder="请选择"
                    v-model:value="record.relationField"
                    :options="record.relationalTieldTable"
                    :field-names="{ label: 'dbColumnName', value: 'dbColumnName' }"
                  />
                </div>
              </template>
              <template v-if="column.key === 'action'">
                <TableAction
                  :actions="[
                    {
                      label: '删除',
                      color: 'error',
                      onClick: () => {
                        handleConnectDelete(record);
                      },
                    },
                  ]"
                />
              </template>
            </template>
          </BasicTable>
          <div :class="`${prefixCls}__content-addbtn`" @click="handleAddConnectBase">
            <a-button size="small" type="link"
              ><template #icon><PlusOutlined /></template>添加</a-button
            >
          </div>
        </template>
        <template #addViewsDatabaseTableSlot>
          <div>添加数据库表（请先选择数据库）</div>
          <BasicTable @register="registerViewsTable">
            <template #bodyCell="{ column, record }">
              <template v-if="column.key === 'relationFieldConnect'">
                <div v-if="record.type !== 'main'">
                  <a-select
                    ref="select"
                    placeholder="请选择"
                    size="small"
                    v-model:value="record.field"
                    :options="record.columns"
                    :field-names="{ label: 'label', value: 'value' }"
                  />
                </div>
              </template>

              <template v-if="column.key === 'action'">
                <TableAction
                  :actions="[
                    {
                      label: '删除',
                      color: 'error',
                      onClick: () => {
                        handleViewsDelete(record);
                      },
                    },
                  ]"
                />
              </template>
            </template>
          </BasicTable>
          <div :class="`${prefixCls}__content-addbtn`" @click="handleAddSqlData">
            <a-button size="small" type="link"
              ><template #icon><PlusOutlined /></template>添加</a-button
            >
          </div>
        </template>
      </BasicForm>
      <div :class="`${prefixCls}__content-formLine`"></div>
    </div>
  </div>

  <DataObject @register="registerModal" @backrows="handleBackRows" />

  <sqlModal @register="registerSqlModal" @backrows="handleSqlBackDatas" />
</template>
<script lang="ts" setup>
  import { ref, defineProps, watch } from 'vue';
  import { PlusOutlined } from '@ant-design/icons-vue';
  import { message } from 'ant-design-vue';
  import { getOutKeyList } from '@/api/formdesign/index';

  import { BasicForm, useForm } from '@/components/Form';
  import { formSchema, columns, connectColumns, viewsColumns } from './index.data';
  import { BasicTable, useTable, TableAction } from '@/components/Table';
  import { useModal } from '@/components/Modal';
  import DataObject from './DataObject.vue';
  import sqlModal from './sqlModal.vue';

  const emit = defineEmits(['formDataBack', 'formDataNoBack', 'automaticFormDataBack']);

  const props = defineProps({
    formScheme: {
      default: null,
      type: Object, //编辑时表单数据
    },
    isNextSteps: {
      default: false,
      type: Boolean, //下一步按钮被点击
    },
    isAddVisible: {
      default: false,
      type: Boolean, //判断新增还是编辑
    },
    isStageClick: {
      default: false,
      type: Boolean,
    },
  });

  watch(
    () => props.formScheme,
    (newValue) => {
      if (newValue) {
        if (newValue.scheme.scheme) {
          let schemObj = JSON.parse(newValue.scheme.scheme);
          let obj = {
            id: newValue.info.id,
            schemeId: newValue.info.schemeId,
            name: newValue.info.name,
            category: newValue.info.category,
            DbCode: schemObj.dbCode,
            enabledMark: newValue.info.enabledMark,
            formType: newValue.info.formType,
            description: newValue.info.description,
          };
          setFieldsValue(obj);
          setTimeout(() => {
            if (newValue.info.formType == 1) {
              setTableDataViews(schemObj.db);
            } else if (newValue.info.formType == 0) {
              handleTableData(schemObj.db);
              if (schemObj.rdb) {
                handleConnectTableData(schemObj.rdb);
              }
            } else if (newValue.info.formType == 2) {
              handleTableData(schemObj.db);
              if (schemObj.rdb) {
                handleConnectTableData(schemObj.rdb);
              }
            }
          }, 100);
        }
      }
    },
    { immediate: true, deep: true },
  );
  watch(
    () => props.isNextSteps,
    (newValue) => {
      if (newValue) {
        isNextStepsAndStageClick();
      }
    },
    { immediate: true, deep: true },
  );
  watch(
    () => props.isAddVisible,
    (newValue) => {
      if (newValue) {
        setTableDataMain([]);
        setTableDataConnect([]);
        resetFields();
      }
    },
    { immediate: true, deep: true },
  );
  watch(
    () => props.isStageClick,
    (newValue) => {
      if (newValue) {
        isNextStepsAndStageClick();
      }
    },
  );

  function isNextStepsAndStageClick() {
    validate();
    let formArr = getFieldsValue();

    if (!formArr.name || !formArr.category || !formArr.DbCode) {
      emit('formDataNoBack');
      return false;
    }

    if (formArr.formType == 1) {
      let tableArr = getDataSourceViews();
      let obj = {
        form: formArr,
        table: tableArr,
      };
      let tabArr: any = [];
      if (tableArr && tableArr.length > 0) {
        tableArr.forEach((item) => {
          if (item.type != 'main') {
            tabArr.push(item.field);
          }
        });
      } else {
        emit('formDataNoBack');
        message.error('请添加视图语句', 2);
        return;
      }

      if (tabArr.includes(undefined)) {
        emit('formDataNoBack');
        message.error('请完善数据库表信息', 2);
      } else {
        emit('formDataBack', obj);
      }
    } else if (formArr.formType == 0) {
      let tableArr = getDataSourceMain();
      let connectTab = getDataSourceConnect();
      let obj = {
        form: formArr,
        table: tableArr,
        connect: connectTab,
      };
      let tabArr: any = [];
      let connectArr: any = [];
      if (connectTab && connectTab.length > 0) {
        connectTab.forEach((item) => {
          if (item.type != 'main') {
            connectArr.push(
              item.fname,
              item.cfield,
              item.field,
              item.relationName,
              item.relationField,
            );
          }
        });
      }

      if (tableArr && tableArr.length > 0) {
        tableArr.forEach((item) => {
          if (item.type != 'main') {
            tabArr.push(item.field, item.relationField, item.relationName);
          }
        });
      } else {
        emit('formDataNoBack');
        message.error('请添加数据库表', 2);
        return;
      }

      if (tabArr.includes(undefined)) {
        emit('formDataNoBack');
        message.error('请完善数据库表信息', 2);
      } else {
        if (connectArr.includes(undefined)) {
          emit('formDataNoBack');
          message.error('请完善数据库关联表信息', 2);
        } else {
          emit('formDataBack', obj);
        }
      }
    } else if (formArr.formType == 2) {
      let obj = {
        form: formArr,
      };
      emit('automaticFormDataBack', obj);
    }
  }

  const [registerModal, { openModal: openBaseDataTableModal }] = useModal();
  
  const [registerSqlModal, { openModal: openSqleModal }] = useModal();

  let tabMainList: any = [];
  let isAddConnectTab: any = false;

  const myDataBaseFormRef = ref<any>();
  const [registerForm, { getFieldsValue, setFieldsValue, resetFields, validate }] = useForm({
    labelWidth: 100,
    schemas: formSchema,
    showActionButtonGroup: false,
    baseColProps: { lg: 24, md: 24 },
  });

  const [
    registerViewsTable,
    { reload: reloadViews, setTableData: setTableDataViews, getDataSource: getDataSourceViews },
  ] = useTable({
    title: '',
    rowKey: 'id',
    columns: viewsColumns,
    formConfig: {
      labelWidth: 120,
    },
    useSearchForm: false,
    showTableSetting: false,
    bordered: false,
    canResize: false,
    pagination: false,
    actionColumn: {
      width: 80,
      title: '操作',
      dataIndex: 'action',
      fixed: undefined,
    },
  });

  const [
    registerContanctTable,
    {
      reload: reloadConnect,
      setTableData: setTableDataConnect,
      getDataSource: getDataSourceConnect,
    },
  ] = useTable({
    title: '',
    rowKey: 'id',
    columns: connectColumns,
    formConfig: {
      labelWidth: 120,
    },
    useSearchForm: false,
    showTableSetting: false,
    bordered: false,
    pagination: false,
    canResize: false,
    actionColumn: {
      width: 80,
      title: '操作',
      dataIndex: 'action',
      fixed: undefined,
    },
  });

  const [
    registerDataBaseTable,
    { reload: reloadMain, setTableData: setTableDataMain, getDataSource: getDataSourceMain },
  ] = useTable({
    title: '',
    rowKey: 'id',
    columns,
    formConfig: {
      labelWidth: 120,
    },
    useSearchForm: false,
    showTableSetting: false,
    bordered: false,
    pagination: false,
    canResize: false,
    actionColumn: {
      width: 80,
      title: '操作',
      dataIndex: 'action',
      fixed: undefined,
    },
  });

  function handleAddDataBase() {
    isAddConnectTab = true;
    const anyformobj = ref<any>(myDataBaseFormRef.value.getFieldsValue());

    if (anyformobj.value.DbCode) {
      openBaseDataTableModal(true, { dbCode: anyformobj.value.DbCode });
    } else {
      message.warning('请选择数据库');
    }
  }

  function handleAddConnectBase() {
    isAddConnectTab = false;
    const anyformobj = ref<any>(myDataBaseFormRef.value.getFieldsValue());

    if (anyformobj.value.DbCode) {
      openBaseDataTableModal(true, { dbCode: anyformobj.value.DbCode });
    } else {
      message.warning('请选择数据库');
    }
  }

  function handleDelete(record: Recordable) {
    let arr = getDataSourceMain();
    let newArr: any = [];
    arr.forEach((item) => {
      if (item.name !== record.name) {
        newArr.push(item);
      }
    });
    newArr.forEach((item, index) => {
      if (index == 0) {
        item.type = 'main';
      } else {
        item.type = 'chlid';
      }
    });

    setTableDataMain(newArr);
    reloadMain();
  }
  function handleConnectDelete(record: Recordable) {
    let arr = getDataSourceConnect();
    let newArr: any = [];
    arr.forEach((item) => {
      if (item.index !== record.index) {
        newArr.push(item);
      }
    });

    setTableDataConnect(newArr);
    reloadConnect();
  }

  function handleBackRows(ModuleId) {
    let formTableArr = getDataSourceMain();
    let tabList: any = formTableArr || [];
    let repeatArr: any = [];
    if (isAddConnectTab) {
      ModuleId.forEach((item) => {
        if (formTableArr && formTableArr.length > 0) {
          formTableArr.forEach((val) => {
            if (item.tableName == val.name) {
              repeatArr.push(val.name);
            } else {
              tabList.push({
                name: item.tableName,
              });
            }
          });
        } else {
          tabList.push({
            name: item.tableName,
          });
        }
      });

      tabList.forEach((item, index) => {
        if (index == 0) {
          item.type = 'main';
        } else {
          item.type = 'chlid';
        }
      });
      const uniqueMap = {};
      if (repeatArr.length > 0) {
        message.warning('重复添加表' + repeatArr, 2);
      }
      let newarr = tabList.filter((item) => {
        const isNotPresent = !uniqueMap[item.name];
        uniqueMap[item.name] = true;
        return isNotPresent;
      });

      handleTableData(newarr);
    } else {
      let connectTableArr = getDataSourceConnect();
      let connectList = connectTableArr || [];

      let bisArr;

      if (tabMainList && tabMainList.length > 0) {
        bisArr = ModuleId.filter((item2) => {
          return tabMainList.some((item1) => item1.name === item2.tableName);
        });
        let filteredArr1 = ModuleId.filter((item2) => {
          return !tabMainList.some((item1) => item1.name === item2.tableName);
        });
        filteredArr1.forEach((item) => {
          connectList.push({
            name: item.tableName,
          });
        });
      } else {
        ModuleId.forEach((item) => {
          connectList.push({
            name: item.tableName,
          });
        });
      }
      if (bisArr) {
        bisArr.forEach((item) => {
          repeatArr.push(item.tableName);
        });
      }
      if (repeatArr.length > 0) {
        message.warning('不能是表单已经绑定的表' + repeatArr, 2);
      }

      handleConnectTableData(connectList);
    }
  }
  function handleConnectTableData(record: Recordable) {
    const anyformobj = ref<any>(myDataBaseFormRef.value.getFieldsValue());
    let tabDatas: any = record;
    let optionsArr: any = [];
    if (tabMainList && tabMainList.length > 0) {
      tabMainList.forEach((item) => {
        optionsArr.push({
          label: item.name,
          value: item.name,
        });
      });
    }

    if (tabDatas) {
      tabDatas.forEach((item, index) => {
        item.index = index;
        item.relationalTable = optionsArr;
        getOutKeyList({ tableNames: item.name, dbCode: anyformobj.value.DbCode }).then(
          (data: Recordable) => {
            item.FieldTablesArr = data[0]?.db_codecolumnsList;
          },
        );
        if (item.relationName) {
          getOutKeyList({ tableNames: item.relationName, dbCode: anyformobj.value.DbCode }).then(
            (data: Recordable) => {
              item.relationalTieldTable = data[0]?.db_codecolumnsList;
            },
          );
        }
      });
    }
    setTableDataConnect(tabDatas);
    reloadConnect();
  }

  function handleTableData(record: Recordable) {
    const anyformobj = ref<any>(myDataBaseFormRef.value.getFieldsValue());
    let tabDatas: any = record;
    if (tabDatas) {
      tabDatas.forEach((item) => {
        if (item.type !== 'main') {
          getOutKeyList({ tableNames: item.name, dbCode: anyformobj.value.DbCode }).then(
            (data: Recordable) => {
              item.outColumnKey = data[0]?.db_codecolumnsList;
            },
          );
          item.relationalTable = record.filter((val) => item.name !== val.name);
          if (item.relationName) {
            getOutKeyList({ tableNames: item.relationName, dbCode: anyformobj.value.DbCode }).then(
              (data: Recordable) => {
                item.relationalTieldTable = data[0]?.db_codecolumnsList;
              },
            );
          }
        }
      });
    }
    tabMainList = tabDatas;
    setTableDataMain(tabDatas);
    reloadMain();
  }
  function handleRelationalTableChange(record: Recordable) {
    const anyformobj = ref<any>(myDataBaseFormRef.value.getFieldsValue());
    let arr = getDataSourceMain();

    arr.forEach((item) => {
      if (item.name == record.name) {
        getOutKeyList({ tableNames: record.relationName, dbCode: anyformobj.value.DbCode }).then(
          (data: Recordable) => {
            item.relationalTieldTable = data[0]?.db_codecolumnsList;
            item.relationField = undefined;
          },
        );
      }
    });
    setTableDataMain(arr);
    reloadMain();
  }
  function handleConnectNameChange(record: Recordable) {
    const anyformobj = ref<any>(myDataBaseFormRef.value.getFieldsValue());
    let arr = getDataSourceConnect();
    arr.forEach((item) => {
      if (item.index == record.index) {
        getOutKeyList({ tableNames: record.relationName, dbCode: anyformobj.value.DbCode }).then(
          (data: Recordable) => {
            item.relationalTieldTable = data[0]?.db_codecolumnsList;
            item.relationField = undefined;
          },
        );
      }
    });
    setTableDataConnect(arr);
    reloadConnect();
  }
  function handleAddSqlData() {
    const anyformobj = ref<any>(myDataBaseFormRef.value.getFieldsValue());
    let viesObj = getDataSourceViews() || [];
    if (anyformobj.value.DbCode) {
      openSqleModal(true, { DbCode: anyformobj.value.DbCode, length: viesObj.length });
    } else {
      message.warning('请选择数据库');
    }
  }

  function handleSqlBackDatas(ModuleId: Recordable) {
    let viesObj: any = getDataSourceViews() || [];
    viesObj.push(ModuleId);
    viesObj.forEach((item, index) => {
      item.index = index;
      if (index == 0) {
        item.type = 'main';
      } else {
        item.type = 'chlid';
      }
    });

    setTableDataViews(viesObj);
    reloadViews();
  }
  function handleViewsDelete(record: Recordable) {
    let arr = getDataSourceViews();
    let newArr: any = [];
    arr.forEach((item) => {
      if (item.index !== record.index) {
        newArr.push(item);
      }
    });

    setTableDataViews(newArr);
    reloadViews();
  }
  const prefixCls = 'l-rblock';
</script>
<style lang="less" scoped>
  .l-rblock {
    width: 100%;
    height: 100%;
    background-color: @border-color-base;

    &__content {
      position: relative;
      box-sizing: border-box;
      width: 100%;
      max-width: 794px;
      height: 100%;
      margin: auto;
      padding: 24px;
      overflow: hidden auto;
      border-radius: 4px;
      background-color: @component-background;

      &-addbtn {
        margin-top: -20px;
        border: 1px dashed #f0f0f0;
        border-color: @border-color-base;
        text-align: center;
        cursor: pointer;

        &:hover {
          border-color: #409eff;
        }
      }

      &-title {
        padding-top: 20px;
      }

      &-formLine {
        height: 50px;
      }
    }
  }
</style>
