<template>
  <section class="AiLibTable">
    <ai-search-bar>
      <template v-if="$scopedSlots.left" #left>
        <slot name="left"/>
      </template>
      <template #right>
        <slot v-if="$scopedSlots.right" name="right"/>
        <el-input v-else placeholder="搜索应用名称" size="small" v-model="search[searchKey]" @change="page.current=1,getTableData()" clearable/>
      </template>
    </ai-search-bar>
    <ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :colConfigs="columns"
              :size.sync="page.size" @getList="getTableData" tableSize="mini" :dict="dict" v-bind="$attrs">
      <el-table-column slot="chb" width="100px" v-if="!disabled">
        <template #header>
          <el-checkbox v-if="multiple" v-model="selectAll" @change="handleCheckAll"/>
        </template>
        <template slot-scope="{row}">
          <el-checkbox v-model="row.checked" @change="handleCheck(row)"/>
        </template>
      </el-table-column>
    </ai-table>
  </section>
</template>

<script>
export default {
  name: "AiLibTable",
  model: {
    prop: "value",
    event: "change"
  },
  props: {
    value: {default: null},
    instance: Function,
    dict: Object,
    permissions: Function,
    action: {default: "/node/wechatapps/list"},
    colConfigs: {
      default: () => [
        {prop: 'label', label: "应用名称"},
        {prop: 'project', label: "项目/框架"},
        {prop: 'category', label: "分类", dict: "appsCategory"},
        {prop: 'name', label: "模块名"},
      ]
    },
    nodeKey: {default: "id"},
    searchKey: {default: "name"},
    multiple: Boolean,
    disabled: Boolean,
    meta: {default: () => []},
    choose: {default: null}
  },
  data() {
    return {
      page: {total: 0, current: 1, size: 10},
      search: {},
      tableData: [],
      selectAll: false
    }
  },
  computed: {
    columns() {
      return [
        {slot: "chb"}, ...this.colConfigs
      ]
    },
    selected() {
      const {choose, value, nodeKey} = this,
          list = [choose].flat().map(e => e?.[nodeKey])
      return [...new Set([value, list].flat())].filter(Boolean) || []
    }
  },
  watch: {
    action(v) {
      v && (this.page.current = 1, this.getTableData())
    },
  },
  methods: {
    getTableData() {
      const {page, search, action, meta, searchKey, dict} = this
      if (meta.length > 0) {
        const reg = new RegExp(search[searchKey])
        this.handleTableData(meta.filter(e => reg.test(e.label) || reg.test(e.name) || reg.test(dict.getLabel('appsCategory', e.category))))
      } else this.instance?.post(action, null, {
        params: {...page, ...search}
      }).then(res => {
        if (res?.data) {
          this.page.total = res.data.total
          this.handleTableData(res.data.records || res.data || [])
        }
      })
    },
    handleTableData(list) {
      const {nodeKey} = this
      list.map(e => {
        e.category = e.libPath.replace(/^\/[^\/]+\/([^\/]+)\/.+/, '$1')
        if (/\/project\//.test(e.libPath)) {
          e.project = e.libPath.replace(/.*project\/([^\/]+)\/.+/, '$1')
        } else if (/\/core\//.test(e.libPath)) {
          e.project = "core"
        } else e.project = "standard"
      })
      this.tableData = list.map(e => ({...e, checked: this.selected.includes(e[nodeKey])}))
    },
    handleCheck(row) {
      const {nodeKey} = this
      if (this.multiple) {
        let selected = this.$copy(this.selected),
            choose = this.$copy(this.choose)
        if (row.checked) {
          selected.push(row[nodeKey])
          choose.push(row)
        } else {
          selected = selected.filter(e => e != row[nodeKey])
          choose = choose.filter(e => e[nodeKey] != row[nodeKey])
        }
        this.$emit("change", selected)
        this.$emit("update:choose", choose)
      } else {
        this.tableData.map(e => e.checked = e[nodeKey] == row.id && row.checked)
        this.$emit("change", row.checked ? row[nodeKey] : '')
        this.$emit("update:choose", row.checked ? row : null)
      }
    },
    handleCheckAll(v) {
      const {nodeKey} = this
      let selected = this.tableData.map(e => {
        e.checked = v
        return e
      }).filter(e => e.checked) || []
      this.$emit("change", selected?.map(e => e[nodeKey]))
      this.$emit("update:choose", selected)
    }
  },
  created() {
    this.dict.load('appsCategory')
    this.$set(this.search, this.searchKey, "")
    this.getTableData()
  }
}
</script>

<style lang="scss" scoped>
.AiLibTable {
}
</style>
