<template>
  <el-dialog
    class="modify-exam-student select-user-dialog"
    :visible.sync="modalIsShow"
    title="选择考试对象"
    top="10vh"
    width="600px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    append-to-body
    @opened="visibleChange"
  >
    <div class="mb-4 tab-btns">
      <el-button
        v-for="(val, key) in EXAM_OBJECT_TYPE"
        :key="key"
        size="medium"
        :type="examObjectType === key ? 'primary' : 'default'"
        :disabled="selectedExamObjectType && selectedExamObjectType !== key"
        @click="selectMenu(key)"
        >{{ val }}
      </el-button>
    </div>

    <el-row type="flex" :gutter="10">
      <el-col :span="12">
        <h3 class="user-part-title">班级/学生</h3>
        <div class="user-tree">
          <el-tree
            ref="UserTree"
            :data="userTree"
            node-key="id"
            show-checkbox
            check-on-click-node
            :expand-on-click-node="false"
            :props="defaultProps"
            @check="checkChange"
          >
          </el-tree>
        </div>
      </el-col>
      <el-col :span="12">
        <h3 class="user-part-title">已选范围</h3>
        <div class="user-tree">
          <el-tree
            ref="UserSelectedTree"
            :data="selectedUsers"
            node-key="id"
            default-expand-all
            :props="defaultProps"
          >
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>{{ data.label }}</span>
              <el-button
                type="text"
                icon="el-icon-remove"
                class="color-danger"
                @click="removeSelectStudent(node)"
              >
              </el-button>
            </span>
          </el-tree>
        </div>
      </el-col>
    </el-row>

    <div slot="footer">
      <el-button type="primary" @click="submit">确认</el-button>
      <el-button @click="cancel">取消</el-button>
    </div>
  </el-dialog>
</template>

<script>
import { uploadOrFindExamTaskStudent } from "../../api";

const EXAM_OBJECT_TYPE = {
  TEACH_CLAZZ_STUDENT: "我教课程选择",
  BASIC_CLAZZ_STUDENT: "学生库选择"
};

export default {
  name: "modify-exam-student",
  props: {
    disabledIds: {
      type: Array,
      default() {
        return [];
      }
    },
    courseId: {
      type: String,
      default: ""
    }
  },
  components: {},
  data() {
    return {
      modalIsShow: false,
      examObjectType: "TEACH_CLAZZ_STUDENT",
      basicCourseId: null,
      EXAM_OBJECT_TYPE,
      dataTree: {
        TEACH_CLAZZ_STUDENT: [],
        BASIC_CLAZZ_STUDENT: []
      },
      selectedExamObjectType: null,
      userTree: [],
      selectedUsers: [],
      defaultProps: {
        children: "children",
        label: "label",
        disabled: "disabled"
      }
    };
  },
  methods: {
    async getStudents(examObjectType) {
      let datas = {
        examObjectType: examObjectType || this.examObjectType
      };
      if (datas.examObjectType === "TEACH_CLAZZ_STUDENT")
        datas.basicCourseId = this.courseId;
      const data = await uploadOrFindExamTaskStudent(datas);
      this.dataTree[datas.examObjectType] = this.parseStudentData(data);
    },
    parseStudentData(data) {
      const disabledStdIds = this.disabledIds.map(item => item.split("_")[1]);
      return data.map(item => {
        let nitem = {
          id: item.clazzId,
          label: item.clazzName,
          clazzId: item.clazzId,
          clazzName: item.clazzName,
          studentClazzType: item.studentClazzType,
          children: []
        };

        nitem.children = item.studentInfoList.map(elem => {
          return {
            ...elem,
            disabled: disabledStdIds.includes(elem.studentId),
            isUser: true,
            id: `${item.clazzId}_${elem.studentId}`,
            label: elem.studentName,
            studentClazzType: item.studentClazzType
          };
        });
        nitem.disabled = !nitem.children.some(elem => !elem.disabled);

        return nitem;
      });
    },
    async selectMenu(val) {
      this.examObjectType = val;
      this.$refs.UserTree.setCheckedKeys([]);

      this.selectedUsers = [];

      if (!this.dataTree[val].length) {
        await this.getStudents();
      }
      this.userTree = this.dataTree[val];
      this.updateUserTreeDisableInfo(this.disabledIds);
    },
    clearTypeData(type = "BASIC_CLAZZ_STUDENT") {
      this.dataTree[type] = [];
    },
    checkChange() {
      // console.log("check click");
      const selectedKeys = this.$refs.UserTree.getCheckedKeys(true);
      const disabledIds = [...selectedKeys, ...this.disabledIds];
      const disabledStdIds = disabledIds.map(item => item.split("_")[1]);

      let selectedUsers = [];
      this.userTree.forEach(item => {
        const children = item.children.filter(elem =>
          selectedKeys.includes(elem.id)
        );
        if (children.length) {
          selectedUsers.push({
            ...item,
            children
          });
        }
        // 同一个学生只允许选择一次
        item.children.forEach(elem => {
          elem.disabled =
            !selectedKeys.includes(elem.id) &&
            disabledStdIds.includes(elem.studentId);
        });
        item.disabled = !item.children.some(elem => !elem.disabled);
      });
      this.selectedUsers = selectedUsers;
    },
    removeSelectStudent(node) {
      // console.log("node remove");
      this.$refs.UserSelectedTree.remove(node);
      let selectedUserIds = [];
      this.selectedUsers.forEach(item => {
        item.children.forEach(elem => {
          selectedUserIds.push(elem.id);
        });
      });
      this.$refs.UserTree.setCheckedKeys(selectedUserIds);
      this.checkChange();
    },
    async visibleChange() {
      if (this.basicCourseId !== this.courseId) {
        this.basicCourseId = this.courseId;
        await this.getStudents("TEACH_CLAZZ_STUDENT");
      }

      this.selectMenu(this.examObjectType);
    },
    updateUserTreeDisableInfo(disabledIds) {
      const disabledStdIds = disabledIds.map(item => item.split("_")[1]);

      this.userTree.forEach(item => {
        item.children.forEach(elem => {
          elem.disabled = disabledStdIds.includes(elem.studentId);
        });
        item.disabled = !item.children.some(elem => !elem.disabled);
      });
    },
    clearSelectedExamObjectType() {
      this.selectedExamObjectType = null;
    },
    cancel() {
      this.modalIsShow = false;
    },
    open() {
      this.modalIsShow = true;
    },
    submit() {
      if (!this.selectedUsers.length) {
        this.$message.error("请选择考试对象");
        return;
      }
      this.selectedExamObjectType = this.examObjectType;
      this.$emit("modified", this.selectedUsers);
      this.cancel();
    }
  }
};
</script>
