<template>
  <el-dialog
    class="modify-exam-config-detail"
    :visible.sync="modalIsShow"
    top="0"
    width="800px"
    title="考试配置"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    append-to-body
    @opened="dialogOpened"
  >
    <el-form
      ref="modalFormComp"
      label-width="140px"
      :rules="rules"
      :model="modalForm"
    >
      <el-form-item label="是否启用入库审核：" required>
        <el-switch v-model="modalForm.review" inactive-color="#dcdfe6">
        </el-switch>
      </el-form-item>
      <el-form-item v-if="modalForm.review" label="强制审核内容：" required>
        <el-checkbox-group v-model="modalForm.auditContent">
          <el-checkbox
            v-for="(val, key) in PRINT_CONTENT_TYPE"
            :key="key"
            :label="key"
            >{{ val }}</el-checkbox
          >
        </el-checkbox-group>
      </el-form-item>
      <el-form-item label="提交印刷方式：" required>
        <el-radio-group v-model="modalForm.printMethod">
          <el-radio
            v-for="(val, key) in CONFIRM_PRINT_TYPE"
            :key="key"
            :label="key"
            >{{ val }}</el-radio
          >
        </el-radio-group>
      </el-form-item>
      <el-form-item prop="cardRuleId" label="题卡规则：">
        <card-rule-select
          ref="CardRuleSelect"
          v-model.trim="modalForm.cardRuleId"
          placeholder="请选择"
          clearable
          :exam-id="modalForm.examId"
          :watch-response="false"
        ></card-rule-select>
        <div class="tips-info">
          <p>说明：</p>
          <p>
            1、若选择全部通卡，则命题老师只能选择通卡，若选择题卡规则，则专卡和通卡均可选择
          </p>
          <p>
            2、若选择题卡规则，命题老师在该考试下自主创建题卡时，版头样式及版头内容为该规则对应样式及版头。
          </p>
        </div>
      </el-form-item>

      <div class="part-box">
        <div class="config-title">
          <h4>试卷&题卡印品：</h4>
          <el-checkbox
            v-show="infoShow"
            v-model="allSelected"
            label="全选"
            @change="selectAll"
          ></el-checkbox>
        </div>
        <el-form-item prop="printContent" label="试卷、题卡：">
          <el-checkbox-group
            v-model="modalForm.printContent"
            @change="() => checkSelectAll()"
          >
            <el-checkbox
              v-for="(val, key) in PRINT_CONTENT_TYPE"
              :key="key"
              :label="key"
              >{{ val }}</el-checkbox
            >
          </el-checkbox-group>
        </el-form-item>
        <el-form-item
          v-if="modalForm.printContent.length"
          prop="backupMethod"
          label="备用数量："
        >
          <el-select
            v-model="modalForm.backupMethod"
            class="mr-2"
            size="small"
            placeholder="请选择"
          >
            <el-option
              v-for="(val, key) in PAPER_BACKUP_TYPE"
              :key="key"
              :value="key"
              :label="val"
            ></el-option>
          </el-select>
          <exam-backup-edit v-model="modalForm.backupCount"></exam-backup-edit>
        </el-form-item>
        <el-form-item
          v-show="infoShow"
          v-if="contentIncludesPaper"
          prop="drawRule"
          label="抽卷规则："
        >
          <el-radio-group v-model="modalForm.drawRule">
            <el-radio
              v-for="(val, key) in DRAW_RULE_TYPE"
              :label="key"
              :key="key"
              >{{ val }}</el-radio
            >
          </el-radio-group>
          <div class="tips-info">
            <p>说明：</p>
            <p>
              1.只抽取一次：不同印刷计划下，同一试卷编号下的卷型只能被抽取一次；
            </p>
            <p>
              2.可反复抽取：不同印刷计划下，同一试卷编号下的卷型可重复抽取，系统默认优先抽取未曝光卷型。
            </p>
          </div>
        </el-form-item>
      </div>

      <div class="part-box" v-show="infoShow">
        <div class="config-title">
          <h4>其他印品：</h4>
        </div>
        <el-form-item
          v-for="(item, index) in modalForm.variableContent"
          :key="item.type"
          :label="`${TEMPLATE_CLASSIFY[item.type]}：`"
          :prop="`variableContent.${index}.templateId`"
          :rules="{
            required: false,
            validator: templateValidator,
            trigger: 'change',
          }"
          :required="!!item.templateId.length"
        >
          <el-checkbox-group
            v-model="item.templateId"
            @change="(vals) => tempChange(vals, `variableContent.${index}`)"
          >
            <el-checkbox
              v-for="temp in templateSources[item.type]"
              :label="temp.id"
              :key="temp.id"
              >{{ temp.name }}</el-checkbox
            >
          </el-checkbox-group>
          <div v-if="item.templateId.length">
            <el-select
              v-model="item.backupMethod"
              class="mr-2"
              size="small"
              placeholder="请选择"
            >
              <el-option
                v-for="(val, key) in PRINT_BACKUP_TYPE"
                :key="key"
                :value="key"
                :label="val"
              ></el-option>
            </el-select>
            <el-input-number
              class="mr-1"
              v-model="item.backupCount"
              size="small"
              :min="0"
              :max="200"
              :step="1"
              step-strictly
              :controls="false"
              style="width: 60px"
            ></el-input-number>
            <span>份</span>
          </div>
        </el-form-item>
        <!-- <h4 class="part-box-tips">普通印品：</h4> -->
        <el-form-item
          v-for="(item, index) in modalForm.ordinaryContent"
          :key="item.type"
          :label="`${TEMPLATE_CLASSIFY[item.type]}：`"
          :prop="`ordinaryContent.${index}.templateId`"
          :rules="{
            required: false,
            validator: templateValidator,
            trigger: 'change',
          }"
          :required="!!item.templateId.length"
        >
          <el-checkbox-group
            v-model="item.templateId"
            @change="(vals) => tempChange(vals, `ordinaryContent.${index}`)"
          >
            <el-checkbox
              v-for="temp in templateSources[item.type]"
              :label="temp.id"
              :key="temp.id"
              >{{ temp.name }}</el-checkbox
            >
          </el-checkbox-group>
          <div v-if="item.templateId.length">
            <el-select
              v-model="item.backupMethod"
              class="mr-2"
              size="small"
              placeholder="请选择"
            >
              <el-option
                v-for="(val, key) in PRINT_BACKUP_TYPE"
                :key="key"
                :value="key"
                :label="val"
              ></el-option>
            </el-select>
            <el-input-number
              class="mr-1"
              v-model="item.backupCount"
              size="small"
              :min="0"
              :max="200"
              :step="1"
              step-strictly
              :controls="false"
              style="width: 60px"
            ></el-input-number>
            <span>份</span>
          </div>
        </el-form-item>
      </div>

      <el-form-item prop="selectedPrint"></el-form-item>

      <div class="part-box">
        <div class="config-title">
          <h4>输出印品配置：</h4>
        </div>
        <el-form-item prop="outputFileType" label="输出文件类型：">
          <el-checkbox-group v-model="modalForm.outputFileType">
            <el-checkbox
              v-for="(val, key) in EXAM_PDF_TYPE"
              :label="key"
              :key="key"
            >
              {{ val }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
      </div>
    </el-form>

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

<script>
import {
  PRINT_CONTENT_TYPE,
  DRAW_RULE_TYPE,
  PRINT_BACKUP_TYPE,
  PAPER_BACKUP_TYPE,
  TEMPLATE_CLASSIFY,
  CONFIRM_PRINT_TYPE,
  EXAM_PDF_TYPE,
} from "@/constants/enumerate";
import { deepCopy } from "@/plugins/utils";
import { examConfigQuery, updateExamConfig } from "../api";
import { printPlanTemplateList } from "../../print/api";
import ExamBackupEdit from "./ExamBackupEdit.vue";

const initModalForm = {
  id: null,
  examId: null,
  review: true,
  auditContent: [],
  printMethod: "AUTO",
  cardRuleId: "",
  printContent: [],
  backupMethod: "ROOM",
  backupCount: 1,
  drawRule: "ONE",
  outputFileType: [],
  variableContent: [
    {
      type: "SIGN",
      templateId: [],
      oldTemplateId: [],
      backupMethod: "ROOM",
      backupCount: 1,
    },
    {
      type: "PACKAGE",
      templateId: [],
      oldTemplateId: [],
      backupMethod: "ROOM",
      backupCount: 1,
    },
  ],
  ordinaryContent: [
    {
      type: "CHECK_IN",
      templateId: [],
      oldTemplateId: [],
      backupMethod: "ROOM",
      backupCount: 1,
    },
  ],
};

export default {
  name: "modify-exam-config-detail",
  components: { ExamBackupEdit },
  props: {
    exam: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  computed: {
    contentIncludesPaper() {
      return this.modalForm.printContent.includes("PAPER");
    },
  },
  data() {
    const printContentValidator = (rule, value, callback) => {
      if (!this.modalForm.printContent.length) {
        return callback(new Error("请选择试卷、题卡"));
      }

      callback();
    };
    const backupMethodValidator = (rule, value, callback) => {
      if (!this.modalForm.printContent.length) {
        return callback();
      }
      if (!value) {
        return callback(new Error("请选择备份方式"));
      }
      if (!this.modalForm.backupCount && this.modalForm.backupCount !== 0) {
        return callback(new Error("请输入备份数量"));
      }

      callback();
    };
    const selectedPrintValidator = (rule, value, callback) => {
      const printInfo = [
        ...this.modalForm.variableContent,
        ...this.modalForm.ordinaryContent,
      ];
      const hasPrintInfo = printInfo.some((item) => item.templateId.length);

      if (hasPrintInfo || this.modalForm.printContent.length) {
        callback();
      } else {
        callback(new Error("必须选择一项印品"));
      }
    };

    const pdfTypesValidator = (rule, value, callback) => {
      if (!value.length) {
        return callback(new Error("请选择输出文件类型"));
      }

      callback();
    };

    return {
      modalIsShow: false,
      isSubmit: false,
      modalForm: deepCopy(initModalForm),
      PRINT_CONTENT_TYPE,
      DRAW_RULE_TYPE,
      PRINT_BACKUP_TYPE,
      PAPER_BACKUP_TYPE,
      CONFIRM_PRINT_TYPE,
      TEMPLATE_CLASSIFY,
      EXAM_PDF_TYPE,
      variableContent: [],
      ordinaryContent: [],
      templateSources: {},
      oldPrintContent: [],
      allSelected: false,
      infoShow: true,
      rules: {
        cardRuleId: [
          {
            required: true,
            message: "请选择题卡规则",
            trigger: "change",
          },
        ],
        printContent: [
          {
            required: true,
            validator: printContentValidator,
            trigger: "change",
          },
        ],
        backupMethod: [
          {
            required: true,
            validator: backupMethodValidator,
            trigger: "change",
          },
        ],
        drawRule: [
          {
            required: true,
            message: "请选择抽卷规则",
            trigger: "change",
          },
        ],
        selectedPrint: [
          {
            required: false,
            validator: selectedPrintValidator,
            trigger: "change",
          },
        ],
        outputFileType: [
          {
            required: true,
            validator: pdfTypesValidator,
            trigger: "change",
          },
        ],
      },
    };
  },
  mounted() {
    this.getTemplates();
  },
  methods: {
    async dialogOpened() {
      const data = await examConfigQuery({
        examId: this.exam.id,
        pageNumber: 1,
        pageSize: 10,
      });
      let val = data.records[0] || {};
      val.examId = this.exam.id;
      this.initData(val);
      this.$nextTick(() => {
        this.$refs.CardRuleSelect.search();
      });
    },
    cancel() {
      this.modalIsShow = false;
    },
    open() {
      this.modalIsShow = true;
    },
    async getTemplates() {
      const data = await printPlanTemplateList();
      const templateSources = {};
      const templates = [...data.variable, ...data.ordinary];
      templates.forEach((item) => {
        templateSources[item.type] = item.template;
      });
      this.templateSources = templateSources;
    },
    initData(val) {
      if (val.id) {
        this.modalForm = this.$objAssign(deepCopy(initModalForm), val);
        const transformInfo = (item) => {
          const templateIds = item.templateId ? [item.templateId] : [];
          return {
            type: item.type,
            templateId: templateIds,
            oldTemplateId: templateIds,
            backupMethod: item.backupMethod,
            backupCount: item.backupCount,
          };
        };
        const initModalFormContent = deepCopy(initModalForm);
        const variableContent = JSON.parse(val.variableContent);
        const variableContentTypes = variableContent.map((item) => item.type);
        this.modalForm.variableContent = [];
        initModalFormContent.variableContent.forEach((item) => {
          if (variableContentTypes.includes(item.type)) {
            const vitem = variableContent.find(
              (cont) => cont.type === item.type
            );
            this.modalForm.variableContent.push(transformInfo(vitem));
            return;
          }
          if (this.templateSources[item.type]) {
            this.modalForm.variableContent.push(item);
            return;
          }
        });

        const ordinaryContent = JSON.parse(val.ordinaryContent);
        const ordinaryContentTypes = ordinaryContent.map((item) => item.type);
        this.modalForm.ordinaryContent = [];
        initModalFormContent.ordinaryContent.forEach((item) => {
          if (ordinaryContentTypes.includes(item.type)) {
            const vitem = ordinaryContent.find(
              (cont) => cont.type === item.type
            );
            this.modalForm.ordinaryContent.push(transformInfo(vitem));
            return;
          }
          if (this.templateSources[item.type]) {
            this.modalForm.ordinaryContent.push(item);
            return;
          }
        });

        this.modalForm.printContent = JSON.parse(val.printContent || "[]");
        this.modalForm.auditContent = JSON.parse(val.auditContent || "[]");
        this.modalForm.outputFileType = JSON.parse(val.outputFileType || "[]");
      } else {
        let modalForm = this.$objAssign(deepCopy(initModalForm), val);
        modalForm.variableContent = modalForm.variableContent.filter(
          (item) => this.templateSources[item.type]
        );
        modalForm.ordinaryContent = modalForm.ordinaryContent.filter(
          (item) => this.templateSources[item.type]
        );
        this.modalForm = modalForm;
      }

      if (!this.checkHasSelect()) {
        this.allSelected = true;
        this.selectAll(this.allSelected);
      } else {
        this.checkSelectAll();
      }
    },
    getData() {
      let data = deepCopy(this.modalForm);
      const transformInfo = (item) => {
        const templateId = item.templateId.join();
        const template = this.templateSources[item.type].find(
          (temp) => temp.id === templateId
        );
        return {
          type: item.type,
          templateId,
          attachmentId: template && template.attachmentId,
          backupMethod: item.backupMethod,
          backupCount: item.backupCount,
        };
      };
      data.printContent = JSON.stringify(this.modalForm.printContent);
      data.auditContent = JSON.stringify(this.modalForm.auditContent);
      data.outputFileType = JSON.stringify(this.modalForm.outputFileType);
      data.variableContent = JSON.stringify(
        this.modalForm.variableContent.map(transformInfo)
      );
      data.ordinaryContent = JSON.stringify(
        this.modalForm.ordinaryContent.map(transformInfo)
      );

      return data;
    },
    selectAll(selected) {
      if (selected) {
        this.modalForm.printContent = Object.keys(this.PRINT_CONTENT_TYPE);
        this.modalForm.variableContent.forEach((item) => {
          if (item.templateId && item.templateId.length) return;

          const source = this.templateSources[item.type][0];
          item.templateId = source && [source.id];
          item.oldTemplateId = source && [source.id];
        });
        this.modalForm.ordinaryContent.forEach((item) => {
          if (item.templateId && item.templateId.length) return;

          const source = this.templateSources[item.type][0];
          item.templateId = source && [source.id];
          item.oldTemplateId = source && [source.id];
        });
      } else {
        this.modalForm.printContent = [];
        this.modalForm.variableContent.forEach((item) => {
          item.templateId = [];
          item.oldTemplateId = [];
        });
        this.modalForm.ordinaryContent.forEach((item) => {
          item.templateId = [];
          item.oldTemplateId = [];
        });
      }
    },
    checkSelectAll() {
      const vNotSelected = this.modalForm.variableContent.some(
        (item) => !item.templateId.length
      );
      const oNotSelected = this.modalForm.ordinaryContent.some(
        (item) => !item.templateId.length
      );
      const pNotSelected =
        this.modalForm.printContent.length <
        Object.keys(this.PRINT_CONTENT_TYPE).length;

      const selecteds = [vNotSelected, oNotSelected, pNotSelected];

      this.allSelected = !selecteds.some((item) => item);
    },
    checkHasSelect() {
      const vSelected = this.modalForm.variableContent.some(
        (item) => item.templateId.length
      );
      const oSelected = this.modalForm.ordinaryContent.some(
        (item) => item.templateId.length
      );
      const pSelected = !!this.modalForm.printContent.length;

      const selecteds = [vSelected, oSelected, pSelected];

      return selecteds.some((item) => item);
    },
    templateValidator(rule, value, callback) {
      const [field, index] = rule.field.split(".");
      const val = this.modalForm[field][index];
      if (val.templateId.length) {
        if (!val.backupMethod) {
          return callback(new Error("请选择备份方式"));
        }
        if (!val.backupCount) {
          return callback(new Error("请输入备份数量"));
        }
        callback();
      } else {
        callback();
      }
    },
    tempChange(vals, name) {
      const [field, index] = name.split(".");
      const info = this.modalForm[field][index];
      const newVals = vals.filter((item) => !info.oldTemplateId.includes(item));
      info.templateId = newVals;
      info.oldTemplateId = newVals;

      this.checkSelectAll();
      this.$refs.modalFormComp.validateField("selectedPrint");
    },
    async submit() {
      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
      if (!valid) return;

      if (this.isSubmit) return;
      this.isSubmit = true;
      let datas = this.getData();
      const data = await updateExamConfig(datas).catch(() => {
        this.isSubmit = false;
      });

      if (!data) return;

      this.isSubmit = false;
      this.$message.success("编辑成功！");
      this.$emit("modified");
      this.cancel();
    },
  },
};
</script>
