<template>
  <a-modal
    :visible="visible"
    :title="pickerTitle"
    width="680px"
    @cancel="handleCancel"
    @ok="handleConfirm"
  >
    <div class="picker">
      <!-- 左侧候选区 -->
      <div class="candidate" v-loading="loading">
        <div class="candidate_header" style="padding: 6px">
          <a-input-search
            v-model="queryParams.name"
            :placeholder="searchPlaceholder"
            size="small"
            :disabled="type === 'role' || type === 'dept'"
            @input="searchUserHandle"
          />
          <div style="margin-top: 8px; color: #8c8c8c">
            <a-icon type="apartment" />
            {{ deptStr }}
          </div>
          <div style="margin-top: 5px">
            <a-checkbox
              :disabled="!multiple || !orgData_.length || !!orgUserData.length"
              :checked="checkAll"
              @change="checkAllChangeHandle"
            >
              全选
            </a-checkbox>
            <span v-if="beforeNodes.length > 0" class="last_node" @click="lastNodeHandle">上一级</span>
          </div>
        </div>

        <!-- 组织结构项 -->
        <div class="org_items">
          <a-empty v-if="orgData_.length === 0" description="似乎没有数据" />
          <div
            v-for="(org, index) in orgData_"
            :key="index"
            class="org-item"
            :class="{
              'org-dept-item': org.type === 'dept',
              'org-user-item': org.type === 'user',
              'org-role-item': org.type === 'role'
            }"
          >
            <div v-if="org.type === 'dept'">
              <a-checkbox
                :disabled="isDeptDisableHandle(org)"
                :checked="org.selected"
                @change="e => checkboxChangeHandle(e.target.checked, org)"
              />
              <a-icon type="folder" style="margin-right: 4px" />
              <span class="name">{{ org.name }}</span>
              <span
                :class="`next-dept${org.selected ? '-disable' : ''}`"
                @click="!org.selected && nextNodeHandle(org)"
              >
                <a-icon type="branches" :style="{ color: org.selected ? '#8c8c8c' : '#1890ff' }" />
                下级
              </span>
            </div>
            <div v-if="org.type === 'user'">
              <a-checkbox
                :disabled="isDeptDisableHandle(org)"
                :checked="org.selected"
                @change="e => checkboxChangeHandle(e.target.checked, org)"
              />
              <span class="avatar">{{ getShortName(org.name) }}</span>
              <span class="name">{{ org.name }}</span>
            </div>
            <div v-if="org.type === 'role'">
              <a-checkbox
                :checked="org.selected"
                @change="e => checkboxChangeHandle(e.target.checked, org)"
              />
              <a-icon type="team" style="margin-right: 4px" />
              <span class="name">{{ org.name }}</span>
              <span
                :class="`next-dept${org.selected ? '-disable' : ''}`"
                @click="!org.selected && nextNodeHandle(org)"
              >
                <a-icon type="branches" :style="{ color: org.selected ? '#8c8c8c' : '#1890ff' }" />
                查看用户
              </span>
            </div>
          </div>
        </div>
      </div>

      <!-- 右侧已选区 -->
      <div class="selected">
        <div class="count">
          <span>已选 {{ selectedNodes.length }} 项</span>
          <span @click="clearSelectedHandle" style="cursor:pointer;color:#d03050">清空</span>
        </div>
        <a-empty v-if="selectedNodes.length === 0" description="点击左侧选择数据" />
        <div
          v-for="(org, index) in selectedNodes"
          :key="index"
          class="org-item"
        >
          <div v-if="org.type === 'dept'">
            <a-icon type="folder" />
            <span class="name">{{ org.name }}</span>
          </div>
          <div v-if="org.type === 'user'" style="display:flex;align-items:center">
            <span class="avatar">{{ getShortName(org.name) }}</span>
            <span class="name">{{ org.name }}</span>
          </div>
          <div v-if="org.type === 'role'" style="display:flex;align-items:center">
            <a-icon type="team" />
            <span class="name">{{ org.name }}</span>
          </div>
          <a-icon
            type="close"
            style="padding-top: 5px;right:5px;cursor:pointer"
            @click="removeNode(org)"
          />
        </div>
      </div>
    </div>

    <!-- 底部按钮 -->
<!--    <div slot="footer" style="text-align:right;margin-top:10px;">-->
<!--      <a-button size="small" @click="handleCancel">取消</a-button>-->
<!--      <a-button type="primary" size="small" @click="handleConfirm">确认</a-button>-->
<!--    </div>-->
  </a-modal>
</template>

<script>
import { message } from 'ant-design-vue';
import { getAction } from '@api/manage'

