<template>
  <el-dialog
    class="select-user-dialog"
    :visible.sync="modalIsShow"
    title="选择考试对象"
    top="10vh"
    width="900px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    append-to-body
    @opened="visibleChange"
  >
    <div class="user-search">
      <el-form inline>
        <!-- <el-form-item>
          <el-select v-model="filter.courseId" placeholder="请选择" filterable>
            <el-option-group
              v-for="item in courses"
              :key="item.label"
              :label="item.label"
            >
              <el-option
                v-for="course in item.options"
                :key="course.id"
                :value="course.id"
                :label="`${course.name}（${course.code}）`"
              >
              </el-option>
            </el-option-group>
          </el-select>
        </el-form-item> -->
        <el-form-item>
          <el-input
            v-model.trim="filter.teacher"
            placeholder="任课老师"
            clearable
            style="width: 160px"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-input
            v-model.trim="filter.teachClassName"
            placeholder="班级名称(教学班)"
            clearable
            style="width: 160px"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-input
            v-model.trim="filter.className"
            placeholder="班级名称(行政班)"
            clearable
            style="width: 160px"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-input
            v-model.trim="filter.paperNumber"
            placeholder="试卷编号"
            clearable
            style="width: 160px"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="search">查询</el-button>
        </el-form-item>
      </el-form>
    </div>

    <el-row type="flex" :gutter="10">
      <el-col :span="12">
        <h3 class="user-part-title title-select">
          <el-checkbox
            v-model="allSelect"
            class="title-checkbox"
            @change="allSelectChange"
            >全选</el-checkbox
          >
          <div>{{ showStudent ? "班级/学生" : "班级" }}</div>
        </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"
          >
            <span class="custom-common-node" slot-scope="{ data }">
              {{ data.label }}
              <i v-if="data.count !== undefined" class="color-gray-3 ml-1"
                >[{{ data.count }}]</i
              >
            </span>
          </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 }}
                <i v-if="data.count !== undefined" class="color-gray-3 ml-1">
                  [{{ data.count }}]
                </i>
              </span>
              <el-button
                type="text"
                icon="el-icon-remove"
                class="color-danger"
                @click.stop="removeSelectStudent(node)"
              >
              </el-button>
            </span>
          </el-tree>
        </div>
      </el-col>
    </el-row>

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

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

