<!--
 * @Author: Jason Liu
 * @Date: 2022-09-28 11:09:44
 * @Desc: sql函数输入器
-->
<template>
  <a-drawer
    width="88%"
    :visible="isShow"
    @close="isShow = false"
    :destroy-on-close="true"
    :closable="false"
    :zIndex="1001"
    class="set_source_column_editor_body"
  >
    <a-tabs
      v-model="sourceType"
      type="card"
      v-if="isShow"
    >
      <a-tab-pane key="fun" :tab="$t('内容设置')">
        <a-row :gutter="[2]">
          <a-col :span="6">
            <a-input-search
              :placeholder="$t('搜索表内容')"
              @search="searchTableList"
            >
            </a-input-search>
            <div class="table_list">
              <vxe-table
                show-overflow
                show-header-overflow
                :row-config="{ isHover: true }"
                stripe
                height="auto"
                ref="tables"
                :data="viewJoinTables"
                :show-header="false"
                border="outer"
                :key="table_key"
                :scroll-y="{ enabled: true, gt: 15 }"
                :tree-config="{
                  indent: 4,
                  transform: true,
                  expandAll: true,
                  trigger: 'row',
                }"
              >
                <vxe-column
                  tree-node
                  :filters="[{ data: '' }]"
                  field="columnName"
                  :filter-method="filterTableNameMethod"
                >
                  <template #default="{ row }">
                    <span
                      class="table_items"
                      v-if="row.tableName"
                    >
                      <i><svg-icon type="icon_data_table" /></i>
                      {{ row.tableName }}
                    </span>
                    <span
                      class="fun_items"
                      v-else
                      :draggable="true"
                      @dragstart="dragTable"
                      :data-call="`${row.parentId}.${row.columnName}`"
                    >
                      {{ row.columnName }}</span
                    >
                  </template>
                </vxe-column>
              </vxe-table>
            </div>
          </a-col>
          <a-col :span="12" class="sql_body">
            <div
              class="select-div"
              v-if="isField"
            >
              <a-select
                style="width: 140px; margin-right: 5px"
                v-model="valueField.orgId"
                :placeholder="$t('请选择机构')"
                @change="getSysList(1)"
                v-if="!$versionCompare('6.0.2503')"
              >
                <a-select-option
                  v-for="item in hospitalList"
                  :key="item.id"
                  :value="item.id"
                >{{ item.shortName }}</a-select-option>
              </a-select>
              <a-select
                style="width: 140px; margin-right: 5px"
                v-model="valueField.sysId"
                :placeholder="$t('请选择系统')"
                @change="getFieldList(1)"
              >
                <a-select-option
                  v-for="item in sysList"
                  :key="item.sysId"
                  :value="item.sysId"
                >{{ item.name }}</a-select-option>
              </a-select>
              <a-select
                style="width: 140px; margin-right: 5px"
                v-model="valueField.field"
                :placeholder="$t('请选择值域')"
              >
                <a-select-option
                  v-for="item in fieldList"
                  :key="item.codeSystemId"
                  :value="item.codeSystemId"
                >{{ item.codeSystemName }}</a-select-option>
              </a-select>
              <a-select
                style="width: 140px; margin-right: 5px"
                v-model="valueField.fieldType"
                :placeholder="$t('请选择值域类别')"
              >
                <a-select-option
                  v-for="item in fieldTypeList"
                  :key="item"
                  :value="item"
                >{{ item }}</a-select-option>
              </a-select>
              <a-button
                type="primary"
                @click="valueMapping(true)"
                >{{ $t('值域映射') }}</a-button
              >
            </div>
            <div
              class="sql-editor"
              :class="{ 'sql-editor-isField': isField }"
            >
              <gl-sql-editor
                v-model="sourceMap.columnName"
                ref="glSqlEditor"
                :tables="tablesColumns"
              />
            </div>
            <div
              class="value-mapping-table"
              v-if="isField"
            >
              <vxe-table
                :loading="loading"
                show-overflow
                :data="fieldTableData"
                :row-config="{ isHover: true }"
                stripe
                :scroll-y="{ enabled: true, gt: 15 }"
                height="auto"
                ref="fieldTableData"
              >
                <vxe-column :title="$t('源Code')">
                  <template #default="{ row }">
                    {{ row.srcCode }}
                  </template>
                </vxe-column>
                <vxe-column :title="$t('源Name')">
                  <template #default="{ row }">
                    {{ row.srcName }}
                  </template>
                </vxe-column>
                <vxe-column
                  :title="$t('目标Id')"
                  width="100"
                >
                  <template #default="{ row }">
                    {{ row.targetId }}
                  </template>
                </vxe-column>
                <vxe-column :title="$t('目标Code')">
                  <template #default="{ row }">
                    {{ row.targetCode }}
                  </template>
                </vxe-column>
                <vxe-column :title="$t('目标Name')">
                  <template #default="{ row }">
                    {{ row.targetName }}
                  </template>
                </vxe-column>
              </vxe-table>
            </div>
          </a-col>
          <a-col :span="6">
            <a-input-search
              :placeholder="$t('搜索函数')"
              v-model.lazy="functionkey"
              @search="searchFunctionList"
            >
              <a-icon
                slot="addonBefore"
                @click="showFunctionHelp = true"
                type="question-circle"
              />
            </a-input-search>
            <div class="function_list">
              <vxe-table
                show-overflow
                show-header-overflow
                :row-config="{ isHover: true }"
                :show-header="false"
                :key="`listkey${listkey}`"
                stripe
                height="auto"
                ref="functionList"
                :data="showFunctionts"
                border="outer"
                :scroll-y="{ enabled: true, gt: 20 }"
                :tree-config="{
                  expandAll: true,
                  trigger: 'row',
                }"
              >
                <vxe-column
                  tree-node
                  :filters="[{ data: '' }]"
                  field="name"
                >
                  <template #default="{ row }">
                    <a-popover
                      :title="row.sqlFunc"
                      v-if="row.sqlFunc"
                    >
                      <template slot="content">
                        <p style="max-width: 300px">{{ row.desc }}</p>
                      </template>

                      <div class="fun_items">
                        <div
                          :draggable="true"
                          @dragstart="dragFunc"
                        >
                          {{ row.sqlFunc }}
                        </div>
                        <div
                          class="fun_desc"
                          v-if="false"
                        >
                          {{ row.desc }}
                        </div>
                      </div>
                    </a-popover>
                    <template v-else>{{ row.name }}</template>
                  </template>
                </vxe-column>
              </vxe-table>
            </div>
          </a-col>
        </a-row>
      </a-tab-pane>
      <template #tabBarExtraContent>
        <!-- <a-checkbox
          v-model="isField"
          v-if="$versionCompare('6.0.2503')"
          @change="changeIsField"
          >{{ $t('值域映射') }}</a-checkbox
        > -->
        <i
          class="w-icon-close"
          @click="isShow = false"
        ></i>
      </template>
    </a-tabs>

    <div class="a_foot_nuttop">
      <a-button @click="isShow = false">{{ $t('关闭') }}</a-button>
      &nbsp;
      <a-button
        type="primary"
        @click="confirmSet()"
        >{{ $t('确定') }}</a-button
      >
    </div>
    <a-modal
      v-model="showFunctionHelp"
      width="78%"
      :z-index="1015"
      :title="$t('函数说明')"
    >
      <template slot="footer">
        <a-button
          key="back"
          @click="showFunctionHelp = false"
          >{{ $t('关闭') }}</a-button
        >
      </template>
      <div class="function_help_list">
        <vxe-table
          class="function_help_list_table"
          show-overflow
          show-header-overflow
          :row-config="{ isHover: true }"
          :key="listkey"
          stripe
          height="auto"
          :data="showFunctionts"
          border="outer"
          :scroll-y="{ enabled: true, gt: 15 }"
          :tree-config="{
            expandAll: true,
            trigger: 'row',
          }"
        >
          <vxe-column
            tree-node
            :title="$t('函数说明')"
          >
            <template #default="{ row }">
              <template v-if="row.sqlFunc">
                <a-button type="link">{{ row.sqlFunc }}</a-button>
                <br />
                <span :title="row.desc">
                  {{ row.desc }}
                </span>
              </template>
              <template v-else>{{ row.name }}</template>
            </template>
          </vxe-column>
        </vxe-table>
      </div>
    </a-modal>
  </a-drawer>
