<template>
  <Modal class="th-database-manage" v-model="addTablesDlg" :title="type==='replace'?'替换数据':'添加数据'" width="500" :mask-closable="false">
    <div class="database">
      <div class="head">
        <div class="db-list">
          <Tree ref="databaseTree" :data="dbList" :load-data="loadTables" show-checkbox></Tree>
        </div>
      </div>
      <!-- 连接数据库对话框 -->
      <NewDatabaseModal ref="newDatabaseModal" :options="dbOptions" @on-ok="editDatabase"/>
    </div>
    <template #footer>
      <div style="float: left;">
        <Tooltip content="支持xlsx、csv、shp(zip格式)和geojson" max-width="200" placement="bottom">
          <Button type="primary" @click="showLocalFile">{{type==='replace'?'从本地文件替换':'从本地文件添加'}}</Button>
        </Tooltip>
        <Button type="primary" @click="showNewDatabaseModal" style="margin-left: 10px;">连接数据库</Button>
      </div>
      
      <Button color="#89B9F3" textColor="#ffffff" @click="hide">取消</Button>
      <Button type="primary" @click="ok">确定</Button>
    </template>
    <!-- 导入本地文件对话框 -->
    <input class="file-upload" type="file" accept=".zip, .xlsx, .json, .geojson, .csv" :multiple="type==='replace'?undefined: 'multiple'" style="display: none">
    <LoadingBar :show="globalLoading"/>
  </Modal>
</template>

