<template>
  <div class="task-print">
    <template v-if="!IS_REBUILD">
      <p v-if="IS_MODEL2" class="tips-info mb-2">
        考试需要命题老师提交具体印刷份数
      </p>
      <p v-else class="tips-info mb-2">
        考试需要命题老师提交完整的考务数据，每个卷袋表示一个考场，人数字段为应考人数，备份数量为该考场试卷题卡备用数量
      </p>
    </template>
    <div v-if="IS_MODEL2 || IS_REBUILD" class="part-box">
      <div class="box-justify mb-1">
        <div></div>
        <el-button v-if="editable" type="primary" @click="toSelectClass"
          >选择班级</el-button
        >
      </div>
      <table class="table">
        <colgroup>
          <col width="90" />
          <col width="120" />
          <col width="120" />
          <col width="200" />
          <col width="300" />
          <col width="100" />
        </colgroup>
        <tr>
          <th>卷袋序号</th>
          <th>印刷份数</th>
          <th>备份数量</th>
          <th>印刷室</th>
          <th>班级</th>
          <th>操作</th>
        </tr>
        <tr>
          <td>1</td>
          <td>
            <el-input-number
              v-model="modalForm.totalSubjects"
              class="width-full"
              :min="1"
              :max="999999"
              :step="1"
              step-strictly
              :controls="false"
              :disabled="IS_REBUILD || !editable"
            ></el-input-number>
          </td>
          <td>
            <el-input-number
              v-model="modalForm.backupCount"
              class="width-full"
              :min="infoExamPrintPlan.backupCount"
              :max="999999"
              :step="1"
              step-strictly
              :controls="false"
              :disabled="!editable"
            ></el-input-number>
          </td>
          <td>
            <el-select
              v-model="modalForm.printHouseId"
              placeholder="请选择"
              class="width-full"
              filterable
              :disabled="!editable"
            >
              <el-option
                v-for="room in printHouses"
                :key="room.printHouseId"
                :value="room.printHouseId"
                :label="room.printHouseName"
              ></el-option>
            </el-select>
          </td>
          <td>
            {{ modalForm.className }}
          </td>
          <td>
            <el-button
              class="btn-primary"
              type="text"
              @click="toViewModel2Student"
              >查看考生</el-button
            >
          </td>
        </tr>
      </table>
    </div>
    <div v-else class="part-box">
      <div class="box-justify mb-2">
        <div>
          <p>
            每个卷袋包含一个考场全部文件（试卷、题卡、卷袋贴、签到表等文件）
          </p>
          <p>
            共{{ packageInfos.packageCount }}个卷袋，{{
              packageInfos.studentCount
            }}个考生，共印试卷{{ packageInfos.paperCount }}份（正式{{
              packageInfos.paperReleaseCount
            }}份，备用{{ packageInfos.paperBackupCount }}份）
          </p>
        </div>
        <div>
          <el-button
            v-if="checkPrivilege('button', 'ExamTaskStudentObject') && editable"
            type="primary"
            @click="toAdd"
            >新增考试对象</el-button
          >
        </div>
      </div>
      <el-table ref="TableList" :data="tableData" border>
        <el-table-column type="index" width="80" label="卷袋序号">
        </el-table-column>
        <el-table-column prop="className" label="考试对象" width="160">
        </el-table-column>
        <el-table-column prop="studentCount" label="人数" width="60">
        </el-table-column>
        <el-table-column prop="backupCount" label="备份数量" width="90">
          <template slot-scope="scope">
            <el-input-number
              v-model="scope.row.backupCount"
              style="width: 60px"
              :min="scope.row.minBackupCount"
              :max="99999"
              :step="1"
              step-strictly
              :controls="false"
              :disabled="!editable"
              @change="backupCountChange"
            ></el-input-number>
          </template>
        </el-table-column>
        <el-table-column label="考试时间" width="300">
          <template slot-scope="scope">
            <template v-if="!scope.row.canEditTime">
              {{ scope.row.examDate }} {{ scope.row.examTime }}
            </template>
            <template v-else>
              <one-date-time-range
                :start-date-time.sync="scope.row.examStartTime"
                :end-date-time.sync="scope.row.examEndTime"
                :disabled="!editable"
                @change="timeChange(scope.row)"
              >
              </one-date-time-range>
            </template>
          </template>
        </el-table-column>
        <el-table-column prop="examPlace" label="校区（考点）" width="140">
          <template slot-scope="scope">
            <el-input
              v-model.trim="scope.row.examPlace"
              :maxlength="20"
              clearable
              :disabled="!editable"
            ></el-input>
          </template>
        </el-table-column>
        <el-table-column prop="examRoom" label="考试教室（考场）" width="140">
          <template slot-scope="scope">
            <el-input
              v-model.trim="scope.row.examRoom"
              :maxlength="20"
              clearable
              :disabled="!editable"
            ></el-input>
          </template>
        </el-table-column>
        <el-table-column prop="printHouseName" label="印刷室" width="140">
          <template slot-scope="scope">
            <el-select
              v-model="scope.row.printHouseId"
              placeholder="请选择"
              filterable
              :disabled="!editable"
              @change="() => printHouseChange(scope.row)"
            >
              <el-option
                v-for="room in printHouses"
                :key="room.printHouseId"
                :value="room.printHouseId"
                :label="room.printHouseName"
              ></el-option>
            </el-select>
          </template>
        </el-table-column>
        <el-table-column
          label="操作"
          width="120"
          class-name="action-column"
          align="center"
          fixed="right"
        >
          <template slot-scope="scope">
            <el-button
              v-if="editable"
              class="btn-danger"
              type="text"
              @click="toDelete(scope.$index)"
              >取消</el-button
            >
            <el-button
              class="btn-primary"
              type="text"
              @click="toViewStudent(scope.row)"
              >查看考生</el-button
            >
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- ModifyExamTaskStudent -->
    <modify-exam-task-student
      v-if="editable"
      ref="ModifyExamTaskStudent"
      :disabled-ids="disabledStudentIds"
      :filter-params="{
        courseId: infoExamTask.courseId,
        examId: infoExamTask.examId,
        teachingRoomId: infoExamTask.teachingRoomId,
      }"
      :show-student="showStudent"
      :selected-ids="IS_MODEL2 || IS_REBUILD ? model2ClassList : null"
      @modified="examStudentModified"
    ></modify-exam-task-student>
    <!-- PreviewTaskStudent -->
    <preview-task-student
      ref="PreviewTaskStudent"
      :student-list="examStudentList"
      :editable="!showStudent && editable"
      @close="previewStudentClosed"
    ></preview-task-student>
  </div>
