<template>
  <x-modal
    :append-to-body="appendToBody"
    :destroy-on-close="false"
    :okConfig="config.okConfig"
    :cancelConfig="config.cancelConfig"
    :modalVisible.sync="visiable"
    wrapper-class="select-role-modal"
    :modal="modal"
    :customModalBg="customModalBg"
    :modal-append-to-body="modalAppendToBody"
    width="middle"
  >
    <template slot="title">
      <div class="header">
        <span class="header-title">{{ config.title }}</span>
        <el-input
          v-model="searchValue"
          class="header-search-input"
          :placeholder="'回车输入角色'"
          :clearable="true"
          @keyup.native.enter="handleSearchChange"
          @input="handleSearchInput"
        >
          <template slot="prefix">
            <x-svg-icon name="search-icon"></x-svg-icon>
          </template>
        </el-input>
        <x-svg-icon name="close" @click.native="handleCancelButtonClick"></x-svg-icon>
      </div>
    </template>
    <div class="main">
      <role-list
        ref="roleList"
        :loadData="config.roleConfig.loadData"
        :selectType="config.selectType"
        :selectedArray="selectedArray"
        :searchValue="searchValue"
        @select-change="handleSelectChange"
      ></role-list>
    </div>
    <template slot="footer">
      <div v-if="config.selectType === 'MULTI'" class="selected-block">
        <template v-for="(info, index) in selectedArray">
          <role-tag
            :key="info.id"
            :roleName="info.roleName"
            :closable="true"
            @close="handleTagClose(info, index)"
          ></role-tag>
        </template>
      </div>
      <div class="footer">
        <div class="footer-notice">
          <template v-if="config.selectType === 'MULTI'">
            <span class="footer-notice-text">多选，已选择{{ selectedArray.length }}人</span>
          </template>
          <template v-else>
            <span class="footer-notice-text"
              >单选，已选择「{{ selectedArray[0] ? selectedArray[0].roleName : '' }}」</span
            >
          </template>
          <el-link class="footer-link-addrole" @click="linkToRole">
            添加应用角色
          </el-link>
        </div>
        <el-button
          :disabled="config.cancelConfig.disabled"
          :loading="cancelButtonLoading"
          @click="handleCancelButtonClick"
        >
          {{ config.cancelConfig && config.cancelConfig.title }}
        </el-button>
        <el-button
          type="primary"
          :disabled="config.okConfig.disabled"
          :loading="okButtonLoading"
          @click="handleOkButtonClick"
        >
          {{ config.okConfig && config.okConfig.title }}
        </el-button>
      </div>
    </template>
  </x-modal>
</template>

<script>
import RoleTag from './role-tag/role-tag'
import RoleList from './role-list/role-list'

export default {
  components: {
    RoleList,
    RoleTag
  },
  props: {
    title: {
      type: String,
      default: ''
    },
    selectType: {
      type: String,
      default: 'SINGLE'
    },
    roleConfig: {
      type: Object,
      default() {
        return {}
      }
    },
    appendToBody: {
      type: Boolean,
      default: true
    },
    modal: {
      type: Boolean,
      default: false
    },
    customModalBg: {
      type: Boolean,
      default: true
    },
    modalAppendToBody: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      config: {
        title: '',
        selectType: 'SINGLE', // Multi
        okConfig: {
          title: '确定'
        },
        cancelConfig: {
          title: '取消'
        },
        roleConfig: {
          loadData() {
            return new Promise([])
          }
        }
      },
      searchValue: '',
      okButtonLoading: false,
      cancelButtonLoading: false,
      selectedArray: [],
      visiable: false,
      appId: ''
    }
  },
  created() {
    this.appId = this.$route.query.appId
    this.mergeConfig(this.$options.propsData)
  },
  methods: {
    init() {
      this.searchValue = ''
      this.okButtonLoading = false
      this.cancelButtonLoading = false
      this.selectedArray = []
      this.$nextTick(() => {
        this.$refs.roleList && this.$refs.roleList.Init()
      })
    },
    mergeConfig(config) {
      if (typeof config === 'object') {
        for (let key in config) {
          if (typeof config[key] === 'object') {
            Object.assign(this.config[key], config[key])
          } else {
            this.config[key] = config[key]
          }
        }
      }
    },
    publicMethods() {
      return {
        openModal: this.openModal,
        closeModal: this.closeModal
      }
    },
    openModal(selectedArray, config) {
      this.mergeConfig(config)
      this.init()
      this.selectedArray = this.$lodash.cloneDeep(selectedArray || [])
      this.visiable = true
    },
    closeModal($event) {
      this.selectedArray = []
      this.visiable = false
    },
    handleSearchChange() {
      this.$refs.roleList && this.$refs.roleList.Init(this.searchValue)
    },
    handleSearchInput(value) {
      if (!value) {
        this.$refs.roleList && this.$refs.roleList.Init()
      }
    },
    handleFnResult(result, loadingKey) {
      if (!(result instanceof Promise) && result !== true) {
        this.visiable = false
      } else if (result instanceof Promise) {
        // 设置按钮为loading状态
        this[loadingKey] = true
        result
          .then((res) => {
            if (res !== true) {
              this.visiable = false
            }
          })
          .finally((res) => {
            this[loadingKey] = false
          })
      }
    },
    handleOkButtonClick() {
      if (!this.config.okConfig || !this.config.okConfig.onOk) {
        this.visiable = false
      } else {
        const result = this.config.okConfig.onOk(this.$lodash.cloneDeep(this.selectedArray))
        this.handleFnResult(result, 'okButtonLoading')
      }
      this.selectedArray = []
    },
    handleCancelButtonClick() {
      this.selectedArray = []
      if (!this.config.cancelConfig || !this.config.cancelConfig.onCancel) {
        this.visiable = false
      } else {
        const result = this.config.cancelConfig.onCancel()
        this.handleFnResult(result, 'cancelButtonLoading')
      }
    },
    handleSelectChange(info) {
      if (info.checked) {
        if (this.config.selectType === 'SINGLE') {
          let prevInfo = this.selectedArray.pop()
          if (prevInfo) {
            prevInfo.checked = false
          }
        }
        this.selectedArray.push(info)
      } else {
        const index = this.selectedArray.findIndex((item) => item.id === info.id)
        this.selectedArray.splice(index, 1)
      }
    },
    handleTagClose(info, index) {
      this.selectedArray.splice(index, 1)
    },
    linkToRole() {
      this.visiable = false
      let newTabRouter = this.$router.resolve({
        name: 'appBaseConfig',
        query: {
          appId: this.appId,
          hash: 'role'
        }
        // hash: 'role' // 此处无法直接使用hash值
      })
      console.log(newTabRouter.href)
      window.open(newTabRouter.href, '_blank')
    }
  }
}
</script>