<script>
import config from '../../constants/config'
import util from '../../libs/util'
import {tableCreate, catalogCreate, databaseLoad, databaseCreate, databaseUpdate, databaseDelete, getDatabaseList, getDatabaseTablesList} from '../../libs/request'
import LoadingBar from '../loading'
import NewDatabaseModal from './NewDatabaseModal.vue'
export default {
  props: {
    paths: {
      type: Array,
      default: () => []
    },
    type: {
      type: String,
      default: 'new'
    },
    node: {
      type: Object,
      default: () => {}
    }
  },
  components: {LoadingBar, NewDatabaseModal},
  methods: {
    show() {
      this.addTablesDlg = true
    },
    hide() {
      this.addTablesDlg = false
    },
    showNewDatabaseModal() {
      this.dbOptions = null
      this.dbEditType = 'add'
      this.$refs.newDatabaseModal.show()
    },
    async changeDbOptions(data) { // 获取数据库的参数选项
      let databaseId = data.databaseId
      let ownerId = config.USER
      this.dbEditType = 'patch'
      this.editDatabaseId = databaseId
      this.$refs.newDatabaseModal.show()
      let response = await databaseLoad(ownerId, databaseId)
      let {name, type, host, port, database} = response.data
      this.dbOptions = {name, type, host, port, database, username: '', password: ''}
    },
    editDatabase(options) { // 提交参数更新
      let ownerId = config.USER
      if (this.dbEditType === 'add') {
        databaseCreate(ownerId, options).then(res => {
          let {databaseId, type, owner, name, tags, metadata} = res.data
          this.databaseList.push({databaseId, type, owner, name, tags, metadata})
        })
      } else {
        databaseUpdate(ownerId, this.editDatabaseId, options).then(res => {
          let {databaseId, type, name, tags, metadata} = res.data
          let item = this.databaseList.find(d => d.databaseId === databaseId)
          Object.assign(item, {type, name, tags, metadata})
          this.$Notice.success({
            title: '修改成功',
            duration: 3
          })
        })
      }
    },
    deleteDatabase(data) { // 删除数据库连接
      let databaseId = data.databaseId
      this.$Modal.confirm({
        title: `确定要删除【${data.title}】数据库吗？`,
        content: '<p>该操作无法恢复，请谨慎操作！</p>',
        onOk: () => {
          let ownerId = config.USER
          databaseDelete(ownerId, databaseId).then(() => {
            let index = this.databaseList.findIndex(d => d.databaseId === databaseId)
            this.databaseList.splice(index, 1)
            this.$Notice.success({
              title: '删除成功',
              duration: 3
            })
          })
        }
      })
    },
    async loadTables(item, callback) {
      let ownerId = config.USER
      let {databaseId} = item
      try {
        let response = await getDatabaseTablesList(ownerId, databaseId)
        let tables = response.data
        let nodes = []
        tables.sort((t1, t2) => {
          if (t1.schema === t2.schema) {
            return t1.name > t2.name ? 1 : -1
          }
          return t1.schema > t2.schema ? 1 : -1
        })
        tables.forEach(tb => {
          let {schema, name, type} = tb
          let tableNode = {
            databaseId,
            title: name,
            type,
            schema,
            render: this.render
          }
          if (schema) {
            let schemaNode = nodes.find(node => node.title === schema)
            if (schemaNode) {
              schemaNode.children.push(tableNode)
            } else {
              nodes.push({
                databaseId,
                title: schema,
                type: 'schema',
                expand: false,
                render: this.render,
                children: [tableNode]
              })
            }
          } else {
            nodes.push(tableNode)
          }
        })
        callback(nodes)
      } catch (err) {
        this.$Modal.error({
          title: '发生错误',
          content: (err.response && err.response.data.message) || err.message
        })
        throw err
      }
    },
    ok() {
      let selectedNodes = this.$refs.databaseTree.getCheckedNodes()
      if (!selectedNodes.length) {
        this.$Message.warning('未选择数据表')
        return
      }
      let tables = []
      selectedNodes.forEach(node => {
        if (node.type !== 'BASE TABLE' && node.type !== 'VIEW') {
          return
        }
        let {type, databaseId, title, schema} = node
        tables.push({type, databaseId, schema, table: title})
      })
      if (this.type === 'replace') {
        if (tables.length > 1) {
          this.$Message.warning('只能选择一个数据表')
          return
        }
        this.replaceTable(tables[0])
      } else {
        this.registerTables(tables)
      }
      this.hide()
    },
    render(h, {data }) {
      let textColor = '#333333'
      let icon = 'shujuku'
      let buttons = null
      if (data.type === 'BASE TABLE') {
        icon = 'table_small'
        textColor = '#999999'
      } else if (data.type === 'VIEW') {
        icon = 'shitu'
        textColor = '#999999'
      } else if (data.type === 'schema') {
        icon = 'boom'
      } else {// 数据库操作按钮
        buttons = h('span', {
          class: ['actions'],
          style: {
            display: 'inline-block',
            float: 'right'
          }
        }, [
          h('i', {
            class: ['ivu-icon', 'iconfont', 'icon-refresh'],
            style: {
              cursor: 'pointer',
              marginRight: '5px',
              fontSize: '16px'
            },
            title: '刷新',
            onclick: () => { this.refreshTree(data) }
          }),
          h('i', {
            class: ['ivu-icon', 'iconfont', 'icon-edit-1'],
            style: {
              cursor: 'pointer',
              marginRight: '5px',
              fontSize: '16px'
            },
            title: '修改连接参数',
            onclick: () => { this.changeDbOptions(data) }
          }),
          h('i', {
            class: ['ivu-icon', 'iconfont', 'icon-delete'],
            style: {
              cursor: 'pointer',
              marginRight: '5px',
              fontSize: '16px'
            },
            title: '删除',
            onclick: () => { this.deleteDatabase(data) }
          })
        ])
      }
      return h('span', { // wrapper
        style: {
          display: 'inline-block',
          fontSize: '14px',
          width: '100%',
          color: textColor
        },
        class: ['hover-highlight']
      }, [
        h('span', [ // wrapper
          h('div', { // 图标
            src: './images/' + icon + '.png',
            class: ['icon', `th-icon-${icon}`],
            style: {
              width: '20px',
              height: '20px',
              display: 'inline-block',
              verticalAlign: 'middle',
              marginRight: '8px'
            }
          }),
          h('span', data.title) // 文字label
        ]),
        buttons // 按钮
      ])
    },
    getDbList(){
      let trees = []
      this.databaseList.forEach(db => {
        let {databaseId, type, owner, name} = db
        trees.push({
          title: name,
          owner,
          databaseId,
          type,
          loading: false,
          children: [],
          render: this.render.bind(this)
        })
      })
      this.dbList = trees
    },
    async refreshTree(item) {
      let {databaseId} = item
      let index = this.dbList.findIndex(db => db.databaseId === databaseId)
      if (!this.dbList[index].children.length) {
        return
      }
      this.dbList[index].loading = true
      this.dbList[index].children = []
      this.loadTables(item, nodes => {
        this.dbList[index].children = nodes
        this.dbList[index].loading = false
      })
    },
    showLocalFile() {
      this.uploadFile()
      this.hide()
    },
    registerTables(tables) { // 表注册
      this.globalLoading = true
      let ownerId = config.USER
      let parentId = this.paths.length ? this.paths[this.paths.length-1].catalogId : null
      tables.forEach(tb => {
        let name = tb.table
        let id = `${name}_${util.generateId()}`
        tableCreate(ownerId, id, {
          type: 'json',
          data: {name, source: tb}
        }).then(res => {
          catalogCreate(ownerId, util.generateId(), {
            name,
            parentId,
            type: res.data.type,
            resId: id
          }).then( res2 => {
            this.$emit('on-add-source', res2.data)
            this.globalLoading = false
          })
        })
      })
    },
    replaceTable(table) {
      this.globalLoading = true
      tableCreate(this.node.owner, this.node.resId, {
        type: 'json',
        data: {name, source: table}
      }).then(() => {
        this.globalLoading = false
        this.$Notice.success({
          title: '替换成功',
          duration: 3
        })
      }).catch(err => {
        this.$Modal.error({
          title: '发生错误',
          content: err.message
        })
        this.globalLoading = false
      })
    },
    uploadFile() { // 上传本地文件
      let input = document.querySelector('.th-database-manage .file-upload')
      let ownerId = config.USER
      input.onchange = e => {
        if (e.target.files.length === 0) {
          return
        }
        let parentId = this.paths.length ? this.paths[this.paths.length-1].catalogId : null
        this.globalLoading = true
        for(let i = 0;i < e.target.files.length;i++) {
          let file = e.target.files[i]
          let nameArray = file.name.split('.')
          let name = nameArray[0].replace(/\s+/g,"_")
          if (this.type === 'replace') { // 从文件替换
            tableCreate(this.node.owner, this.node.resId, {
              type: 'file',
              data: file
            }).then(() => {
              this.globalLoading = false
              this.$Notice.success({
                title: '替换成功',
                duration: 3
              })
            }).catch(err => {
              this.$Modal.error({
                title: '发生错误',
                content: err.message
              })
              this.globalLoading = false
            })
          } else { // 从文件新建
            let id = `${name}_${util.generateId()}`
            tableCreate(ownerId, id, {
              type: 'file',
              data: file
            }).then(res => {
              catalogCreate(ownerId, util.generateId(), {
                name: nameArray[0],
                parentId,
                type: res.data.type,
                resId: id
              }).then( res2 => {
                this.$emit('on-add-source', res2.data)
                this.globalLoading = false
              })
            })
          }
        }
      }
      input.click()
    }
  },
  mounted() {
    
  },
  data() {
    return {
      databaseList: [],
      addTablesDlg: false,
      dbList: [],
      dbEditType: 'add', // 'add' || 'patch'
      editDatabaseId: '', // 记录当前正在编辑的数据库id
      dbOptions: null,  // 数据库的连接参数
      globalLoading: false
    }
  },
  watch: {
    addTablesDlg() {
      if (!this.addTablesDlg) {
        return
      }
      if (this.databaseList.length) {
        this.getDbList()
      } else {
        let ownerId = config.USER
        getDatabaseList(ownerId).then(res => {
          this.databaseList = res.data
          this.getDbList()
        })
      }
    },
    databaseList: {
      deep: true,
      handler() {
        this.getDbList()
      }
    }
  }
}  
</script>