<template>
  <div>
    <el-row>
      <el-col :span="14" class="p-r">
        <div class="al-c">
          <h3 class="fw-500">配置详情 - {{ type === 'normal' ? '普通配置' : '私有配置' }}</h3>
        </div>
        <el-form label-width="120px" :model="settingsForm">
          <template v-for="(item, index) in settingsForm.settings">
            <el-form-item
              :key="index"
              :label="`${item.title}`"
              :prop="`settings[${index}].value`"
              :rules="{required: true, message: '配置内容不能为空', trigger: 'blur'}"
            >
              <div v-if="item.type === 'bool'">
                <el-switch v-model="item.value" :active-value="1" :inactive-value="0"/>
              </div>
              <div v-else-if="item.type === 'string'">
                <el-input v-model="item.value" style="width: 70%"/>
                <el-button type="primary" @click="openEditor(index)">json</el-button>
              </div>
              <div v-else>
                <el-input v-model="item.value" style="width: 70%"/>
              </div>
            </el-form-item>
          </template>
          <div v-if="settingsForm.settings.length === 0" class="al-c mgt-20 mgb-20">暂无配置项</div>
          <el-form-item>
            <el-button v-if="permissionEdit" type="warning" @click="save">保存</el-button>
            <el-button v-if="permissionPublish" type="primary" @click="publish">发布</el-button>
          </el-form-item>
        </el-form>

        <div class="divider"/>
      </el-col>
      <el-col :span="10">
        <div class="al-c">
          <h3 class="fw-500">配置项设置</h3>
        </div>
        <div class="al-c mgt-20">
          <el-select
            v-model="selectedSettings"
            multiple
            placeholder="请选择配置项"
            class="mgb-20"
            style="width: 300px"
            value-key="key"
            @remove-tag="delSetting"
          >
            <el-option
              v-for="item in settingsList"
              :key="item.key"
              :label="`${item.value.title}(${item.key})`"
              :value="item"
              @click.native="clickOp(item)"
            />
          </el-select>
          <div class="btn-group">
            <el-button type="success" size="small" @click="addSetting">添加新的配置项</el-button>
            <el-button type="danger" size="small" @click="clearSettings">清空</el-button>
          </div>
        </div>
      </el-col>
    </el-row>

    <!-- modal - editor -->
    <el-dialog title="编辑 JSON" :visible.sync="modalEditorVisible">
      <vue-json-editor
        v-model="json"
        lang="en"
        mode="code"
        :modes="['code', 'tree']"
        :show-btns="false"
      />

      <div slot="footer">
        <el-button @click="closeEditorModal">取 消</el-button>
        <el-button type="primary" @click="saveJson">确 定</el-button>
      </div>
    </el-dialog>

    <!-- modal - newSetting -->
    <el-dialog
      title="编辑配置项"
      :visible.sync="modalNewSettingVisible"
      :before-close="closeNewSettingModal"
    >
      <el-form
        ref="newSettingForm"
        :model="newSettingForm"
        :rules="newSettingRules"
        label-width="80px"
      >
        <el-form-item label="名称" prop="value.title">
          <el-input v-model="newSettingForm.value.title"/>
        </el-form-item>
        <el-form-item label="key" prop="key">
          <el-input v-model="newSettingForm.key"/>
          <span class="ipt-tip">该值写入redis并传入客户端，请谨慎填写</span>
        </el-form-item>
        <el-form-item label="值类型" prop="value.type">
          <el-select v-model="newSettingForm.value.type" placeholder="请选择值类型" style="width: 100%">
            <el-option label="布尔值" value="bool"/>
            <el-option label="数值" value="num"/>
            <el-option label="字符串" value="string"/>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer">
        <el-button @click="closeNewSettingModal">取 消</el-button>
        <el-button type="primary" @click="saveNewSetting">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import request from '@/utils/request'
import vueJsonEditor from 'vue-json-editor'
import { Promise } from 'q'
import { mapGetters } from 'vuex'

