<template>
  <div
    id="box"
    class="bs-container"
    @mousemove="mousemoveOnBox"
    @mouseup="mouseupOnBox"
  >
    <el-row
      v-show="datasetType === null"
      type="flex"
      class="layout"
    >
      <div
        id="left-box"
        class="left-box"
        :style="{ 'transition': transition + 's' }"
      >
        <div class="inner-container">
          <TypeTree
            ref="datasetsTypeTree"
            :dataset-type-list="datasetTypeList"
            :app-code="appCode"
            @nodeClick="nodeClick"
            @refreshData="refreshData"
            @expandedNodes="expandedNodes"
            @reCategory="getTreeList"
          />
        </div>
      </div>
      <div
        class="right-box inner-container"
        :style="{ 'transition': transition + 's' }"
      >
        <div
          id="resize"
          class="resize  pack-up-box"
          @mousedown="mousedown"
          @mouseup="mouseup"
          @mousemove="mousemove"
        >
          <a
            v-if="isPackUpTree"
            @click="packUpTree"
            @mousedown="resize = null"
            @mouseup="resize = null"
            @mousemove="resize = null"
          >
            <i :class="isPackUpTree === false ? 'el-icon-caret-left' : 'el-icon-caret-right'" />
          </a>
          <a
            v-else
            class="visible-pack-up"
          >
            <span>||</span>
          </a>
        </div>
        <el-form
          ref="queryForm"
          :model="queryForm"
          class="filter-container bs-el-form"
          @submit.native.prevent
        >
          <el-form-item
            class="filter-item"
            prop="name"
          >
            <el-input
              v-model="queryForm.name"
              class="bs-el-input"
              placeholder="请输入数据集名称"
              clearable
              @keyup.enter.native="handleSearch()"
              @clear="handleSearch()"
            />
          </el-form-item>
          <el-form-item
            class="filter-item"
            prop="labelIds"
          >
            <el-select
              v-model="queryForm.labelIds"
              class="bs-el-select"
              popper-class="bs-el-select"
              clearable
              filterable
              multiple
              collapse-tags
              placeholder="请选择数据集关联标签"
              @clear="handleSearch()"
            >
              <el-option
                v-for="labelItem in labelList"
                :key="labelItem.id"
                :label="labelItem.labelName"
                :value="labelItem.id"
              />
            </el-select>
          </el-form-item>
          <el-form-item class="filter-item">
            <el-button
              :loading="dataListLoading"
              type="primary"
              icon="el-icon-search"
              @click="handleSearch()"
            >
              查询
            </el-button>
          </el-form-item>
          <el-form-item class="filter-item">
            <el-button
              v-if="toAdd"
              class="bs-el-button-default"
              @click="addDataset"
            >
              新增
            </el-button>
          </el-form-item>
        </el-form>
        <div class="bs-table-box">
          <el-table
            v-if="isDialog"
            ref="userTable"
            v-loading="dataListLoading"
            class="bs-el-table bs-scrollbar"
            :element-loading-text="loadingText"
            :data="tableData"
            :header-cell-style="sortStyle"
            @sort-change="reSort"
            @current-change="handleCurrentChange"
            @select="selectDs"
            @select-all="selectAll"
          >
            <el-empty slot="empty" />
            <el-table-column
              v-if="isDialog && multiple"
              type="selection"
              width="55"
            />
            <el-table-column
              prop="name"
              label="数据集名称"
              align="left"
              show-overflow-tooltip
            >
              <template slot-scope="scope">
                <el-radio
                  v-if="isDialog && !multiple"
                  v-model="curRow"
                  :label="scope.row"
                >
                  {{ scope.row.name }}
                </el-radio>
                <span v-else>{{ scope.row.name }}</span>
              </template>
            </el-table-column>
            <el-table-column
              prop="datasetType"
              label="数据集类型"
              align="center"
              show-overflow-tooltip
            >
              <template slot-scope="scope">
                <span>{{ datasetTypeList.find(type=>type.datasetType===scope.row.datasetType) ? datasetTypeList.find(type=>type.datasetType===scope.row.datasetType).name : '其他' }}</span>
              </template>
            </el-table-column>
            <el-table-column
              prop="labelIds"
              label="标签"
              align="center"
              show-overflow-tooltip
            >
              <template slot-scope="scope">
                <span>{{ getLabels(scope.row.labelIds).join(',') }}</span>
              </template>
            </el-table-column>
            <el-table-column
              prop="remark"
              label="备注"
              align="left"
              show-overflow-tooltip
            />
            <!--操作栏-->
            <el-table-column
              v-if="doEdit||isDelete"
              label="操作"
              width="200"
              align="center"
            >
              <template
                v-if="showOperate(scope.row.datasetType)"
                slot-scope="scope"
              >
                <el-button
                  v-if="doEdit"
                  class="bs-el-button-default"
                  :disabled="scope.row.editable === 1 && !appCode"
                  @click="toEdit(scope.row.id, scope.row.datasetType, scope.row.name, scope.row.typeId)"
                >
                  编辑
                </el-button>

                <el-button
                  v-if="isDelete"
                  class="bs-el-button-default"
                  :loading="scope.row.loading"
                  :disabled="scope.row.editable === 1 && !appCode"
                  @click="delDataset(scope.row)"
                >
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
          <el-table
            v-else
            ref="userTable"
            v-table
            v-loading="dataListLoading"
            height="0"
            class="bs-el-table bs-scrollbar"
            :element-loading-text="loadingText"
            :data="tableData"
            :header-cell-style="sortStyle"
            @sort-change="reSort"
            @current-change="handleCurrentChange"
            @select="selectDs"
            @select-all="selectAll"
          >
            <el-empty slot="empty" />
            <el-table-column
              v-if="isDialog && multiple"
              type="selection"
              width="55"
            />
            <el-table-column
              prop="name"
              label="数据集名称"
              align="left"
              show-overflow-tooltip
            >
              <template slot-scope="scope">
                <el-radio
                  v-if="isDialog && !multiple"
                  v-model="curRow"
                  :label="scope.row"
                >
                  {{ scope.row.name }}
                </el-radio>
                <span v-else>{{ scope.row.name }}</span>
              </template>
            </el-table-column>
            <el-table-column
              prop="datasetType"
              label="数据集类型"
              align="center"
              show-overflow-tooltip
            >
              <template slot-scope="scope">
                <span>{{ datasetTypeList.find(type=>type.datasetType===scope.row.datasetType) ? datasetTypeList.find(type=>type.datasetType===scope.row.datasetType).name : '其他' }}</span>
              </template>
            </el-table-column>
            <el-table-column
              prop="labelIds"
              label="标签"
              align="center"
              show-overflow-tooltip
            >
              <template slot-scope="scope">
                <span>{{ getLabels(scope.row.labelIds).join(',') }}</span>
              </template>
            </el-table-column>
            <el-table-column
              prop="remark"
              label="备注"
              align="left"
              show-overflow-tooltip
            />
            <!--操作栏-->
            <el-table-column
              v-if="doEdit||isDelete"
              label="操作"
              width="200"
              align="center"
            >
              <template
                v-if="showOperate(scope.row.datasetType)"
                slot-scope="scope"
              >
                <el-button
                  v-if="doEdit"
                  class="bs-el-button-default"
                  :disabled="scope.row.editable === 1 && !appCode"
                  @click="toEdit(scope.row.id, scope.row.datasetType, scope.row.name, scope.row.typeId)"
                >
                  编辑
                </el-button>
                <el-button
                  v-if="isDelete"
                  class="bs-el-button-default"
                  :loading="scope.row.loading"
                  :disabled="scope.row.editable === 1 && !appCode"
                  @click="delDataset(scope.row)"
                >
                  删除
                </el-button>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <div class="bs-pagination">
          <el-pagination
            class="bs-el-pagination"
            popper-class="bs-el-pagination"
            :current-page="current"
            :page-sizes="[10, 20, 50, 100]"
            :page-size="size"
            :total="totalCount"
            background
            prev-text="上一页"
            next-text="下一页"
            layout="total, prev, pager, next, sizes"
            @size-change="sizeChangeHandle"
            @current-change="currentChangeHandle"
          />
        </div>
      </div>
    </el-row>
    <!-- 新增-类型窗口 -->
    <DatasetTypeDialog
      ref="DatasetTypeDialog"
      :dataset-type-list="datasetTypeList"
      @openAddForm="openAddForm"
    />
    <checkDatasource
      ref="checkDatasource"
      :reason-list="reasonList"
    />
    <component
      :is="componentData.component"
      v-if="datasetType"
      ref="EditForm"
      :key="componentData.key"
      :config="componentData.config"
      :dataset-id="datasetId"
      :dataset-name="datasetName"
      :type-id="typeId"
      :is-edit="isEdit"
      :app-code="appCode"
      @back="back"
    >
      <template #output-field-table-column>
        <slot name="output-field-table-column" />
      </template>
    </component>
  </div>
