<template>
  <div class="c-setting-panel">
    <el-row>
      <el-col :span="14" class="p-r">
        <div class="al-c">
          <h3 class="fw-500">
            配置详情 - {{ type === 'normal' ? '普通配置' : '私有配置' }}
          </h3>
          <span class="dis-b al-c mgb-20" style="color: #E6A23C">{{
            tip
          }}</span>
        </div>
        <el-form ref="settingForm" label-width="120px" :model="settingsForm">
          <el-form-item label="游戏">
            <el-input
              v-model="gameInfo.game_name"
              style="width: 70%"
              disabled
            />
          </el-form-item>
          <el-form-item label="平台">
            <el-select
              v-model="platform_id"
              style="width: 70%"
              @change="changePlatform"
            >
              <el-option
                v-for="item in platformsArr"
                :key="item.platform.platform_id"
                :label="item.platform.name"
                :value="item.platform.platform_id"
              />
            </el-select>
          </el-form-item>
          <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"
                  @change="changTip"
                />
              </div>
              <div v-else-if="item.type === 'string'">
                <el-input
                  v-model="item.value"
                  style="width: 70%"
                  @change="changTip"
                />
                <el-button type="primary" @click="openEditor(index)"
                  >json</el-button
                >
              </div>
              <div v-else>
                <el-input
                  v-model="item.value"
                  style="width: 70%"
                  @change="changTip"
                />
              </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="permEdit && this.platform_id"
              type="primary"
              @click="save"
              >保存</el-button
            >
            <el-button
              v-if="permPublish && this.platform_id"
              type="warning"
              @click="publish"
              >发布</el-button
            >
            <el-button v-if="permEdit && this.platform_id" @click="reset" type="success"
              >重置</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 multiple-select"
            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"
              v-if="permEdit"
              >添加新的配置项</el-button
            >
            <el-button
              v-show="selectedSettings.length > 0"
              type="danger"
              size="small"
              @click="clearSettings"
              v-if="permEdit"
              >清空</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 vueJsonEditor from 'vue-json-editor'
import { Promise } from 'q'
import { mapGetters } from 'vuex'
import { getGame } from '@/api/games'
import {
  resetSettings,
  getGameSettings,
  saveGameSettings,
  getSettingItems,
  publishGameSettings,
  saveSettingItem
} from '@/api/settings'
import getPageTitle from '@/utils/get-page-title'

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

  data() {
    return {
      uid: '',
      platform_id: 0,
      platformsArr: [],
      gameInfo: {},
      permEdit: false,
      permPublish: false,
      // left
      tip: '',
      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.uid = this.$route.params.uid
    this.permEdit =
      this.userInfo.permissions.includes(`${this.uid}-edit`) ||
      this.userInfo.permissions.includes(`${this.uid}-publish`) ||
      this.userInfo.permissions.includes(`games-writeable`)
    this.permPublish =
      this.userInfo.permissions.includes(`${this.uid}-publish`) ||
      this.userInfo.permissions.includes(`games-writeable`)
    this.getGameInfo(this.getGameSettings)
    this.getSettingsList()
  },
  methods: {
    changeState(changed) {
      this.$emit('change', changed)
    },
    changePlatform() {
      this.getGameSettings()
    },
    // left
    getGameInfo(cb) {
      getGame({ uid: this.uid })
        .then(res => {
          const { data } = res
          if (data.errcode === 0) {
            this.gameInfo = data.gameInfo
            this.platformsArr = data.gameInfo.platforms
            this.$route.meta.title = this.gameInfo.game_name
            document.title = getPageTitle(this.gameInfo.game_name)
            if (this.$route.query.platform_id) {
              this.platform_id = this.$route.query.platform_id
            } else {
              this.platform_id = this.platformsArr[0]
                ? this.platformsArr[0].platform.platform_id
                : ''
            }

            if (cb && cb instanceof Function) cb()
          }
        })
        .catch(err => {
          console.log(err)
        })
    },
    getGameSettings() {
      getGameSettings({
        uid: this.uid,
        type: this.type === 'normal' ? 0 : 1,
        id: this.gameInfo.game_id,
        pid: this.platform_id
      }).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
        this.settingKeys = data.records.map(item => {
          return item.key
        })
        if (data.published === false) {
          this.tip = '配置已保存，待发布'
        } else if (data.published === true) {
          this.tip = '配置已发布'
        }
        if (this.settingsForm.settings.length === 0) this.tip = ''
        this.changeState(false)
      })
    },
    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
      }
    },
    reset() {
      resetSettings({
        uid: this.uid,
        type: this.type === 'normal' ? 0 : 1,
        id: this.gameInfo.game_id,
        pid: this.platform_id
      })
        .then(res => {
          const { data } = res
          if (data.errcode === 0) {
            this.settingsForm.settings = data.records
            this.selectedSettings = data.records
            this.settingKeys = data.records.map(item => {
              return item.key
            })

            this.tip = '已还原到最新发布配置！'
            this.changeState(false)
          }
        })
        .catch(err => {
          console.log(err)
        })
    },
    save() {
      this.$refs['settingForm'].validate(valid => {
        if (valid) {
          this.$confirm('是否保存游戏配置？', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          })
            .then(() => {
              this.saveSettings()
            })
            .catch(() => {
              this.$message({
                type: 'info',
                message: '已取消保存!'
              })
            })
        } else {
          this.$message.error('请按要求填写游戏信息！')
          return false
        }
      })
    },
    publish() {
      this.$confirm('是否确认正式发布游戏配置?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
          // 保存
          this.saveSettings()
            .then(() => {
              publishGameSettings({
                uid: this.uid,
                cfgs: this.settingsForm.settings,
                gameId: this.gameInfo.game_id,
                platform: this.platform_id,
                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('配置发布成功！')
                this.tip = '配置已发布'
              })
            })
            .catch(err => {
              this.$message.error(err)
            })
          // 发布
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消发布操作！'
          })
        })
    },
    saveSettings() {
      return new Promise((resolve, reject) => {
        saveGameSettings({
          uid: this.uid,
          cfgs: this.settingsForm.settings,
          gameId: this.gameInfo.game_id,
          platform: this.platform_id,
          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('配置保存成功！')
          this.tip = '配置已保存，待发布'
          this.changeState(false)
          resolve()
        })
      })
    },
    changTip() {
      this.tip = '配置已修改'
      this.changeState(true)
    },
    // right
    getSettingsList() {
      getSettingItems().then(res => {
        const { data } = res
        if (data.errcode !== 0) {
          this.$notify.error({
            title: '错误',
            message: data.errmsg
          })
          return
        }
        this.settingsList = data.records
      })
    },
    clearSettings() {
      this.$confirm('是否要清空配置项?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.selectedSettings = []
          this.settingKeys = []
          this.settingsForm.settings = []
          this.$message.success('已清空配置项！')
        })
        .catch(() => {})
    },
    addSetting() {
      this.openNewSettingModal()
    },
    delSetting(val) {
      this.clickOp(val)
    },
    clickOp(val) {
      this.changTip()
      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) {
          saveSettingItem({
            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>

<style scoped>
.c-setting-panel .multiple-select >>> .el-tag {
  display: block;
  width: 100%;
  padding: 0 20px;
  text-align: left;
}

.c-setting-panel .multiple-select >>> .el-tag__close.el-icon-close {
  float: right;
  top: 5px;
}
</style>