export default {
  name: 'OrgPicker',
  props: {
    title: { type: String, default: '请选择' },
    type: { type: String, default: 'org' }, // org/user/dept/role
    multiple: { type: Boolean, default: true },
    selected: { type: Array, default: () => [] }
  },
  data() {
    return {
      visible: false,
      loading: false,
      orgData: [],
      orgUserData: [],
      beforeNodes: [],
      checkAll: false,
      queryParams: { name: '' },
      selectedNodes: [...this.selected]
    };
  },
  computed: {
    orgData_() {
      return this.orgUserData.length > 0 ? this.orgUserData : this.orgData;
    },
    deptStr() {
      return this.beforeNodes.map(v => v.name).join(' > ');
    },
    pickerTitle() {
      switch (this.type) {
        case 'user': return '请选择人员';
        case 'role': return '请选择角色';
        case 'dept': return '请选择部门';
        default: return '-';
      }
    },
    searchPlaceholder() {
      if (this.type === 'role') return '角色暂不支持搜索';
      if (this.type === 'dept') return '部门暂不支持搜索';
      return '搜索人员，支持拼音、姓名';
    }
  },
  methods: {
    show() {
      this.checkAll = false;
      this.visible = true;
      this.beforeNodes = [];
      this.orgUserData = [];
      this.orgData = [];
      this.selectedNodes = [...this.selected];
      if (this.type === 'role') this.loadRoleData();
      else if (this.type === 'dept') this.loadDeptData();
      else this.loadOrgData();
    },
    handleCancel() {
      this.visible = false;
      // this.$emit('cancel');
    },
    handleConfirm() {
      const cleanNodes = this.selectedNodes.map(n => ({ ...n }));
      this.$emit('confirm', cleanNodes);
      this.visible = false;
    },
    loadOrgData(deptId) {
      this.loading = true;
      getAction("/sys/sysDepart/queryTreeList/parent",{ parentId:deptId }).then(res => {
        this.orgData = res.result;
        this.loading = false;
      });
    },
    loadRoleData() {
      this.loading = true;
      getAction("/sys/role/all").then(res => {
        this.orgData = res.result;
        this.loading = false;
      });
    },
    loadDeptData() {
      this.loading = true;
      getAction("/sys/sysDepart/queryTreeList/all").then(res => {
        this.orgData = res.result;
        this.loading = false;
      });
    },
    loadUsersByRole(roleId) {
      this.loading = true;
      getAction("/sys/user/userByRole",{roleId:roleId}).then(res => {
        this.orgData = res.result;
        this.loading = false;
      });
    },
    isDeptDisableHandle(node) {
      if (this.type === 'dept') return false;
      return this.type === 'user' && node.type === 'dept';
    },
    lastNodeHandle() {
      if (this.beforeNodes.length === 0) return;
      this.beforeNodes.pop();
      const node = this.beforeNodes[this.beforeNodes.length - 1];
      if (!node) {
        if (this.type === 'role') this.loadRoleData();
        else if (this.type === 'dept') this.loadDeptData();
        else this.loadOrgData();
      } else {
        if (this.type === 'role') this.loadRoleData();
        else if (this.type === 'dept') this.loadDeptData();
        else this.loadOrgData(node.id);
      }
    },
    nextNodeHandle(node) {
      this.beforeNodes.push(node);
      if (this.type === 'role' && node.type === 'role') {
        this.loadUsersByRole(node.id);
      } else {
        this.loadOrgData(node.id);
      }
    },
    searchUserHandle() {
      if (!this.queryParams.name.trim()) {
        this.orgUserData = [];
        return;
      }
      if (this.type !== 'user') {
        this.orgUserData = [];
        return;
      }
      getAction("/sys/user/search",{ username: this.queryParams.name }).then(res => {
        this.orgUserData = res.data;
      });
    },
    checkboxChangeHandle(checked, node) {
      if (checked) {
        if (!this.multiple && this.selectedNodes.length > 0) {
          message.warning('禁止多选');
          return;
        }
        this.selectedNodes.push({ ...node });
      } else {
        this.checkAll = false;
        this.removeNode(node);
      }
      node.selected = checked;
    },
    removeNode(node) {
      this.selectedNodes = this.selectedNodes.filter(item => item.id !== node.id);
      const orgItem = this.orgData.find(item => item.id === node.id);
      if (orgItem) orgItem.selected = false;
    },
    clearSelectedHandle() {
      this.selectedNodes.forEach(item => this.removeNode(item));
    },
    getShortName(name) {
      return name ? (name.length > 2 ? name.substring(1, 3) : name) : '**';
    },
    checkAllChangeHandle(e) {
      const val = e.target.checked;
      this.checkAll = val;
      for (const item of this.orgData) {
        if (this.isDeptDisableHandle(item)) continue;
        item.selected = val;
        if (val && !this.selectedNodes.find(i => i.id === item.id)) {
          this.selectedNodes.push({ ...item });
        }
      }
      if (!val) this.selectedNodes = [];
    }
  }
};
</script>

<style scoped lang="less">
/* 样式保持原有结构，只需将 .n- 前缀换成 a- */
@containWidth: 278px;
.candidate, .selected { flex: 1; overflow-y: auto; border: 1px solid #e8e8e8; }
.picker { display: flex; height: 402px; }
.org_items { overflow-y: auto; position: relative; height: 310px; }
.org-item { display: flex; justify-content: space-between; width: calc(100% - 18px); position: relative; padding: 10px 5px; }
.org-item:hover { background: #f1f1f1; }
.avatar { width: 25px; font-size: 10px; text-align: center; display: inline-block; line-height: 25px; background: #1890ff; color: #fff; border-radius: 50%; margin: 0 5px 0 5px;}
.next-dept { float: right; color: #1890ff; cursor: pointer; }
.next-dept-disable { float: right; color: #8c8c8c; cursor: not-allowed; }
.last_node { cursor: pointer; color: #1890ff; }
.count { padding: 10px; border-bottom: 1px solid #e8e8e8; margin-bottom: 5px; display: flex; justify-content: space-between; }
</style>