</template>

<script>
import TypeTree from './TypeTree.vue'
import JsEditForm from './JsEditForm.vue'
import JsonEditForm from './JsonEditForm.vue'
import table from 'data-room-ui/js/utils/table.js'
import ScriptEditForm from './ScriptEditForm.vue'
import checkDatasource from 'data-room-ui/DataSourceManagement/src/checkDatasource.vue'
import CustomEditForm from './CustomEditForm.vue'
import { pageMixins } from 'data-room-ui/js/mixins/page'
import OriginalEditForm from './OriginalEditForm.vue'
import HttpEditForm from './HttpEditForm.vue'
import DatasetTypeDialog from './DatasetTypeDialog.vue'
import StoredProcedureEditForm from './StoredProcedureEditForm.vue'
import { datasetPage, datasetRemove, datasetCheck } from 'data-room-ui/js/utils/datasetConfigService'
import { getLabelList } from 'data-room-ui/js/utils/LabelConfigService'
export default {
  name: 'DataSetManagement',
  directives: {
    table // 注册自定义指令
  },
  components: {
    TypeTree,
    DatasetTypeDialog,
    OriginalEditForm,
    CustomEditForm,
    JsonEditForm,
    StoredProcedureEditForm,
    ScriptEditForm,
    JsEditForm,
    checkDatasource,
    HttpEditForm
  },
  mixins: [pageMixins],
  props: {
    multiple: {
      type: Boolean,
      default: false
    },
    isDialog: {
      type: Boolean,
      default: false
    },
    dsValue: {
      type: [Array, Object],
      default: null
    },
    appCode: {
      type: String,
      default: ''
    },
    isBorder: {
      type: Boolean,
      default: false
    },
    toAdd: {
      type: Boolean,
      default: true
    },
    doEdit: {
      type: Boolean,
      default: true
    },
    isDelete: {
      type: Boolean,
      default: true
    }

  },
  data () {
    return {
      reasonList: [],
      datasetType: null,
      isEdit: false,
      categoryData: [],
      tableData: [], // 表格数据
      queryForm: {
        name: '',
        datasetType: '',
        typeId: '', // 分类id
        labelIds: []
      }, // 查询条件
      // 数据集类型
      datasetTypeList: [],
      labelList: [],
      isPackUpTree: false,
      transition: 0.1,
      loadingText: '正在加载数据',
      dataListLoading: false,
      leftBox: null,
      rightBox: null,
      startX: null,
      event: null,
      endX: null,
      resize: null,
      datasetId: '', // 数据集Id，用于详情与编辑
      datasetName: '', // 数据集名称
      typeId: '', // 详情typeId
      curRow: null,
      multipleSelection: [],
      // 远程组件
      componentData: {
        component: null,
        config: null,
        key: new Date().getTime()
      }
    }
  },
  computed: {
    allType () {
      return this.datasetTypeList.map(item => item.datasetType).filter(item => item !== '')
    }
  },
  watch: {
    datasetType (value) {
      if (value === null) {
        this.datasetId = ''
        this.datasetName = ''
        this.isEdit = false
      }
    }
  },
  mounted () {
    this.init()
    if (/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent)) {
      // 当前浏览器为Safari浏览器
      // 执行相关操作
      document.addEventListener('mousemove', function (event) {
        if (event.buttons === 1) {
          event.preventDefault()
        }
      })
    }
  },
  methods: {
    getLabels (list) {
      const arr = []
      list?.forEach((item) => {
        arr.push(this.labelList.filter(x => x.id === item)[0]?.labelName)
      })
      return arr
    },
    toggleRowSelection () {
      this.$nextTick(() => {
        const dsIds = this.multipleSelection.map(ds => ds.id)
        this.$refs.userTable.clearSelection()
        this.tableData.forEach(item => {
          if (dsIds.includes(item.id)) {
            this.$refs.userTable.toggleRowSelection(item, true)
          }
        })
      })
    },
    // 全选
    selectAll (selection) {
      if (this.isDialog && this.multiple) {
        if (selection.length) {
          const dsIds = this.multipleSelection.map(ds => ds.id)
          selection.forEach(ds => {
            if (!dsIds.includes(ds.id)) {
              this.multipleSelection.push(ds)
            }
          })
        } else {
          this.tableData.forEach(row => {
            const dsIds = this.multipleSelection.map(ds => ds.id)
            const i = dsIds.indexOf(row.id)
            if (i > -1) this.multipleSelection.splice(i, 1)
          })
        }
      }
    },
    // 手动勾选
    selectDs (selection, row) {
      if (this.isDialog && this.multiple) {
        let dsIndex = null
        const ds = this.multipleSelection.find((ds, index) => {
          if (ds.id === row.id) {
            dsIndex = index
            return ds
          }
        })
        if (!ds) {
          this.multipleSelection.push(row)
        } else {
          this.multipleSelection.splice(dsIndex, 1)
        }
      }
    },
    // 获取选中数据集信息
    getSelectDs () {
      if (!this.isDialog) return
      if (this.multiple) {
        // 多选返回
        return this.multipleSelection
      } else {
        // 单选返回
        return this.curRow ? this.curRow : null
      }
    },
    // 单选数据集
    handleCurrentChange (currentRow) {
      this.curRow = currentRow
    },
    // 删除数据集
    delDataset (row) {
      row.loading = true
      datasetCheck(row.id).then((res) => {
        row.loading = false
        if (res.canDelete) {
          this.$confirm('确定删除当前数据集吗?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning',
            customClass: 'bs-el-message-box'
          }).then(() => {
            datasetRemove(row.id).then(res => {
              this.init(false)
              this.$message.success('删除成功')
            })
          }).catch(() => {
          })
        } else {
          this.reasonList = res.reasons
          this.$refs.checkDatasource.checkDatasourceVisible = true
        }
      })
    },
    // 详情
    toPreview (id, type, name, typeId) {
      this.datasetId = id
      this.datasetType = type
      this.datasetName = name
      this.typeId = typeId
      this.isEdit = false
    },
    toEdit (id, type, name, typeId) {
      this.datasetId = id
      this.datasetType = type
      this.componentData = this.getComponents(this.datasetTypeList.find(item => item?.datasetType === type)?.componentName) ?? ''
      this.datasetName = name
      this.typeId = typeId
      this.isEdit = true
    },
    // 回到管理端
    back () {
      this.datasetType = null
      this.isEdit = false
    },
    // 新增数据集-类型
    openAddForm (type, componentName) {
      this.datasetType = type
      this.componentData = this.getComponents(componentName)
      this.typeId = this.queryForm.typeId
      this.isEdit = true
    },
    showOperate (datasetType) {
      return this.getComponents(this.datasetTypeList.find(type => type.datasetType === datasetType)?.componentName)?.config?.showOperate ?? true
    },
    getComponents (componentName) {
      const components = Object.values(this.$options.components)
      let remoteComponentData = null
      if (window.BS_CONFIG?.customDatasetComponents && window.BS_CONFIG?.customDatasetComponents.length > 0) {
        // 获取远程组件
        remoteComponentData = window.BS_CONFIG?.customDatasetComponents.find(item => item.config.componentName === componentName)
      }
      return {
        component: components.find(component => component.name === componentName) || remoteComponentData?.vueFile,
        config: remoteComponentData?.config || null,
        key: new Date().getTime()
      }
    },
    // 初始化
    init (temp = true) {
      if (temp) {
        this.getTreeList()
      }
      if (this.isDialog) {
        if (this.multiple) {
          this.multipleSelection = this.dsValue ? this.dsValue : []
        } else {
          this.curRow = this.dsValue
        }
      }
      this.current = 1
      const list = [
        { name: '全部', datasetType: '' },
        { name: '原始数据集', datasetType: 'original', componentName: 'OriginalEditForm', description: '直接查询某个数据库表' },
        { name: '自助数据集', datasetType: 'custom', componentName: 'CustomEditForm', description: '自定义SQL语句查询' },
        { name: '存储过程数据集', datasetType: 'storedProcedure', componentName: 'StoredProcedureEditForm', description: '调用数据库存储过程查询' },
        { name: 'JSON数据集', datasetType: 'json', componentName: 'JsonEditForm', description: '直接定义静态数据' },
        { name: 'JS数据集', datasetType: 'js', componentName: 'JsEditForm', description: '编写JS代码进行动态模拟数据创建' },
        { name: 'HTTP数据集', datasetType: 'http', componentName: 'HttpEditForm', description: '接入第三方HTTP服务查询' },
        { name: '脚本数据集', datasetType: 'script', componentName: 'ScriptEditForm', description: '支持ES、Mongodb、国产化数据库、自定义Java代码查询' }

      ]
      if (window.BS_CONFIG?.datasetTypeList && window.BS_CONFIG?.datasetTypeList?.length !== 0) {
        this.datasetTypeList = [{ name: '全部', datasetType: '' }, ...list.filter(item => window.BS_CONFIG?.datasetTypeList.findIndex(x => x === item.datasetType) !== -1)]
      } else {
        this.datasetTypeList = [
          ...list
        ]
      }
      if (window.BS_CONFIG?.customDatasetComponents && window.BS_CONFIG?.customDatasetComponents.length > 0) {
        // 将获得到的远程数据集进行组装
        window.BS_CONFIG?.customDatasetComponents.forEach((item) => {
          this.datasetTypeList.push({ name: item.config.name, datasetType: item.config.datasetType, componentName: item.config.componentName })
        })
      }
      this.getDataList()
      // getLabelList().then(res => {
      //   this.labelList = res
      // })
    },
    // 新增数据集
    addDataset () {
      this.$refs.DatasetTypeDialog.dialogVisible = true
    },
    selectChange () {
      this.getDataList()
    },
    getTreeList () {
    },
    // 获取表格数据
    getDataList () {
      getLabelList().then(res => {
        this.labelList = res
      })
      this.dataListLoading = true
      datasetPage({
        current: this.current,
        size: this.size,
        moduleCode: this.appCode,
        ...this.queryForm,
        datasetType: this.queryForm.datasetType === '' ? [...this.allType] : [this.queryForm.datasetType]
      }).then((data) => {
        this.tableData = data.list
        this.tableData.forEach(r => {
          this.$set(r, 'loading', false)
        })
        if (this.isDialog) {
          if (this.multiple && this.multipleSelection.length) {
            this.toggleRowSelection()
          } else if (this.curRow.id) {
            const ds = this.tableData.find(item => item.id === this.curRow.id)
            if (ds) this.curRow = ds
          }
        }
        this.totalCount = data.totalCount
        this.dataListLoading = false
      }).catch(() => {
        this.dataListLoading = false
      })
    },
    expandedNodes (data) {
      if (data && data > 50) {
        this.transition = 0
      } else {
        this.transition = 0.1
      }
    },
    nodeClick (row, type) {
      this.current = 1
      if (type === 'group') {
        this.queryForm.typeId = row.id
        this.queryForm.datasetType = ''
      } else if (type === 'type') {
        this.queryForm.typeId = ''
        this.queryForm.datasetType = row
      }
      this.getDataList()
    },
    refreshData (node) {
      if (node && node.id === this.queryForm.typeId) {
        this.queryForm.typeId = ''
      }
      this.getDataList()
    },
    handleSearch () {
      this.current = 1
      this.queryForm.typeId = ''
      // 清除左侧机构树的选中状态
      this.$refs.datasetsTypeTree.ztreeObj.cancelSelectedNode()
      this.getDataList()
    },
    // 拖拽修改div宽度
    mousedown (e) {
      this.resize = document.getElementsByClassName('resize')[0]
      this.resize.left = document.getElementById('left-box').getBoundingClientRect().width
      this.leftBox = document.getElementsByClassName('left-box')[0]
      this.rightBox = document.getElementsByClassName('right-box')[0]
      this.startX = e.clientX
    },
    mousemove (e) {
      this.event = e
      if (this.resize) {
        const boxWidth = document.getElementById('box').getBoundingClientRect().width
        this.endX = e.clientX
        const offset = document.getElementById('box').getBoundingClientRect().left > 300 ? 0 : 25
        const moveLen = this.resize.left + (this.endX - this.startX) + offset
        this.leftBox.style.width = moveLen / boxWidth * 100 + '%'
        this.rightBox.style.width = ((1 - moveLen / boxWidth) * 100) + '%'
        this.isPackUpTree = false
        if (moveLen < 100 && this.endX - this.startX < 0) {
          this.isPackUpTree = true
          this.leftBox.style.width = '0%'
          this.rightBox.style.width = '100%'
        } else if (moveLen / boxWidth > 0.5) {
          this.leftBox.style.width = '50%'
          this.rightBox.style.width = '50%'
        }
      }
    },
    packUpTree () {
      this.$refs.datasetsTypeTree.expandedNodes()
      this.isPackUpTree = !this.isPackUpTree
      if (!this.isPackUpTree) {
        this.leftBox.style.width = '25%'
        this.rightBox.style.width = '75%'
      } else {
        this.leftBox.style.width = '0%'
        this.rightBox.style.width = '100%'
      }
    },
    mouseup () {
      if (this.resize) {
        this.resize = null
        if (this.endX < 350 && this.endX - this.startX > 0) {
          this.isPackUpTree = false
          this.leftBox.style.width = '25%'
          this.rightBox.style.width = '75%'
        }
      }
    },
    mousemoveOnBox (e) {
      this.mousemove(e)
    },
    mouseupOnBox () {
      this.resize = null
      if (this.endX < 350 && this.endX - this.startX > 0) {
        this.isPackUpTree = false
        this.leftBox.style.width = '25%'
        this.rightBox.style.width = '75%'
      }
      this.resize = null
    }
  }
}
</script>

