<template>
  <div class="info-print-task">
    <p v-if="IS_MODEL2" class="tips-info mb-2">
      考试需要命题老师提交具体印刷份数
    </p>
    <p v-else class="tips-info mb-2">
      考试需要命题老师提交完整的考务数据，每个卷袋表示一个考场，人数字段为应考人数，备份数量为该考场试卷题卡备用数量
    </p>
    <el-form ref="modalFormComp" label-position="top">
      <el-form-item label="考试时间：" required>
        <el-date-picker
          v-model="createDate"
          type="date"
          value-format="timestamp"
          placeholder="考试日期"
          style="width: 150px"
          :editable="false"
          @change="timeChange"
        >
        </el-date-picker>
        <el-time-picker
          is-range
          v-model="createTime"
          range-separator="至"
          start-placeholder="考试开始时间"
          end-placeholder="考试结束时间"
          placeholder="选择时间范围"
          value-format="timestamp"
          :editable="false"
          @change="timeChange"
        >
        </el-time-picker>
      </el-form-item>
      <el-form-item
        label="考试对象："
        required
        style="margin-bottom: 0"
      ></el-form-item>
    </el-form>
    <div v-if="IS_MODEL2" class="part-box">
      <div class="box-justify mb-1">
        <div></div>
        <el-button 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" />
        </colgroup>
        <tr>
          <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"
            ></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"
            ></el-input-number>
          </td>
          <td>
            <el-select
              v-model="modalForm.printHouseId"
              placeholder="请选择"
              class="width-full"
              filterable
            >
              <el-option
                v-for="room in printHouses"
                :key="room.printHouseId"
                :value="room.printHouseId"
                :label="room.printHouseName"
              ></el-option>
            </el-select>
          </td>
          <td>
            {{ model2ClassList.map((item) => item.clazzName).join("，") }}
          </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', 'ExamTaskStudentObjectImport')"
            type="success"
            icon="el-icon-download"
            @click="downloadTemplate('examTaskStudent')"
            >模板下载</el-button
          >
          <upload-button
            v-if="checkPrivilege('button', 'ExamTaskStudentObjectImport')"
            btn-icon="el-icon-circle-plus-outline"
            btn-content="批量导入"
            btn-type="success"
            :upload-url="uploadUrl"
            :format="['xls', 'xlsx']"
            accept=".xls,.xlsx"
            @valid-error="validError"
            @upload-success="uploadSuccess"
          >
          </upload-button>
          <el-button
            v-if="checkPrivilege('button', 'ExamTaskStudentObject')"
            type="primary"
            :disabled="studentUploaded && !!tableData.length"
            @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"
              @change="backupCountChange"
            ></el-input-number>
          </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="100"
              clearable
            ></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="50"
              clearable
            ></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
              @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
          v-for="item in extendFields"
          :key="item.code"
          :label="item.name"
          width="120"
        >
          <div slot-scope="scope">
            <el-input
              v-model="scope.row.extends[item.code]"
              placeholder="请输入"
              clearable
            ></el-input>
          </div>
        </el-table-column>
        <el-table-column
          label="操作"
          width="120"
          class-name="action-column"
          align="center"
          fixed="right"
        >
          <template slot-scope="scope">
            <el-button
              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
      ref="ModifyExamTaskStudent"
      :disabled-ids="disabledStudentIds"
      :filter-params="{
        courseCode: infoExamTask.courseCode,
        examId: infoExamTask.examId,
        teachingRoomId: infoExamTask.teachingRoomId,
      }"
      :show-student="showStudent"
      :selected-ids="IS_MODEL2 ? model2ClassIds : null"
      @modified="examStudentModified"
    ></modify-exam-task-student>
    <!-- PreviewTaskStudent -->
    <preview-task-student
      ref="PreviewTaskStudent"
      :student-list="curRow.examTaskStudentObjectParamList"
      :show-student="showStudent"
      @close="previewStudentClosed"
    ></preview-task-student>
  </div>
</template>

<script>
import { calcSum, getTimeDatestamp } from "@/plugins/utils";
import { examRuleDetail } from "../../../base/api";
import { listTaskPrintHouse } from "../../api";
import ModifyExamTaskStudent from "./ModifyExamTaskStudent.vue";
import PreviewTaskStudent from "./PreviewTaskStudent.vue";
import { mapState, mapMutations } from "vuex";
import UploadButton from "@/components/UploadButton";
import templateDownload from "@/mixins/templateDownload";