export default {
  name: 'SettingPanel',
  components: {
    vueJsonEditor
  },
  props: {
    type: {
      type: String,
      default: 'normal'
    }
  },

  data() {
    return {
      _id: '',
      gameInfo: {},
      permissionEdit: false,
      permissionPublish: false,
      // left
      settingsForm: {
        settings: []
      },
      selectedSettings: [],
      settingKeys: [],
      // right
      settingsList: [],
      // modal - editor
      modalEditorVisible: false,
      json: {},
      curIndex: 0,
      // modal - newSetting
      modalNewSettingVisible: false,
      newSettingForm: {
        _id: '',
        key: '',
        value: {
          title: '',
          type: ''
        }
      },
      newSettingRules: {
        key: [{ required: true, message: '请输入 key 值', trigger: 'blur' }],
        'value.title': [
          { required: true, message: '请填写名称', trigger: 'blur' }
        ],
        'value.type': [
          { required: true, message: '请选择值类型', trigger: 'blur' }
        ]
      }
    }
  },
  computed: {
    ...mapGetters(['userInfo'])
  },
  mounted() {
    this._id = this.$route.params._id
    this.permissionEdit =
      this.userInfo.permissions.includes(`${this._id}-edit`) ||
      this.userInfo.permissions.includes(`${this._id}-publish`)
    this.permissionPublish = this.userInfo.permissions.includes(
      `${this._id}-publish`
    )
    this.getGameInfo(this.getGameSettings)
    this.getSettingsList()
  },
  methods: {
    // left
    getGameInfo(cb) {
      request({
        url: '/api/games/list',
        method: 'get',
        params: {
          _id: this._id
        }
      }).then(res => {
        const { data } = res
        if (data.errcode !== 0) {
          this.$notify.error({
            title: '错误',
            message: data.errmsg
          })
          return
        }
        this.gameInfo = data.gameList[0]
        this.$route.meta.title = this.gameInfo.game_name
        if (cb && cb instanceof Function) cb()
      })
    },
    getGameSettings() {
      request({
        url: '/api/games/settings/one_game_cfg',
        method: 'get',
        params: {
          type: this.type === 'normal' ? 0 : 1,
          id: this.gameInfo.game_id,
          pid: this.gameInfo.platform
        }
      }).then(res => {
        const { data } = res
        if (data.errcode !== 0) {
          this.$notify.error({
            title: '错误',
            message: data.errmsg
          })
          return
        }
        this.settingsForm.settings = data.records
        this.selectedSettings = data.records
      })
    },
    openEditor(index) {
      this.curIndex = index
      try {
        this.json = JSON.parse(this.settingsForm.settings[index].value)
        this.modalEditorVisible = true
      } catch (err) {
        this.$notify.error('非 json 格式无法解析')
        this.json = {}
        this.modalEditorVisible = true
      }
    },
    save() {
      this.$confirm('是否保存游戏配置？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.saveSettings()
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消保存!'
          })
        })
    },
    publish() {
      this.$confirm('是否确认正式发布游戏配置?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async() => {
          // 保存
          this.saveSettings()
            .then(() => {
              request({
                url: '/api/games/settings/publish_cfg',
                method: 'post',
                data: {
                  cfgs: this.settingsForm.settings,
                  gameId: this.gameInfo.game_id,
                  platform: this.gameInfo.platform,
                  type: this.type === 'normal' ? 0 : 1
                }
              }).then(res => {
                const { data } = res
                if (data.errcode !== 0) {
                  this.$notify.error({
                    title: '错误',
                    message: data.errmsg
                  })
                  return
                }
                this.$message.success('配置发布成功！')
              })
            })
            .catch(err => {
              this.$message.error(err)
            })
          // 发布
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消发布操作！'
          })
        })
    },
    saveSettings() {
      return new Promise((resolve, reject) => {
        request({
          url: '/api/games/settings/save_cfg',
          method: 'post',
          data: {
            cfgs: this.settingsForm.settings,
            gameId: this.gameInfo.game_id,
            platform: this.gameInfo.platform,
            type: this.type === 'normal' ? 0 : 1
          }
        }).then(res => {
          const { data } = res
          if (data.errcode !== 0) {
            this.$notify.error({
              title: '错误',
              message: data.errmsg
            })
            reject(data.errmsg)
            return
          }
          this.$message.success('配置保存成功！')
          resolve()
        })
      })
    },
    // right
    getSettingsList() {
      request({
        url: '/api/games/settings/sys_dics?type=game_cfg',
        method: 'get'
      }).then(res => {
        const { data } = res
        if (data.errcode !== 0) {
          this.$notify.error({
            title: '错误',
            message: data.errmsg
          })
          return
        }
        this.settingsList = data.records
      })
    },
    clearSettings() {
      this.selectedSettings = []
      this.settingKeys = []
      this.settingsForm.settings = []
    },
    addSetting() {
      this.openNewSettingModal()
    },
    delSetting(val) {
      this.clickOp(val)
    },
    clickOp(val) {
      const key = val.key

      if (this.settingKeys.includes(key)) {
        // 删除
        let index1 = 0
        const index2 = this.settingKeys.indexOf(key)
        for (let i = 0; i < this.settingsForm.settings.length; i++) {
          if (this.settingsForm.settings[i].key === key) index1 = i
          break
        }
        this.settingsForm.settings.splice(index1, 1)
        this.settingKeys.splice(index2, 1)
      } else {
        // 添加
        this.settingsForm.settings.push({
          key: val.key,
          value: '',
          title: val.value.title,
          type: val.value.type
        })
        this.settingKeys.push(key)
      }
    },
    // modal - editor
    saveJson() {
      this.settingsForm.settings[this.curIndex].value = JSON.stringify(
        this.json
      )
      this.closeEditorModal()
    },
    closeEditorModal() {
      this.modalEditorVisible = false
    },
    // modal - newSetting
    openNewSettingModal() {
      this.newSettingForm = {
        _id: '',
        key: '',
        value: {
          title: '',
          type: 'bool'
        }
      }
      this.modalNewSettingVisible = true
    },
    closeNewSettingModal() {
      this.$refs['newSettingForm'].clearValidate()
      this.modalNewSettingVisible = false
    },
    saveNewSetting() {
      this.$refs['newSettingForm'].validate(valid => {
        if (valid) {
          request({
            url: '/api/games/settings/save_sys_dic',
            method: 'post',
            data: {
              record: {
                id: this.newSettingForm._id ? this.newSettingForm._id : '',
                key: this.newSettingForm.key,
                title: this.newSettingForm.value.title,
                type: this.newSettingForm.value.type
              }
            }
          }).then(res => {
            const { data } = res
            if (data.errcode !== 0) {
              this.$message.error(data.errmsg)
              return
            }
            this.modalNewSettingVisible = false
            this.$message.success('成功添加配置项！')
            this.getSettingsList()
          })
        } else {
          this.$message.error('请按要求填写配置信息！')
          return false
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.p-game-settings {
  .divider {
    position: absolute;
    top: 50px;
    right: 0;
    width: 1px;
    background-color: #dcdfe6;
    height: 100px;
  }
}
</style>