</template>

<script>
import { mapState } from "vuex";
import { calcSum, getExamDateTime, getTimeDatestamp } from "@/plugins/utils";
import { listTaskPrintHouse } from "../../api";
import { examConfigByExamIdOrgId } from "../../../base/api";
import ModifyExamTaskStudent from "../createExamAndPrintTask/ModifyExamTaskStudent.vue";
import PreviewTaskStudent from "../createExamAndPrintTask/PreviewTaskStudent.vue";
import OneDateTimeRange from "@/components/OneDateTimeRange.vue";

const initModalForm = {
  paperNumber: "",
  courseName: "",
  courseCode: "",
  courseId: "",
  totalSubjects: 1,
  printHouseId: "",
  backupCount: null,
  className: "",
  basicStudentIds: [],
};

export default {
  name: "task-print",
  components: { ModifyExamTaskStudent, PreviewTaskStudent, OneDateTimeRange },
  data() {
    return {
      modalForm: {
        ...initModalForm,
      },
      tableData: [],
      model2ClassList: [],
      model2Students: [],
      curRow: {},
      printHouses: [],
      packageInfos: {
        packageCount: 0,
        studentCount: 0,
        paperCount: 0,
        paperReleaseCount: 0,
        paperBackupCount: 0,
      },
      selectedStudentIds: [],
      disabledStudentIds: [],
      examStudentList: [],
      showStudent: false,
      curCreateTime: [],
      defaultTime: "",
      // exam task content
      infoExamTask: {},
      infoExamTaskDetail: [],
      infoExamPrintPlan: {},
      infoPrintTask: {},
    };
  },
  computed: {
    ...mapState("exam", ["editType", "examTask", "curTaskApply", "taskStatus"]),
    IS_MODEL2() {
      return this.examTask.examModel === "MODEL2";
    },
    IS_REBUILD() {
      return this.examTask.category === "REBUILD";
    },
    editable() {
      return this.taskStatus.IS_APPLY;
    },
  },
  mounted() {
    const curDate = getTimeDatestamp(Date.now());
    const hour = 60 * 60 * 1000;
    this.curCreateTime = [curDate + 8 * hour, curDate + 10 * hour];
    this.defaultTime = curDate;

    this.initData();
  },
  methods: {
    async getPrintHouses() {
      this.printHouses = await listTaskPrintHouse();
    },
    async getInfoPrintTask() {
      const orgInfo = this.$ls.get("user", { orgInfo: {} }).orgInfo;
      const examPrintPlan = await examConfigByExamIdOrgId({
        examId: this.examTask.examId,
        orgId: orgInfo.id,
      });
      this.infoExamPrintPlan = examPrintPlan || {};
    },
    async initData() {
      await this.getPrintHouses();
      await this.getInfoPrintTask();

      if (!this.curTaskApply.examTaskContent) return;

      const { examTask, examTaskDetailList, examDetail } = JSON.parse(
        this.curTaskApply.examTaskContent
      );
      this.infoExamTask = examTask;
      this.infoExamTaskDetail = examTaskDetailList;
      this.infoPrintTask = examDetail;

      this.modalForm = this.$objAssign(initModalForm, this.infoPrintTask);
      if (this.IS_MODEL2 || this.IS_REBUILD) {
        this.model2ClassList = this.infoPrintTask.className.split(",");
        this.model2Students = this.infoPrintTask.model2Students || [];
        return;
      }

      this.tableData = this.infoPrintTask.list;
      this.updatePackageInfos();
    },
    updatePackageInfos() {
      this.packageInfos.packageCount = this.tableData.length;
      this.packageInfos.studentCount = calcSum(
        this.tableData.map((item) => item.studentCount)
      );
      this.packageInfos.paperReleaseCount = this.packageInfos.studentCount;
      this.packageInfos.paperBackupCount = calcSum(
        this.tableData.map((item) => item.backupCount || 0)
      );
      this.packageInfos.paperCount =
        this.packageInfos.paperReleaseCount +
        this.packageInfos.paperBackupCount;
    },
    getBackupCount(studentCount) {
      const { backupCount } = this.infoExamPrintPlan;
      if (backupCount < 1) {
        const count = Math.ceil(backupCount * studentCount);
        return { backupCount: count, minBackupCount: count };
      }
      return { backupCount, minBackupCount: backupCount };
    },
    timeChange(row) {
      if (!row.examStartTime || !row.examEndTime) {
        row.examDate = "";
        row.examTime = "";
        return;
      }

      Object.assign(row, getExamDateTime(row.examStartTime, row.examEndTime));
    },
    backupCountChange() {
      this.updatePackageInfos();
    },
    printHouseChange(row) {
      const curHouse = this.printHouses.find(
        (item) => item.printHouseId === row.printHouseId
      );
      if (curHouse) {
        row.printHouseName = curHouse.printHouseName;
      }
    },
    toAdd() {
      if (!this.infoExamTask.courseId) {
        this.$message.error("请先选择课程");
        return;
      }

      this.disabledStudentIds = this.getTabelStudentIds();
      this.showStudent =
        this.checkPrivilege("button", "SelectStudent") &&
        this.infoExamTask.examModel !== "MODEL1";
      this.$refs.ModifyExamTaskStudent.open();
    },
    getTabelStudentIds() {
      return this.tableData
        .map((item) => {
          return item.examTaskStudentObjectParamList.map((elem) => elem.id);
        })
        .flat();
    },
    getInitTableRow() {
      let modalFormData = { ...this.modalForm };
      delete modalFormData.printHouseId;
      let data = {
        id: this.$randomCode(),
        groupName: "",
        examPlace: "",
        examRoom: "",
        examStartTime: "",
        examEndTime: "",
        examDate: "",
        examTime: "",
        examSetDate: [],
        className: "",
        studentCount: "",
        printHouseId: "",
        printHouseName: "",
        backupCount: 0,
        minBackupCount: 0,
        isSelectStudent: true,
        examTaskStudentObjectParamList: [],
        classNames: [],
        canEditTime: false,
        ...modalFormData,
      };
      return data;
    },
    examStudentModified({ selectedStudents }) {
      if (this.IS_MODEL2 || this.IS_REBUILD) {
        this.model2ClassList = selectedStudents.map((item) => item.label);
        this.modalForm.className = this.model2ClassList.join();
        this.model2Students = selectedStudents
          .map((item) => item.children)
          .flat()
          .map((item) => {
            return { ...item, enable: true };
          });
        this.modalForm.basicStudentIds = this.model2Students.map(
          (item) => item.id
        );
        this.modalForm.totalSubjects = this.model2Students.length;
        return;
      }

      this.updateTableData(selectedStudents);

      this.updatePackageInfos();
    },
    updateTableData(selectedStudents) {
      const groupMap = {};
      selectedStudents.forEach((item) => {
        item.children.forEach((student) => {
          const { examRoom, examPlace, examStartTime, examEndTime } = student;
          const groupName = `${examRoom}_${examPlace}_${examStartTime}_${examEndTime}`;
          if (!groupMap[groupName]) {
            groupMap[groupName] = {
              examTaskStudentObjectParamList: [],
              classNames: [],
              examRoom,
              examPlace,
              examStartTime,
              examEndTime,
              groupName,
            };
          }
          // TODO:可能需要简化一下学生信息
          groupMap[groupName].examTaskStudentObjectParamList.push({
            ...student,
            enable: true,
          });
          if (!groupMap[groupName].classNames.includes(item.label)) {
            groupMap[groupName].classNames.push(item.label);
          }
        });
      });

      const tableGroupNames = this.tableData.map((item) => {
        const { examRoom, examPlace, examStartTime, examEndTime } = item;
        return `${examRoom}_${examPlace}_${examStartTime}_${examEndTime}`;
      });

      Object.keys(groupMap).forEach((groupName) => {
        const data = groupMap[groupName];
        const ind = tableGroupNames.indexOf(groupName);
        if (ind !== -1) {
          this.tableData[ind].examTaskStudentObjectParamList.push(
            ...data.examTaskStudentObjectParamList
          );
          const classNameSet = new Set([
            ...this.tableData[ind].classNames,
            ...data.classNames,
          ]);
          const studentCount =
            this.tableData[ind].examTaskStudentObjectParamList.length;
          this.tableData[ind].studentCount = studentCount;
          this.tableData[ind].classNames = Array.from(classNameSet);
          this.tableData[ind].className = this.tableData[ind].classNames.join();

          Object.assign(this.tableData[ind], this.getBackupCount(studentCount));
          return;
        }

        const times =
          data.examStartTime && data.examEndTime
            ? getExamDateTime(data.examStartTime, data.examEndTime)
            : { examSetDate: [...this.curCreateTime] };

        const tableRow = this.$objAssign(this.getInitTableRow(), {
          ...data,
          ...times,
          ...this.getBackupCount(data.examTaskStudentObjectParamList.length),
          className: data.classNames.join(),
          studentCount: data.examTaskStudentObjectParamList.length,
          canEditTime: !data.examStartTime || !data.examEndTime,
        });
        this.tableData.push(tableRow);
      });
    },
    toDelete(index) {
      this.tableData.splice(index, 1);
      this.updatePackageInfos();
    },
    toViewStudent(row) {
      // console.log(row);
      this.curRow = row;
      this.examStudentList = row.examTaskStudentObjectParamList;
      this.$refs.PreviewTaskStudent.open();
    },
    toViewModel2Student() {
      this.examStudentList = this.model2Students;
      this.$refs.PreviewTaskStudent.open();
    },
    previewStudentClosed() {
      const students = this.examStudentList.filter((item) => item.enable);
      const studentCount = students.length;

      if (this.IS_MODEL2 || this.IS_REBUILD) {
        this.modalForm.totalSubjects = studentCount;
        this.modalForm.basicStudentIds = students.map((item) => item.id);
        return;
      }

      Object.assign(this.curRow, {
        ...this.getBackupCount(studentCount),
        studentCount,
      });
    },
    // model2 select class
    toSelectClass() {
      if (!this.infoExamTask.courseId) {
        this.$message.error("请先选择课程");
        return;
      }

      this.disabledStudentIds = [];
      this.showStudent = false;
      this.$refs.ModifyExamTaskStudent.open();
    },
    // action
    getData(examTaskData) {
      const tableData = this.tableData.map((row) => {
        const nrow = { ...row };
        nrow.examTaskStudentObjectParamListIds =
          row.examTaskStudentObjectParamList
            .filter((item) => item.enable)
            .map((item) => item.id);
        return nrow;
      });

      this.infoPrintTask = {
        ...this.modalForm,
        model2Students: this.model2Students,
        list: tableData,
      };

      this.infoExamTaskDetail = examTaskData.examTaskDetailList;
      const examTaskContent = {
        examTask: this.infoExamTask,
        examTaskDetail: this.infoExamTaskDetail,
        examDetail: this.infoPrintTask,
      };
      examTaskContent.examTask.examStartTime = this.infoPrintTask.examStartTime;
      examTaskContent.examTask.examEndTime = this.infoPrintTask.examEndTime;
      return examTaskContent;
    },
    checkData() {
      if (this.IS_MODEL2 || this.IS_REBUILD) {
        if (!this.modalForm.totalSubjects) {
          this.$message.error("请输入印刷份数！");
          return;
        }
        if (!this.modalForm.printHouseId) {
          this.$message.error("请选择印刷室！");
          return;
        }
        if (!this.modalForm.className) {
          this.$message.error("请选择班级！");
          return;
        }
        return true;
      }

      if (!this.tableData.length) {
        this.$message.error("请添加考试对象！");
        return;
      }

      const errorMsg = [];
      this.tableData.forEach((row) => {
        const errorFields = [];

        if (!row.examStartTime || !row.examEndTime) {
          errorFields.push("考试时间");
        }
        if (!row.backupCount) {
          errorFields.push("备份数量");
        }
        if (!row.examPlace) {
          errorFields.push("校区（考点）");
        }
        if (!row.examRoom) {
          errorFields.push("考试教室（考场）");
        }
        if (!row.printHouseId) {
          errorFields.push("印刷室");
        }
        if (errorFields.length) {
          errorMsg.push(
            `考试对象${row.className}中，${errorFields.join("、")}必须填写`
          );
        }
      });
      if (errorMsg.length) {
        this.$message.error(errorMsg.join("。"));
        return;
      }
      return true;
    },
  },
};
</script>
