<template>
  <div class="app-container">

    <div class="filter-container">
      <el-select
        v-model="listQuery.sysOrigin"
        :placeholder="$t('pages.sysConfigSetting.filter.system')"
        style="width:120px;"
        class="filter-item"
        @change="handleSearch"
      >
        <el-option
          v-for="item in permissionsSysOriginPlatforms"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        >
          <span style="float: left;"> <sys-origin-icon :icon="item.value" :desc="item.value" /></span>
          <span style="float: left;margin-left:10px">{{ item.label }}</span>
        </el-option>
      </el-select>
      <el-cascader
        v-model="listQuery.groupList"
        clearable
        :placeholder="$t('pages.sysConfigSetting.filter.group')"
        :options="translatedEnumConfigGroupNames"
        :props="cascaderProps"
        class="filter-item"
        @change="handleSearch"
      />
      <el-select
        v-model="listQuery.inoperable"
        :placeholder="$t('pages.sysConfigSetting.filter.status')"
        clearable
        style="width: 120px"
        class="filter-item"
        @change="handleSearch"
      >
        <el-option
          v-for="item in enumConfigOperates"
          :key="item.value"
          :label="getOperateName(item.value)"
          :value="item.value"
        />
      </el-select>

      <el-select
        v-model="listQuery.returnApp"
        :placeholder="$t('pages.sysConfigSetting.filter.returnApp')"
        clearable
        style="width: 120px"
        class="filter-item"
        @change="handleSearch"
      >
        <el-option :label="$t('pages.sysConfigSetting.word.yes')" :value="true" />
        <el-option :label="$t('pages.sysConfigSetting.word.no')" :value="false" />
      </el-select>
      <el-input
        v-model.trim="listQuery.name"
        :placeholder="$t('pages.sysConfigSetting.filter.key')"
        style="width: 200px;"
        class="filter-item"
      />
      <el-input
        v-model.trim="listQuery.val"
        :placeholder="$t('pages.sysConfigSetting.filter.value')"
        style="width: 200px;"
        class="filter-item"
      />
      <el-input
        v-model.trim="listQuery.description"
        :placeholder="$t('pages.sysConfigSetting.filter.description')"
        style="width: 200px;"
        class="filter-item"
      />

      <el-button
        class="filter-item"
        type="primary"
        icon="el-icon-search"
        @click="handleSearch"
      >
        {{ $t('pages.sysConfigSetting.action.search') }}
      </el-button>
      <el-button
        class="filter-item"
        type="primary"
        icon="el-icon-edit"
        @click="handleCreate"
      >
        {{ $t('pages.sysConfigSetting.action.add') }}
      </el-button>
    </div>
    <el-table
      v-loading="listLoading"
      :data="list"
      :element-loading-text="$t('pages.sysConfigSetting.loading')"
      fit
      highlight-current-row
      @cell-mouse-enter="handleMouseEnter"
    >
      <el-table-column prop="sysOrigin" :label="$t('pages.sysConfigSetting.table.system')" align="center" min-width="80">
        <template slot-scope="scope">
          <sys-origin-icon :icon="scope.row.sysOrigin" :desc="scope.row.sysOrigin" />
        </template>
      </el-table-column>
      <el-table-column prop="title" :label="$t('pages.sysConfigSetting.table.title')" align="center" />
      <el-table-column prop="val" :label="$t('pages.sysConfigSetting.table.value')" align="center" />
      <el-table-column prop="groupName" :label="$t('pages.sysConfigSetting.table.group')" align="center">
        <template slot-scope="scope">
          <span>{{ getGroupNames(scope.row.groupList) }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="dataType" :label="$t('pages.sysConfigSetting.table.dataType')" align="center" width="110" />
      <el-table-column prop="sort" :label="$t('pages.sysConfigSetting.table.sort')" align="center" width="70" />
      <el-table-column prop="inoperable" :label="$t('pages.sysConfigSetting.table.status')" align="center" width="120">
        <template slot-scope="scope">
          <el-tag v-if="scope.row.inoperable === false" type="success">{{ getOperateName(false) }}</el-tag>
          <el-tag v-if="scope.row.inoperable === true" type="danger">{{ getOperateName(true) }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="returnApp" :label="$t('pages.sysConfigSetting.table.returnApp')" align="center" width="100">
        <template slot-scope="scope">
          <span v-if="scope.row.returnApp === true">{{ $t('pages.sysConfigSetting.word.yes') }}</span>
          <span v-if="scope.row.returnApp === false">{{ $t('pages.sysConfigSetting.word.no') }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="description" :label="$t('pages.sysConfigSetting.table.description')" align="center" width="80">
        <template slot-scope="scope">
          <el-tooltip class="item" effect="dark" placement="top-start">
            <div slot="content" class="tooltip-content">{{ scope.row.description }}</div>
            <div class="el-icon-info cursor-pointer" />
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column prop="name" :label="$t('pages.sysConfigSetting.table.key')" align="center" width="80">
        <template slot-scope="scope">
          <div @click="copyTextContent(scope.row.name)">
            <el-tooltip class="item" effect="dark" placement="top-start">
              <div slot="content" class="tooltip-content">{{ scope.row.name }}</div>
              <div class="el-icon-info cursor-pointer" />
            </el-tooltip>
          </div>
        </template>
      </el-table-column>
      <el-table-column prop="createTime" :label="$t('pages.sysConfigSetting.table.operationTime')" align="center" width="130">
        <template slot-scope="scope">
          <el-tooltip class="item" effect="dark" placement="top-start">
            <div slot="content" class="tooltip-content">
              <div>{{ $t('pages.sysConfigSetting.table.createdAt') }}：{{ scope.row.createTime | dateFormat }}</div>
              <div>{{ $t('pages.sysConfigSetting.table.updatedAt') }}：{{ scope.row.updateTime | dateFormat }}</div>
            </div>
            <div class="el-icon-info cursor-pointer" />
          </el-tooltip>
        </template>
      </el-table-column>
      <el-table-column fixed="right" :label="$t('pages.sysConfigSetting.table.actions')" align="center" width="130">
        <template slot-scope="scope">
          <el-button type="text" @click.native="handleUpdate(scope.row)">{{ $t('pages.sysConfigSetting.action.edit') }}</el-button>
          <el-button type="text" @click.native="handlDel(scope.row)">{{ $t('pages.sysConfigSetting.action.delete') }}</el-button>
        </template>
      </el-table-column>
    </el-table>

    <pagination
      v-show="total > 0"
      :total="total"
      :page.sync="listQuery.cursor"
      :limit.sync="listQuery.limit"
      @pagination="renderData"
    />

    <el-dialog
      :title="formTitle"
      :visible.sync="formVisible"
      :modal-append-to-body="true"
      :append-to-body="true"
      :before-close="handleClose"
      :close-on-click-modal="false"
      width="550px"
    >
      <div v-loading="submitLoading">
        <el-form
          ref="form"
          style="width: 400px; margin-left:50px;"
          :model="form"
          :rules="rules"
          label-position="right"
          label-width="80px"
        >
          <el-form-item v-if="isHideProperty" :label="$t('pages.sysConfigSetting.form.key')" prop="name">
            <el-input v-model.trim="form.name" type="text" />
          </el-form-item>
          <el-form-item :label="$t('pages.sysConfigSetting.form.dataType')" prop="dataType">
            <el-select
              v-model="form.dataType"
              :placeholder="$t('pages.sysConfigSetting.placeholder.dataType')"
              style="width:100%;"
              @change="handleDataTypeChange"
            >
              <el-option
                v-for="item in enumConfigDataTypes"
                :key="item.value"
                :value="item.value"
                :label="item.name"
              />
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('pages.sysConfigSetting.form.value')" prop="val">
            <el-input v-model.trim="form.val" type="text" />
          </el-form-item>
          <el-form-item :label="$t('pages.sysConfigSetting.form.title')" prop="title">
            <el-input v-model.trim="form.title" type="text" />
          </el-form-item>
          <el-form-item :label="$t('pages.sysConfigSetting.form.description')" prop="description">
            <el-input v-model.trim="form.description" type="text" />
          </el-form-item>
          <el-form-item :label="$t('pages.sysConfigSetting.form.group')" prop="groupList">
            <el-cascader v-model="form.groupList" :options="translatedEnumConfigGroupNames" :props="cascaderProps" style="width:100%;" />
          </el-form-item>
          <el-form-item :label="$t('pages.sysConfigSetting.form.operationStatus')" prop="inoperable">
            <el-select
              v-model="form.inoperable"
              :placeholder="$t('pages.sysConfigSetting.placeholder.operationStatus')"
              class="filter-item"
              style="width:100%;"
            >
              <el-option
                v-for="item in enumConfigOperates"
                :key="item.value"
                :value="item.value"
                :label="getOperateName(item.value)"
              />
            </el-select>
          </el-form-item>
          <el-form-item :label="$t('pages.sysConfigSetting.form.returnApp')" prop="returnApp">
            <el-select
              v-model="form.returnApp"
              :placeholder="$t('pages.sysConfigSetting.placeholder.returnApp')"
              clearable
              style="width:100%;"
              class="filter-item"
            >
              <el-option :label="$t('pages.sysConfigSetting.word.yes')" :value="true" />
              <el-option :label="$t('pages.sysConfigSetting.word.no')" :value="false" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="submitForm()">{{ $t('pages.sysConfigSetting.action.save') }}</el-button>
            <el-button @click="handleClose()">{{ $t('pages.sysConfigSetting.action.cancel') }}</el-button>
          </el-form-item>
        </el-form>
      </div>
    </el-dialog>

  </div>
</template>

<script>
import { copyText, deepClone } from '@/utils'
import { getConfigInfo, addConfigInfo, updateConfigInfo, delConfig } from '@/api/table'
import { enumConfigGroupNames, enumConfigOperates, enumConfigDataTypes, enumConfigDataTypesExpression } from '@/constant/type'
import Pagination from '@/components/Pagination'
import { mapGetters } from 'vuex'

function getFormData() {
  return {
    id: '',
    name: '',
    val: '',
    groupName: '',
    groupList: [],
    title: '',
    description: '',
    dataType: 'int',
    sort: '0',
    inoperable: false,
    returnApp: true,
    sysOrigin: 'HALAR'
  }
}

export default {
  name: 'CnfEnumsManager',
  components: { Pagination },
  data() {
    const validateRequired = (rule, value, callback) => {
      if (value === undefined || value === null || value === '' || (Array.isArray(value) && value.length === 0)) {
        callback(new Error(this.tPage('validation.requiredField')))
        return
      }
      callback()
    }
    var validateValue = (rule, value, callback) => {
      if (value === undefined || value === null || value === '') {
        callback(new Error(this.tPage('validation.requiredField')))
        return
      }
      const expression = enumConfigDataTypesExpression[this.form.dataType]
      if (expression.rex && !expression.rex.test(value)) {
        callback(new Error(this.getDataTypeValidationMessage(this.form.dataType, expression.msg)))
        return
      }
      callback()
    }
    return {
      cascaderProps: {
        value: 'value',
        label: 'name'
      },
      formTitle: '',
      thisRow: {},
      list: [],
      total: 0,
      people: 0,
      listQuery: {
        cursor: 1,
        limit: 20,
        name: '',
        val: '',
        description: '',
        groupName: '',
        groupList: [],
        sysOrigin: 'HALAR',
        inoperable: '',
        returnApp: ''
      },
      formVisible: false,
      enumConfigGroupNameMap: {},
      enumConfigGroupNames,
      enumConfigOperates,
      enumConfigDataTypes,
      form: getFormData(),
      submitLoading: false,
      rules: {
        name: [
          { required: true, validator: validateRequired, trigger: 'blur' }
        ],
        val: [
          { required: true, validator: validateValue, trigger: 'blur' }
        ],
        title: [
          { required: true, validator: validateRequired, trigger: 'blur' }
        ],
        groupList: [
          { required: true, validator: validateRequired, trigger: 'blur' }
        ],
        inoperable: [
          { required: true, validator: validateRequired, trigger: 'blur' }
        ],
        returnApp: [
          { required: true, validator: validateRequired, trigger: 'blur' }
        ],
        description: [
          { required: true, validator: validateRequired, trigger: 'blur' }
        ]
      },
      listLoading: true
    }
  },
  computed: {
    ...mapGetters(['permissionsSysOriginPlatforms']),
    isHideProperty() {
      return !this.form.id || this.form.id <= 0
    },
    translatedEnumConfigGroupNames() {
      return this.translateConfigGroupOptions(this.enumConfigGroupNames)
    }
  },
  created() {
    const that = this
    const querySystem = this.permissionsSysOriginPlatforms[0]
    if (!querySystem) {
      return
    }
    that.listQuery.sysOrigin = querySystem.value
    that.renderData()
    that.enumConfigGroupNamesToMap()
  },
  methods: {
    renderData(isClean) {
      const that = this
      if (isClean === true) {
        that.listQuery.cursor = 1
        that.list = []
      }
      that.listLoading = true
      that.listQuery.groupName = that.listQuery.groupList.join(',')
      getConfigInfo(that.listQuery).then(res => {
        const { body } = res
        that.total = body.total || 0
        that.list = that.convertResultList(body.records)
        that.listLoading = false
      })
    },
    convertResultList(list) {
      if (list) {
        list.forEach(item => {
          if (item.groupName) {
            item.groupList = item.groupName.split(',')
          }
        })
        return list
      }
      return []
    },
    enumConfigGroupNamesToMap(list, isChildren) {
      const that = this
      if (!list && !isChildren) {
        list = that.enumConfigGroupNames
      }
      list.forEach(item => {
        that.enumConfigGroupNameMap[item.value] = that.getConfigGroupName(item.value, item.name)
        if (item.children && item.children.length > 0) {
          that.enumConfigGroupNamesToMap(item.children, true)
        }
      })
    },
    getGroupNames(keys) {
      const that = this
      return keys ? keys.map(item => that.getConfigGroupName(item, that.enumConfigGroupNameMap[item] || item)).join('/') : ''
    },
    tPage(key, values) {
      return this.$t(`pages.sysConfigSetting.${key}`, values)
    },
    translateConfigGroupOptions(list) {
      return list.map(item => ({
        ...item,
        name: this.getConfigGroupName(item.value, item.name),
        children: item.children ? this.translateConfigGroupOptions(item.children) : item.children
      }))
    },
    getConfigGroupName(value, fallback) {
      const key = `pages.sysConfigSetting.configGroup.${value}`
      const translated = this.$t(key)
      return translated === key ? fallback : translated
    },
    getOperateName(value) {
      return value ? this.tPage('operate.inoperable') : this.tPage('operate.operable')
    },
    getDataTypeValidationMessage(type, fallback) {
      const key = `pages.sysConfigSetting.dataTypeValidation.${type}`
      const translated = this.$t(key)
      return translated === key ? fallback : translated
    },
    handleSearch() {
      this.renderData(true)
    },
    handleCreate() {
      this.formVisible = true
      this.formTitle = this.tPage('dialog.create')
      this.form = getFormData()
    },
    handleUpdate(row) {
      this.formVisible = true
      this.formTitle = this.tPage('dialog.edit')
      this.form = Object.assign({}, row)
    },
    submitForm() {
      const that = this
      that.$refs.form.validate(valid => {
        if (valid) {
          that.submitLoading = true
          const submitForm = deepClone(that.form)
          submitForm.sysOrigin = that.listQuery.sysOrigin
          submitForm.groupName = submitForm.groupList.join(',')
          if (!that.form.id) {
            addConfigInfo(submitForm).then(res => {
              that.submitLoading = false
              that.formVisible = false
              that.form = getFormData()
              that.renderData()
            }).catch(er => {
              that.submitLoading = false
              console.error(er)
            })
            return
          }
          updateConfigInfo(submitForm).then(res => {
            that.submitLoading = false
            that.formVisible = false
            that.form = getFormData()
            that.renderData()
          }).catch(er => {
            that.submitLoading = false
            console.error(er)
          })
        } else {
          console.error('error submit!!')
          return false
        }
      })
    },
    handleClose() {
      this.formVisible = false
      this.$refs.form.resetFields()
      this.$refs.form.clearValidate()
    },
    handlDel(item) {
      const that = this
      that.searchLoading = that.listLoading = false

      this.$confirm(this.tPage('confirm.deleteMessage'), this.tPage('confirm.title'), {
        confirmButtonText: this.tPage('confirm.confirm'),
        cancelButtonText: this.tPage('confirm.cancel')
      }).then(() => {
        delConfig(item.id).then(res => {
          that.renderData()
          that.$opsMessage.success()
        }).catch(er => {
          that.$opsMessage.success()
        })
      }).catch(() => {})
    },
    renderDataSuccess() {
      this.$message({
        message: this.tPage('message.success'),
        type: 'success'
      })
      this.renderData()
    },
    handleMouseEnter(row) {
      this.thisRow = row
    },
    copyTextContent(text) {
      const that = this
      copyText(text).then(() => {
        that.$message({
          message: that.tPage('message.copySuccess'),
          type: 'success'
        })
      }).catch(() => {
        that.$message({
          message: that.tPage('message.copyFail'),
          type: 'error'
        })
      })
    },
    handleDataTypeChange(value) {
      this.form.val = ''
    },
    handlerChangeSysOrigin(value) {
      if (this.golbalSetting === value) {
        this.listQuery.groupList = []
      }
      this.handleSearch()
    }
  }
}
</script>
<style scoped lang="scss">
.tooltip-content {
  max-width: 300px;
}
</style>