export default {
  name: "info-print-task",
  components: { ModifyExamTaskStudent, PreviewTaskStudent, UploadButton },
  mixins: [templateDownload],
  data() {
    return {
      modalForm: {
        examStartTime: "",
        examEndTime: "",
        paperNumber: "",
        courseName: "",
        courseCode: "",
        totalSubjects: 1,
        printHouseId: "",
        backupCount: null,
        classId: "",
      },
      tableData: [],
      model2ClassList: [],
      model2ClassIds: [],
      curRow: {},
      printHouses: [],
      extendFields: [],
      packageInfos: {
        packageCount: 0,
        studentCount: 0,
        paperCount: 0,
        paperReleaseCount: 0,
        paperBackupCount: 0,
      },
      selectedStudentIds: [],
      disabledStudentIds: [],
      examStudentList: [],
      showStudent: false,
      // date-picker
      curCreateTime: [],
      createDate: "",
      createTime: [],
      // import
      uploadUrl: "/api/admin/exam/task/exam_task_exam_student_import",
      dfilename: "学生导入模板.xlsx",
      studentUploaded: false,
    };
  },
  computed: {
    ...mapState("exam", [
      "infoExamTask",
      "infoExamTaskDetail",
      "infoPrintTask",
      "infoExamPrintPlan",
    ]),
    IS_MODEL2() {
      return this.infoExamTask.examModel === "MODEL2";
    },
  },
  watch: {
    "infoExamTask.courseCode": function (val, oldval) {
      if (val !== oldval) this.initData();
    },
    "infoExamPrintPlan.backupCount": function (val, oldval) {
      if (val !== oldval) this.planBackupCountChange();
    },
  },
  mounted() {
    this.getExtendFields();
    this.getPrintHouses();

    const curDate = getTimeDatestamp(Date.now());
    const hour = 60 * 60 * 1000;
    this.curCreateTime = [curDate + 8 * hour, curDate + 10 * hour];
    this.createTime = [...this.curCreateTime];
  },
  methods: {
    ...mapMutations("exam", ["updateTaskInfo"]),
    initData() {
      if (this.IS_MODEL2) {
        this.modalForm.backupCount = this.infoExamPrintPlan.backupCount;
        return;
      }

      this.modalForm = Object.assign(this.modalForm, {
        paperNumber: this.infoExamTask.paperNumber,
        courseName: this.infoExamTask.courseName,
        courseCode: this.infoExamTask.courseCode,
      });

      const { examStartTime, examEndTime } = this.infoPrintTask;
      if (examStartTime && examEndTime) {
        this.createTime = [examStartTime, examEndTime];
        this.createDate = getTimeDatestamp(examStartTime);
        this.modalForm.examStartTime = this.createTime[0];
        this.modalForm.examEndTime = this.createTime[1];
      }

      this.tableData = [];
      this.updatePackageInfos();
      this.updateData();
    },
    planBackupCountChange() {
      this.tableData.forEach((item) => {
        Object.assign(item, this.getBackupCount(item.studentCount));
      });
      this.updatePackageInfos();
    },
    getBackupCount(studentCount) {
      const { backupCount } = this.infoExamPrintPlan;
      if (backupCount < 1) {
        const count = Math.ceil(backupCount * studentCount);
        return { backupCount: count, minBackupCount: count };
      }
      return { backupCount, minBackupCount: backupCount };
    },
    checkTime() {
      if (!this.modalForm.examStartTime || !this.modalForm.examEndTime) {
        this.$message.error("请选择考试时间！");
        return false;
      }

      if (this.modalForm.examStartTime >= this.modalForm.examEndTime) {
        this.$message.error("考试开始时间必须小于考试结束时间！");
        return false;
      }
      return true;
    },
    checkData() {
      if (!this.checkTime()) return Promise.reject();

      if (this.IS_MODEL2) {
        if (!this.modalForm.totalSubjects) {
          this.$message.error("请输入印刷份数！");
          return Promise.reject();
        }
        if (!this.modalForm.printHouseId) {
          this.$message.error("请选择印刷室！");
          return Promise.reject();
        }
        if (!this.modalForm.classId) {
          this.$message.error("请选择班级！");
          return Promise.reject();
        }
        return Promise.resolve(true);
      }

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

      let errorMsg = [];
      this.tableData.forEach((row) => {
        let errorFields = [];
        this.extendFields.forEach((field) => {
          if (!row.extends[field.code]) {
            errorFields.push(field.name);
          }
        });

        if (!row.backupCount) {
          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 Promise.reject();
      }
      return Promise.resolve(true);
    },
    updateData() {
      const tableData = this.tableData.map((row) => {
        let nrow = { ...row };
        let extendFields = this.extendFields.map((field) => {
          let info = { ...field };
          info.value = row.extends[field.code];
          return info;
        });

        nrow.extendFields = JSON.stringify(extendFields);
        nrow.examStartTime = this.modalForm.examStartTime;
        nrow.examEndTime = this.modalForm.examEndTime;
        return nrow;
      });

      this.updateTaskInfo({
        infoPrintTask: {
          ...this.modalForm,
          list: tableData,
        },
      });
    },
    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;
    },
    async getExtendFields() {
      const examRule = await examRuleDetail();
      this.extendFields = examRule.extendFields
        ? JSON.parse(examRule.extendFields)
        : [];
      this.extendFields = this.extendFields.filter((item) => item.enable);
    },
    async getPrintHouses() {
      this.printHouses = await listTaskPrintHouse();
    },
    timeChange() {
      if (!this.createDate || !this.createTime) {
        this.modalForm.examStartTime = null;
        this.modalForm.examEndTime = null;
        return;
      }

      const curDate = getTimeDatestamp(this.createDate);
      const timeDate = getTimeDatestamp(this.createTime[0]);

      this.modalForm.examStartTime = curDate + this.createTime[0] - timeDate;
      this.modalForm.examEndTime = curDate + this.createTime[1] - timeDate;
    },
    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.courseCode) {
        this.$message.error("请先选择课程");
        return;
      }

      this.disabledStudentIds = this.getTabelStudentIds();
      this.showStudent = this.checkPrivilege("button", "SelectStudent");
      this.$refs.ModifyExamTaskStudent.open();
    },
    getTabelStudentIds() {
      let ids = [];
      this.tableData.forEach((item) => {
        item.examTaskStudentObjectParamList.forEach((elem) => {
          ids.push(elem.id);
        });
      });
      return ids;
    },
    getInitTableRow() {
      let modalFormData = { ...this.modalForm };
      delete modalFormData.printHouseId;
      let data = {
        id: this.$randomCode(),
        examPlace: "",
        examRoom: "",
        classId: "",
        className: "",
        studentCount: "",
        printHouseId: "",
        printHouseName: "",
        extendFields: "",
        backupCount: 0,
        minBackupCount: 0,
        isSelectStudent: true,
        examTaskStudentObjectParamList: [],
        ...modalFormData,
      };
      let extendFieldModal = {};
      this.extendFields.forEach((field) => {
        extendFieldModal[field.code] = "";
      });
      data.extends = extendFieldModal;
      return data;
    },
    examStudentModified({ selectedStudents, isSelectStudent }) {
      if (this.IS_MODEL2) {
        this.model2ClassList = selectedStudents.map((item) => {
          return {
            clazzId: item.clazzId,
            clazzName: item.clazzName,
          };
        });
        this.model2ClassIds = this.model2ClassList.map((item) => item.clazzId);
        this.modalForm.classId = this.model2ClassIds.join();
        return;
      }
      if (this.studentUploaded) {
        this.tableData = [];
        this.studentUploaded = false;
      }
      let examTaskStudentObjectParamList = [];
      selectedStudents.forEach((item) => {
        item.children.forEach((student) => {
          examTaskStudentObjectParamList.push({ ...student, enable: true });
        });
      });
      let tableRow = this.$objAssign(this.getInitTableRow(), {
        classId: selectedStudents.map((item) => item.clazzId).join(),
        className: selectedStudents.map((item) => item.clazzName).join(),
        studentCount: examTaskStudentObjectParamList.length,
        examTaskStudentObjectParamList,
        isSelectStudent,
        ...this.getBackupCount(examTaskStudentObjectParamList.length),
      });
      this.tableData.push(tableRow);

      this.updatePackageInfos();
    },
    toDelete(index) {
      this.tableData.splice(index, 1);
      this.updatePackageInfos();
    },
    toViewStudent(row) {
      // console.log(row);
      this.curRow = row;
      this.$refs.PreviewTaskStudent.open();
    },
    previewStudentClosed() {
      const studentCount = this.curRow.examTaskStudentObjectParamList.filter(
        (item) => item.enable
      ).length;

      Object.assign(this.curRow, {
        ...this.getBackupCount(studentCount),
        studentCount,
      });
    },
    // import
    validError(errorData) {
      this.$message.error(errorData.message);
    },
    uploadSuccess(res) {
      this.studentUploaded = true;
      this.$message.success("导入成功！");

      this.tableData = res.data.map((item) => {
        const initRow = this.getInitTableRow();
        let examTaskStudentObjectParamList = [];
        item.examTaskStudentObjectResultList.forEach((elem) => {
          elem.studentInfoList.forEach((std) => {
            examTaskStudentObjectParamList.push({
              ...std,
              studentClazzType: elem.studentClazzType,
              id: `${elem.clazzId}_${std.studentId}`,
            });
          });
        });
        let tableRow = this.$objAssign(initRow, {
          classId: item.examTaskStudentObjectResultList
            .map((item) => item.clazzId)
            .join(),
          className: item.examTaskStudentObjectResultList
            .map((item) => item.clazzName)
            .join(),
          examRoom: item.examRoom,
          examPlace: item.examPlace,
          studentCount: examTaskStudentObjectParamList.length,
          examTaskStudentObjectParamList,
          ...this.getBackupCount(examTaskStudentObjectParamList.length),
        });

        return tableRow;
      });
      this.updatePackageInfos();
    },
    // model2 select class
    toSelectClass() {
      if (!this.infoExamTask.courseCode) {
        this.$message.error("请先选择课程");
        return;
      }

      this.disabledStudentIds = [];
      this.showStudent = false;
      this.$refs.ModifyExamTaskStudent.open();
    },
  },
};
</script>