<style lang="scss" scoped>
@import '../../assets/style/bsTheme.scss';
@import '../../assets/style/zTree/treePackUp.scss';

::v-deep .big-screen-router-view-wrap{
  padding-left: 16px !important;
}
::v-deep .bs-pagination {
  margin-top: 4px;
  padding-right: 16px;
  // padding: 0 !important;
  // right: 16px !important;
  // bottom: 16px !important;
  // position: absolute !important;
   .el-input__inner {
    width: 110px !important;
    border:none;
    background: var(--bs-el-background-1);
  }
}

::v-deep .bs-container .inner-container .el-form .filter-item {
   .el-input__inner {
    width: 200px;
  }
}

::v-deep .left-tab-box {
  span {
    color: var(--bs-el-text);
  }
}

::v-deep .left-tab-box ul li.tab-active {
  background-color: var(--bs-el-background-3);
}

::v-deep .left-tab-box ul li:hover {
  background-color: var(--bs-el-background-3);
}

::v-deep .el-dialog {
  .bs-container {
    // max-height: calc(90vh - 236px) !important;

    .el-table {
      height: calc(100vh - 390px);
    }

    .ztree {
      max-height: calc(90vh - 325px) !important;
    }

    .el-tabs__item.is-active {
      border-bottom: none !important;
    }

  }

}

::v-deep .ztreeNodeMenu {
  ul {
    background-color: var(--bs-background-1);
  }

  li:hover {
    background-color: var(--bs-el-background-3);

    span {
      color: var(--bs-el-color-primary);
    }
  }

  span {
    color: var(--bs-el-text);
  }

  .triangle {
    background-color: var(--bs-background-1) !important;
  }
}

.layout {
  width: 100%;
  height: 100%;
}

::v-deep .el-table__body-wrapper{
  max-height: unset !important;
}
</style>
