<template>
  <el-dialog
    class="modify-exam-config-detail"
    :visible.sync="modalIsShow"
    :title="title"
    top="0"
    width="800px"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    append-to-body
    @opened="dialogOpened"
    @close="dialogClose"
  >
    <el-form
      ref="modalFormComp"
      label-width="130px"
      :rules="rules"
      :model="modalForm"
    >
      <el-form-item prop="cardRuleId" label="题卡规则：">
        <card-rule-select
          ref="CardRuleSelect"
          v-model.trim="modalForm.cardRuleId"
          placeholder="请选择"
          clearable
        ></card-rule-select>
        <div class="tips-info">
          <p>说明：</p>
          <p>
            1、若选择全部通卡，则命题老师只能选择通卡，若选择题卡规则，则专卡和通卡均可选择
          </p>
          <p>
            2、若选择题卡规则，命题老师在该考试下自主创建题卡时，版头样式及版头内容为该规则对应样式及版头。
          </p>
        </div>
      </el-form-item>

      <div class="part-box">
        <h4 class="part-box-tips">
          试卷&题卡印品：
          <el-checkbox
            v-show="infoShow"
            v-model="allSelected"
            label="全选"
            @change="selectAll"
          ></el-checkbox>
        </h4>
        <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>
          <el-input-number
            class="mr-1"
            v-model="modalForm.backupCount"
            size="small"
            :min="0"
            :max="200"
            :step="1"
            step-strictly
            :controls="false"
            style="width: 60px"
          ></el-input-number>
          <span>份</span>
        </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">
        <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"
            @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
              v-model="item.backupCount"
              class="mr-1"
              size="small"
              :min="1"
              :max="200"
              :step="1"
              step-strictly
              :controls="false"
              style="width: 60px"
            ></el-input-number>
            <span>份</span>
          </div>
        </el-form-item>
      </div>

      <div class="part-box" v-show="infoShow">
        <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
              v-model="item.backupCount"
              class="mr-1"
              size="small"
              :min="1"
              :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>

      <el-form-item prop="orgIds" label="适用范围：">
        <!-- <select-orgs v-model="modalForm.orgIds" ref="SelectOrgs"></select-orgs> -->
        <div
          v-if="orgDataReady"
          class="select-orgs part-box part-box-pad part-box-border"
        >
          <el-tree
            :data="orgs"
            show-checkbox
            default-expand-all
            node-key="id"
            ref="MenuTree"
            :props="defaultProps"
            check-on-click-node
            :expand-on-click-node="false"
            @check-change="checkChange"
          >
          </el-tree>
        </div>
      </el-form-item>
    </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
} from "@/constants/enumerate";
import { deepCopy } from "@/plugins/utils";
import { updateExamConfig, listOrgsByExamId, organizationList } from "../api";
import { printPlanTemplateList } from "../../print/api";

const initModalForm = {
  id: null,
  examId: null,
  cardRuleId: "",
  orgIds: [],
  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-exam-config-detail",
  props: {
    instance: {
      type: Object,
      default() {
        return {};
      }
    }
  },
  computed: {
    isEdit() {
      return !!this.instance.id;
    },
    title() {
      return (this.isEdit ? "编辑" : "新增") + "考试配置";
    },
    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("必须选择一项印品"));
      }
    };

    return {
      modalIsShow: false,
      isSubmit: false,
      modalForm: deepCopy(initModalForm),
      PRINT_CONTENT_TYPE,
      DRAW_RULE_TYPE,
      PRINT_BACKUP_TYPE,
      PAPER_BACKUP_TYPE,
      TEMPLATE_CLASSIFY,
      variableContent: [],
      ordinaryContent: [],
      templateSources: {},
      oldPrintContent: [],
      usedOrgIds: [],
      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"
          }
        ],
        orgIds: [
          {
            required: true,
            validator: (rule, value, callback) => {
              if (value.length) {
                callback();
              } else {
                callback(new Error("请选择适用范围"));
              }
            },
            trigger: "change"
          }
        ]
      },
      // org select
      orgDataReady: false,
      orgs: [],
      leafOrgIds: [],
      defaultProps: {
        label: "name"
      }
    };
  },
  mounted() {
    this.getTemplates();
    this.getOrgs();
  },
  methods: {
    async dialogOpened() {
      const data = await listOrgsByExamId({
        examId: this.instance.examId,
        id: this.instance.id
      });
      this.usedOrgIds = data || [];
      this.setDisabledOrgs(this.usedOrgIds);
      this.orgDataReady = true;

      this.$nextTick(() => {
        this.initData(this.instance);
      });
    },
    dialogClose() {
      this.orgDataReady = false;
    },
    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
          };
        };
        this.modalForm.variableContent = JSON.parse(val.variableContent).map(
          transformInfo
        );
        this.modalForm.ordinaryContent = JSON.parse(val.ordinaryContent).map(
          transformInfo
        );
        this.modalForm.printContent = JSON.parse(val.printContent);
        this.modalForm.orgIds = val.orgs.map(item => item.id);
      } 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;
      }

      this.setCheckedNode(this.modalForm.orgIds);

      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.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;
      console.log(valid);

      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.title + "成功！");
      this.$emit("modified");
      this.cancel();
    },
    // org select
    async getOrgs() {
      const orgs = await organizationList();
      this.orgs = orgs || [];

      if (this.orgs.length) {
        this.orgs[0].children.sort((a, b) => {
          if (a.type === "PRINTING_HOUSE") return 1;
          if (b.type === "PRINTING_HOUSE") return -1;

          return 0;
        });
      }

      let leafOrgIds = [];
      const getLeafOrg = orgs => {
        orgs.forEach(org => {
          org.disabled = false;
          if (org["children"] && org["children"].length) {
            getLeafOrg(org.children);
          } else {
            leafOrgIds.push(org.id);
          }
        });
      };
      getLeafOrg(this.orgs);
      this.leafOrgIds = leafOrgIds;
    },
    setDisabledOrgs(disabledOrgIds) {
      const updateInfo = orgs => {
        orgs.forEach(org => {
          org.disabled = disabledOrgIds.includes(org.id);
          if (org["children"] && org["children"].length) {
            updateInfo(org.children);
          }
        });
      };
      updateInfo(this.orgs);
    },
    setCheckedNode(selectedIds) {
      const leafSelectedIds = selectedIds.filter(id =>
        this.leafOrgIds.includes(id)
      );
      this.$refs.MenuTree.setCheckedKeys(leafSelectedIds);
    },
    checkChange() {
      this.modalForm.orgIds = this.$refs.MenuTree.getCheckedKeys();
      this.$refs.modalFormComp.validateField("orgIds");
    }
  }
};
</script>