export default {
  name: "modify-exam-task-student",
  props: {
    disabledIds: {
      type: Array,
      default() {
        return [];
      },
    },
    selectedIds: {
      type: Array,
      default() {
        return [];
      },
    },
    filterParams: {
      type: Object,
      default() {
        return {
          courseId: "",
          examId: "",
          teachingRoomId: "",
        };
      },
    },
    showStudent: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      modalIsShow: false,
      filter: {
        courseId: "",
        examId: "",
        teacher: "",
        teachClassName: "",
        className: "",
        paperNumber: "",
      },
      dataTree: [],
      userTree: [],
      selectedUsers: [],
      filterLabel: "",
      loading: false,
      courses: [],
      allSelect: false,
      defaultProps: {
        children: "children",
        label: "label",
        disabled: "disabled",
      },
    };
  },
  methods: {
    async visibleChange() {
      this.allSelect = false;
      this.filter = this.$objAssign(this.filter, this.filterParams);
      await this.getStudents();

      this.$refs.UserTree.setCheckedKeys([]);
      this.selectedUsers = [];
      this.userTree = this.getUserTree();
      this.updateUserTreeDisableInfo(this.disabledIds);

      if (this.selectedIds && this.selectedIds.length) {
        this.$nextTick(() => {
          this.$refs.UserTree.setCheckedKeys(this.selectedIds);
          this.checkChange();
        });
      }
    },
    async search() {
      await this.getStudents();
      this.userTree = this.getUserTree();

      this.$nextTick(() => {
        this.setTreeSelectedKeys();
      });
    },
    async getCourses() {
      this.courses = [];
      if (!this.filterParams.teachingRoomId) return;
      const res = await courseQuery({
        teachingRoomId: this.filterParams.teachingRoomId,
        examId: this.filterParams.examId,
      });
      const teachingCourseIds = res.teachCourseList.map((item) => item.id);
      this.courses = [
        {
          label: "课程管理",
          options: res.teachCourseList,
        },
        {
          label: "开课学院",
          options: res.basicCourseList.filter(
            (item) => !teachingCourseIds.includes(item.id)
          ),
        },
      ];
    },
    async getStudents() {
      const data = await uploadOrFindExamTaskStudent(this.filter);
      this.dataTree = this.parseStudentData(data);
    },
    parseStudentData(data) {
      const disabledStdIds = this.disabledIds.map((item) => item.split("_")[1]);
      return data.map((item) => {
        let nitem = {
          id: item.teachClassName,
          label: item.teachClassName,
          children: [],
        };

        nitem.children = item.studentInfoList.map((elem) => {
          return {
            ...elem,
            label: elem.studentName,
            isUser: true,
            disabled: disabledStdIds.includes(elem.studentId),
          };
        });
        nitem.disabled = !nitem.children.some((elem) => !elem.disabled);
        nitem.count = nitem.children.length;

        return nitem;
      });
    },
    getUserTree() {
      let userTree = this.dataTree;
      if (this.showStudent) return userTree;

      return userTree.map((item) => {
        let nitem = { ...item };
        nitem.children = [];
        return nitem;
      });
    },
    allSelectChange() {
      if (this.allSelect) {
        this.$refs.UserTree.setCheckedKeys(
          this.userTree.map((item) => item.id)
        );
      } else {
        this.$refs.UserTree.setCheckedKeys([]);
      }
      this.checkChange();
    },
    checkChange() {
      // console.log("check click");
      const selectedKeys = this.$refs.UserTree.getCheckedKeys(true);
      if (!this.showStudent) {
        this.selectedUsers = this.userTree.filter((item) =>
          selectedKeys.includes(item.id)
        );
        return;
      }

      let selectedUsers = [];
      this.userTree.forEach((item) => {
        const children = item.children.filter((elem) =>
          selectedKeys.includes(elem.id)
        );
        if (children.length) {
          selectedUsers.push({
            ...item,
            children,
          });
        }
      });
      this.selectedUsers = selectedUsers;
    },
    removeSelectStudent(node) {
      // console.log("node remove");
      if (!this.showStudent) {
        this.selectedUsers = this.selectedUsers.filter(
          (item) => item.id !== node.data.id
        );
        this.$refs.UserTree.setCheckedKeys(
          this.selectedUsers.map((item) => item.id)
        );
        return;
      }

      this.$refs.UserSelectedTree.remove(node);
      this.setTreeSelectedKeys();
      this.checkChange();
    },
    setTreeSelectedKeys() {
      if (!this.showStudent) {
        const selectedUsersIds = this.selectedUsers.map((item) => item.id);
        this.$refs.UserTree.setCheckedKeys(selectedUsersIds);
        return;
      }
      let selectedUserIds = [];
      this.selectedUsers.forEach((item) => {
        item.children.forEach((elem) => {
          selectedUserIds.push(elem.id);
        });
      });
      this.$refs.UserTree.setCheckedKeys(selectedUserIds);
    },
    labelChange() {
      if (this.filterLabel) {
        const escapeRegexpString = (value = "") =>
          String(value).replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
        const reg = new RegExp(escapeRegexpString(this.filterLabel), "i");
        this.userTree = this.getUserTree().filter((item) =>
          reg.test(item.label)
        );
      } else {
        this.userTree = this.getUserTree();
      }
      this.setTreeSelectedKeys();
    },
    updateUserTreeDisableInfo(disabledIds) {
      if (!this.showStudent) {
        const disabledClassIds = [];
        this.dataTree.forEach((item) => {
          if (item.children.some((elem) => disabledIds.includes(elem.id))) {
            disabledClassIds.push(item.id);
          }
        });
        this.userTree.forEach((item) => {
          item.disabled = disabledClassIds.includes(item.id);
        });
        return;
      }

      this.userTree.forEach((item) => {
        item.children.forEach((elem) => {
          elem.disabled = disabledIds.includes(elem.id);
        });
        item.disabled = !item.children.some((elem) => !elem.disabled);
      });
    },
    cancel() {
      this.modalIsShow = false;
    },
    open() {
      this.modalIsShow = true;
    },
    getFullSelectedUsers() {
      let userTree = this.dataTree;
      const selectedUsersIds = this.selectedUsers.map((item) => item.id);
      return userTree.filter((item) => selectedUsersIds.includes(item.id));
    },
    submit() {
      if (!this.selectedUsers.length) {
        this.$message.error("请选择考试对象");
        return;
      }

      if (this.loading) return;
      this.loading = true;
      const selectedUsers = this.showStudent
        ? this.selectedUsers
        : this.getFullSelectedUsers();

      this.$emit("modified", {
        selectedStudents: selectedUsers,
        isSelectStudent: this.showStudent,
      });
      setTimeout(() => {
        this.loading = false;
      }, 500);
      this.cancel();
    },
  },
};
</script>
