<template>
  <el-dialog
    class="modify-print-plan"
    :visible.sync="modalIsShow"
    :title="title"
    top="10px"
    width="700px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    append-to-body
    @open="visibleChange"
  >
    <el-form
      ref="modalFormComp"
      label-width="130px"
      :rules="rules"
      :model="modalForm"
    >
      <div class="part-box">
        <h4 class="part-box-tips">基本信息：</h4>
        <el-form-item prop="name" label="印刷计划名称：">
          <el-input
            v-model.trim="modalForm.name"
            clearable
            placeholder="请输入"
            :disabled="!editable"
          ></el-input>
        </el-form-item>
        <el-form-item prop="examStartTime" label="考试时间：">
          <el-date-picker
            v-model="createTime"
            type="datetimerange"
            range-separator="至"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            value-format="timestamp"
            align="right"
            unlink-panels
            :disabled="!editable"
            @change="dateChange"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item prop="semesterId" label="使用学期：">
          <semester-select
            v-model="modalForm.semesterId"
            class="width-full"
            :disabled="!editable"
          ></semester-select>
        </el-form-item>
        <el-form-item prop="examId" label="考试：">
          <exam-select
            v-model="modalForm.examId"
            :semester-id="modalForm.semesterId"
            :category="modalForm.category"
            class="width-full"
            @change="examChange"
          ></exam-select>
        </el-form-item>
      </div>

      <div class="part-box">
        <h4 class="part-box-tips">
          试卷&题卡印品：
          <el-checkbox
            v-model="allSelected"
            label="全选"
            disabled
            @change="selectAll"
          ></el-checkbox>
        </h4>
        <el-form-item prop="printContent" label="试卷、题卡：">
          <el-checkbox-group
            v-model="modalForm.printContent"
            disabled
            @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="请选择"
            disabled
          >
            <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"
            disabled
          ></exam-backup-edit>
        </el-form-item>
        <el-form-item
          v-if="contentIncludesPaper"
          prop="drawRule"
          label="抽卷规则："
        >
          <el-radio-group v-model="modalForm.drawRule" disabled>
            <el-radio
              v-for="(val, key) in DRAW_RULE_TYPE"
              :label="key"
              :key="key"
              >{{ val }}</el-radio
            >
          </el-radio-group>
          <p class="tips-info">
            1.只抽取一次：不同印刷计划下，同一试卷编号下的卷型只能被抽取一次；
          </p>
          <p class="tips-info">
            2.可反复抽取：不同印刷计划下，同一试卷编号下的卷型可重复抽取，系统默认优先抽取未曝光卷型。
          </p>
        </el-form-item>
      </div>

      <div class="part-box">
        <h4 class="part-box-tips">其他印品：</h4>
        <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"
            disabled
            @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="请选择"
              disabled
            >
              <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"
              disabled
              style="width: 60px"
            ></el-input-number>
            <span>份</span>
          </div>
        </el-form-item>
      </div>

      <div class="part-box">
        <!-- <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"
            disabled
            @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="请选择"
              disabled
            >
              <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"
              disabled
              style="width: 60px"
            ></el-input-number>
            <span>份</span>
          </div>
        </el-form-item>
      </div>

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

    <div slot="footer">
      <el-button
        v-if="editable"
        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,
  EXAM_TYPE,
} from "@/constants/enumerate";
import { deepCopy } from "@/plugins/utils";
import { updatePrintPlan, printPlanTemplateList } from "../api";
import { examConfigQuery } from "../../base/api";
import ExamBackupEdit from "../../base/components/ExamBackupEdit.vue";