</template>
<script>
  const glSqlEditor = require('w-vue-middle/components/glSqlEditor').default;
  const $dataIntegration = require('w-vue-chongqing/src/api/dataIntegration');

  export default {
    name: 'setSourceColumn',
    components: { glSqlEditor },
    props: {
      show: {
        type: Boolean,
        default: false,
      },
      outputTable: {
        type: Object,
        default: () => {
          return {};
        },
      },
      value: {
        type: Object,
        default: () => {
          return {};
        },
      },
      sourceColumns: {
        type: Array,
        default: () => {
          return [];
        },
      },
    },
    computed: {
      isShow: {
        get() {
          return this.show;
        },
        set(val) {
          this.$emit('update:show', val);
        },
      }
    },
    data() {
      return {
        functionList: [], //函数列表
        showFunctionts: [], //显示的函数列表
        sqlText: undefined,
        functionkey: undefined, //函数搜索
        tableKey: undefined,
        tablesColumns: {},
        listkey: 0,
        table_key: 0,
        sourceType: 'fun',
        joinTables: [],
        viewJoinTables: [],
        showFunctionHelp: false, //显示帮助文档
        sourceMap: {
          asName: undefined,
          autoincrement: false,
          checked: true,
          columnName: undefined,
          columnSize: undefined,
          columnType: undefined,
          notNull: undefined,
          pk: undefined,
          select: undefined,
          tableAsName: undefined,
          tableCode: undefined,
          tableId: undefined,
          tableName: undefined,
          _X_ROW_KEY: undefined,
        },
        valueField: {
          orgId: undefined,
          sysId: undefined,
          field: undefined,
          fieldType: undefined,
          sqlText: undefined,
        },
        sysList: [],
        fieldList: [],
        fieldTypeList: [],
        hospitalList: [],
        fieldTableData: [],
        loading: false,
        isField: false,
      };
    },
    created() {
      this.getFunctionList();
      this.getSourceColumnInfo();
      this.parseTable();
    },
    methods: {
      /**
       * @Author: Jason Liu
       * @description: 搜索内容表信息
       */
      searchTableList(e = undefined) {
        let tempData = this.joinTables;
        if (e) {
          let val = e.toLocaleLowerCase();
          tempData = this.joinTables.filter((row) => {
            if (row.columnName) {
              return row.columnName.toLocaleLowerCase().indexOf(val) > -1;
            } else {
              return false;
            }
          });
        }

        this.viewJoinTables = tempData;
        this.table_key++;
      },
      /**
       * @Author: Jason Liu
       * @description: 查询表字段信息
       */
      filterTableNameMethod({ option, row }) {
        let val = option.data.toLocaleLowerCase();
        if (row.columnName) {
          return row.columnName.toLocaleLowerCase().indexOf(val) > -1;
        } else {
          return false;
        }
      },
      /**
       * @Author: Jason Liu
       * @description: 拖动表复制事件
       */
      dragTable(event) {
        event.dataTransfer.setData('text/plain', event.target.dataset.call);
      },
      /**
       * @Author: Jason Liu
       * @description: 拖动函数复制事件
       */
      dragFunc(event) {
        event.dataTransfer.setData('text/plain', event.target.outerText);
      },
      /**
       * @Author: Jason Liu
       * @description: 设置行数据样式
       */
      setRowDataClass({ row, rowIndex }) {
        return this.sourceMap.columnName ==
          `${row.tableAsName || this.tables.tableCode}.${row.columnName}`
          ? 'row--current'
          : '';
      },
      /**
       * @Author: Jason Liu
       * @description: 获取函数列表
       */
      getFunctionList() {
        $dataIntegration.getSQlFunctonList().then((req) => {
          this.functionList = req.data.map((item, i) => {
            item.id = i;
            item.children = item.sub;
            return item;
          });

          this.searchFunctionList();

          this.functionList.forEach((fun) => {
            fun.sub.forEach((sub) => {
              this.tablesColumns[sub.sqlFunc] = [];
            });
          });
        });
      },
      /**
       * @Author: Jason Liu
       * @description: 确认提交内容
       */
      confirmSet() {
        this.isShow = false;
        if (this.isField &&
          this.sourceMap.columnName?.includes('valueMapping')
          && this.fieldTableData?.length === 0
        ) {
          const input = this.sourceMap.columnName;
          // 直接复制而不是生成的，自动解析sql
          this.valueField.sysId = this.extractMatchValue(input, /source_sys_id=="(\d+)"/);
          this.valueField.field = this.extractMatchValue(input, /code_system_id=="(\d+)"/);
          this.valueField.fieldType = this.extractMatchValue(input, /valueMapping\(.*?,\s*['"]?([^'",)]+)['"]?/);
        }
        this.value.source = {
          ...this.sourceMap,
          valueMapData: {
            isField: this.isField,
            ...this.valueField,
          },
        };
        this.$emit('change', this.value);
      },
      /**
       * @Author: Jason Liu
       * @description: 查询函数
       */
      searchFunctionList() {
        let tempList = JSON.parse(JSON.stringify(this.functionList));
        if (this.functionkey) {
          let val = this.functionkey.toLocaleLowerCase();
          tempList = tempList.map((item) => {
            item.children = item.sub.filter((sub) => {
              return sub.sqlFunc.toLocaleLowerCase().indexOf(val) > -1;
            });
            return item;
          });
        }
        this.showFunctionts = tempList;
        this.listkey++;
      },
      /**
       * @Author: Jason Liu
       * @description: 获取来源输出列信息
       */
      getSourceColumnInfo() {
        this.sourceMap = {...this.value?.source}
      },
      /**
       * @Author: Jason Liu
       * @description: 标准化表格
       */
      parseTable() {
        this.tablesColumns = {};
        this.joinTables = [];

        this.sourceColumns.forEach((column, i) => {
          let code = column.tableAsName || this.tables.tableCode;
          if (this.tablesColumns[code]) {
          } else {
            this.tablesColumns[code] = [];

            this.joinTables.push({
              id: code,
              tableName: code,
            });
          }
          this.joinTables.push({
            columnName: column.columnName,
            parentId: code,
            id: i,
          });

          this.tablesColumns[code].push(column.columnName);

          this.searchTableList();
        });
      },
      // 值域映射
      valueMapping(isSet = false) {
        if (!this.valueField.orgId || !this.valueField.sysId || !this.valueField.field || !this.valueField.fieldType ) {
          this.$message.warning($t('请先选择系统、值域和值域类别'));
          return;
        }
        if (isSet) {
          let code = undefined
          if (!$versionCompare('6.0.2503')) {
            code = `valueMapping(,'${this.valueField.fieldType}','org_id=="${this.valueField.orgId}"&&source_sys_id=="${this.valueField.sysId}"&&code_system_id=="${this.valueField.field}"')`;
          } else {
            code = `valueMapping(,'${this.valueField.fieldType}','source_sys_id=="${this.valueField.sysId}"&&code_system_id=="${this.valueField.field}"')`;
          }
          if (this.sourceMap.columnName) {
            this.sourceMap.columnName += '\n' + code;
          } else {
            this.sourceMap.columnName = code;
          }
        }
        this.loading = true;
        $dataIntegration
          .queryDomainList({
            dbId: this.outputTable.data.dbId || '',
            platSysId: this.sysList.find((item) => item.code === 'code')?.sysId,
            thirdSysId: this.valueField.sysId,
            codeSystemId: this.valueField.field,
          })
          .then((res) => {
            this.fieldTableData = [...res.data];
            this.loading = false;
            if (this.sourceMap.columnName) {
              this.sourceMap.columnName = this.sourceMap.columnName.replace(
                'thirdSysId',
                this.valueField.sysId || '',
              );
              this.sourceMap.columnName = this.sourceMap.columnName.replace(
                'domainId',
                this.valueField.field || '',
              );
              this.sourceMap.columnName = this.sourceMap.columnName.replace(
                'mappingValue',
                this.valueField.fieldType || '',
              );
            }
          })
          .finally(() => {
            this.loading = false;
          });
      },
      // 获取机构
      getHospitalInfo() {
        $dataIntegration
          .getValueMappingQueryOrg({
            dbId: this.outputTable.data.dbId || '',
          })
          .then((res) => {
            this.hospitalList = [...res.data] || [];
          });
      },
      // 获取系统
      getSysList(type) {
        if (type === 1) {
          this.valueField.sysId = undefined;
        }
        $dataIntegration
          .queryPlat({
            dbId: this.outputTable.data.dbId || '',
            orgId: this.valueField.orgId || '',
          })
          .then((res) => {
            this.sysList = [...res.data] || [];
          });
      },
      // 获取值域
      getFieldList(type) {
        if (type === 1) {
          this.valueField.field = undefined;
        }
        if (this.valueField.sysId) {
          $dataIntegration
            .queryPlatDomain({
              dbId: this.outputTable.data.dbId || '',
              sysId: this.valueField.sysId,
            })
            .then((res) => {
              this.fieldList = [...res.data] || [];
            });
        }
      },
      // 获取值域类别
      getFieldTypeList() {
        $dataIntegration
          .queryValueMappingMeta({
            dbId: this.outputTable.data.dbId || '',
          })
          .then((res) => {
            this.fieldTypeList = [...res.data] || [];
          });
      },
      extractMatchValue(inputString, pattern) {
        return inputString.match(pattern)?.[1] || null;
      },
      initVersionSpecificMethods() {
        if (!$versionCompare('6.0.2503')) return;
        this.valueField.orgId = $storage.get("accept_system_org");
        [this.getHospitalInfo, this.getFieldTypeList, this.getSysList, this.getFieldList]
          .forEach(fn => typeof fn === 'function' && fn());
      },
      /**
       * @Author: Jason Liu
       * @description: 获取值域映射信息
       */
      getValueMapData() {
        // 解决直接复制valueMapping，valueMapData为空问题
        if (this.sourceMap.columnName?.includes('valueMapping') && !this.sourceMap.valueMapData) {
          this.isField = true;
          const input = this.sourceMap.columnName;
          this.valueField.sysId = this.extractMatchValue(input, /source_sys_id=="(\d+)"/);
          this.valueField.field = this.extractMatchValue(input, /code_system_id=="(\d+)"/);
          this.valueField.fieldType = this.extractMatchValue(input, /valueMapping\(.*?,\s*['"]?([^'",)]+)['"]?/);
          this.initVersionSpecificMethods();
          return this.valueMapping(false);
        }
        if (this.sourceMap.valueMapData?.isField) {
          this.isField = true;
          this.valueField = { ...this.sourceMap.valueMapData };
          this.initVersionSpecificMethods();
          return this.valueMapping(false);
        }
        this.sysList = [];
        this.fieldList = [];
      },
      changeIsField() {
        if (this.isField) {
          this.getHospitalInfo();
          this.getFieldTypeList();
          this.getSysList();
          this.getFieldList();
        }
      },
    },
    watch: {
      isShow(val) {
        if (val) {
          this.getFunctionList();
          this.getSourceColumnInfo();
          this.parseTable();
          this.isField = false;
          this.valueField = {
            orgId: $storage.get("accept_system_org"),
            sysId: undefined,
            field: undefined,
            fieldType: undefined,
            sqlText: undefined,
          };
          this.fieldTableData = [];
          this.sysList = [];
          this.getValueMapData();
        }
      },
      
    },
  };
</script>
<style lang="less" scoped>
  .function_help_list {
    height: 400px;
    .vxe-table--render-default .vxe-body--column.col--ellipsis > .vxe-cell {
      max-height: initial;
      .c--tooltip {
        height: 80px !important;
      }
    }
  }
  .set_source_column_editor_body {
    .sql_body {
      height: calc(100vh - 140px);
    }
    .table_column_list {
      height: calc(100vh - 190px);
      border-right: 1px solid #dedede;
    }
    .table_list {
      margin-top: 6px;
      height: calc(100vh - 170px);
    }
    .function_list {
      border-left: 1px solid #dedede;
      margin-top: 6px;
      height: calc(100vh - 170px);
    }
    .table_items {
      i {
        color: #2d5afa;
      }
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
      -o-text-overflow: ellipsis;
    }
    .fun_items {
      color: #2d5afa;
      div {
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;
        -o-text-overflow: ellipsis;
      }
      .fun_desc {
        color: #666666;
        font-size: 12px;
      }
    }
    .select-div {
      height: 30px;
      display: flex;
      justify-content: flex-end;
      align-items: center;
      margin-bottom: 10px;
    }

    .sql-editor {
      width: 100%;
      height: 100%;
    }
    .sql-editor-isField {
      width: 100%;
      height: 300px;
    }
    .value-mapping-table {
      height: calc(100% - 342px);
      margin-top: 10px;
    }
    .w-icon-close {
      cursor: pointer;
    }
  }
  .sql-div {
    height: calc(100vh - 160px);
    margin-top: 6px;
  }
  .function_help_list_table{
    ::v-deep .vxe-cell {
      height: auto !important;
    }
  }
</style>