const initModalForm = {
  id: null,
  name: "",
  examStartTime: "",
  examEndTime: "",
  semesterId: "",
  examId: "",
  category: "FORMAL",
  printContent: [],
  backupMethod: "ROOM",
  backupCount: 1,
  drawRule: "ONE",
  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-print-plan",
  components: { ExamBackupEdit },
  props: {
    instance: {
      type: Object,
      default() {
        return {};
      },
    },
    editType: {
      type: String,
      default: "ADD",
      validator: (val) => ["ADD", "PREVIEW", "EDIT"].includes(val),
    },
  },
  computed: {
    isEdit() {
      return !!this.instance.id;
    },
    title() {
      const names = {
        ADD: "新增印刷计划",
        PREVIEW: "印刷计划详情",
        EDIT: "编辑印刷计划",
      };
      const infos = [names[this.editType], EXAM_TYPE[this.modalForm.category]];
      return infos.filter((item) => Boolean(item)).join("-");
    },
    editable() {
      return this.editType !== "PREVIEW";
    },
    contentIncludesPaper() {
      return this.modalForm.printContent.includes("PAPER");
    },
  },
  data() {
    // const printContentValidator = (rule, value, callback) => {
    //   if (value.includes("PAPER") && !value.includes("CARD")) {
    //     callback(new Error("选择了试卷，同时必须选择题卡"));
    //   } else {
    //     callback();
    //   }
    // };
    const backupMethodValidator = (rule, value, callback) => {
      if (!this.modalForm.printContent.length) {
        return callback();
      }
      if (!value) {
        return callback(new Error("请选择备份方式"));
      }
      if (!this.modalForm.backupCount) {
        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("必须选择一项印品"));
      }
    };
    return {
      modalIsShow: false,
      isSubmit: false,
      modalForm: deepCopy(initModalForm),
      createTime: [],
      PRINT_CONTENT_TYPE,
      DRAW_RULE_TYPE,
      PRINT_BACKUP_TYPE,
      PAPER_BACKUP_TYPE,
      TEMPLATE_CLASSIFY,
      variableContent: [],
      ordinaryContent: [],
      templateSources: {},
      oldPrintContent: [],
      allSelected: false,
      rules: {
        name: [
          {
            required: true,
            message: "请输入印刷计划名称，长度不要超过50个字符",
            max: 50,
            trigger: "change",
          },
        ],
        examStartTime: [
          {
            required: true,
            message: "请设置考试时间",
            trigger: "change",
          },
        ],
        semesterId: [
          {
            required: true,
            message: "请选择使用学期",
            trigger: "change",
          },
        ],
        examId: [
          {
            required: true,
            message: "请选择使用考试",
            trigger: "change",
          },
        ],
        printContent: [
          {
            required: false,
            // validator: printContentValidator,
            trigger: "change",
          },
        ],
        backupMethod: [
          {
            required: true,
            validator: backupMethodValidator,
            trigger: "change",
          },
        ],
        drawRule: [
          {
            required: true,
            message: "请选择抽卷规则",
            trigger: "change",
          },
        ],
        selectedPrint: [
          {
            required: false,
            validator: selectedPrintValidator,
            trigger: "change",
          },
        ],
      },
    };
  },
  mounted() {
    this.getTemplates();
  },
  methods: {
    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;
    },
    selectAll(selected) {
      if (selected) {
        this.modalForm.printContent = ["PAPER", "CARD"];
        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 < 2;

      const selecteds = [vNotSelected, oNotSelected, pNotSelected];

      this.allSelected = !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");
    },
    printContentChange(val) {
      const isSelectPaper =
        !this.oldPrintContent.includes("PAPER") && val.includes("PAPER");
      if (isSelectPaper && !val.includes("CARD")) {
        val.push("CARD");
      }
      this.oldPrintContent = val;
    },
    initData(val) {
      if (val.id) {
        this.createTime = [val.examStartTime, val.examEndTime];
        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 = 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 = 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 = val.printContent
          ? val.printContent.split(",")
          : [];
        this.checkSelectAll();
      } else {
        this.allSelected = false;
        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;
        this.createTime = [];
      }
    },
    visibleChange() {
      this.initData(this.instance);

      this.$nextTick(() => {
        this.$refs.modalFormComp.clearValidate();
      });
    },
    cancel() {
      this.modalIsShow = false;
    },
    open() {
      this.modalIsShow = true;
    },
    async examChange() {
      if (!this.modalForm.examId) return;
      const data = await examConfigQuery({
        examId: this.modalForm.examId,
        pageNumber: 1,
        pageSize: 10,
      });
      this.initExamConfig(data.records[0]);
    },
    initExamConfig(val) {
      // console.log(val);
      if (!val) return;
      const data = this.$objAssign(
        {
          backupMethod: "ROOM",
          backupCount: 1,
          drawRule: "ONE",
        },
        val
      );
      Object.assign(this.modalForm, data);
      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.checkSelectAll();
    },
    dateChange() {
      if (this.createTime) {
        this.modalForm.examStartTime = this.createTime[0];
        this.modalForm.examEndTime = this.createTime[1];
      } else {
        this.modalForm.examStartTime = "";
        this.modalForm.examEndTime = "";
      }
    },
    async submit() {
      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
      if (!valid) return;

      if (this.isSubmit) return;
      this.isSubmit = true;
      const datas = { ...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,
        };
      };
      datas.variableContent = JSON.stringify(
        this.modalForm.variableContent.map(transformInfo)
      );
      datas.ordinaryContent = JSON.stringify(
        this.modalForm.ordinaryContent.map(transformInfo)
      );

      const data = await updatePrintPlan(datas).catch(() => {});
      this.isSubmit = false;
      if (!data) return;

      this.$message.success("保存成功！");
      this.$emit("modified");
      this.cancel();
    },
  },
};
</script>
