<template>
  <div class="school-set-stdno part-box part-box-pad">
    <el-form
      ref="modalFormComp"
      :model="modalForm"
      :rules="rules"
      label-width="180px"
    >
      <el-form-item prop="digit" label="学号位数：">
        <el-input-number
          v-model="modalForm.digit"
          :min="5"
          :max="15"
          :step="1"
          step-strictly
          :controls="false"
          style="width: 80px"
        ></el-input-number>
        <span class="tips-info">（如：10）</span>
      </el-form-item>
      <el-form-item label="学号是否包含字母：">
        <el-radio-group v-model="modalForm.containsLetter">
          <el-radio :label="true">是</el-radio>
          <el-radio :label="false">否</el-radio>
        </el-radio-group>
      </el-form-item>
      <template v-if="modalForm.containsLetter">
        <el-form-item prop="columns" label="字母所在列：">
          <el-select
            v-model="modalForm.columns"
            placeholder="请选择"
            multiple
            style="width: 200px"
            @change="columnChange"
          >
            <el-option
              v-for="n in modalForm.digit"
              :key="n"
              :value="n"
              :label="n"
            ></el-option>
          </el-select>
          <div v-if="modalForm.relationList.length" style="margin-top: 10px">
            <el-radio-group
              v-model="curSelectColumn"
              @change="selectColumnChange"
            >
              <el-radio-button
                v-for="(item, index) in modalForm.relationList"
                :key="index"
                :label="item.columnIndex"
                >第{{ item.columnIndex }}列</el-radio-button
              >
            </el-radio-group>
          </div>
        </el-form-item>
        <template v-if="modalForm.columns.length">
          <el-form-item prop="columnChar" label="使用字母：">
            <el-input
              v-model.trim="modalForm.columnChar"
              plachholder="请输入"
              style="width: 200px"
              @change="columnCharChange"
            ></el-input>
            <p class="tips-info">说明：请输入大写字母，最多输入10个字母</p>
          </el-form-item>
          <el-form-item label="字母映射关系：">
            <table
              v-if="curSelectColumnLetters.length"
              class="table table-tiny"
              style="width: 200px"
            >
              <tr>
                <th>使用字母</th>
                <th>映射数字</th>
              </tr>
              <tr v-for="(item, index) in curSelectColumnLetters" :key="index">
                <td>{{ item }}</td>
                <td>{{ index }}</td>
              </tr>
            </table>
          </el-form-item>
        </template>
      </template>
    </el-form>

    <!-- stdno view -->
    <div class="card-head-body">
      <h3 class="mb-1">答题卡学号区域预览：</h3>
      <head-stdno :data="headStdnoData"></head-stdno>
    </div>
  </div>
</template>

<script>
import { deepCopy } from "@/plugins/utils";
import { schoolSetStdnoInfo, schoolSetStdnoUpdate } from "../../api";
import HeadStdno from "../../../../../card/elements/card-head/cardHeadSpin/HeadStdno.vue";

export default {
  name: "school-set-stdno",
  components: { HeadStdno },
  props: {
    school: {
      type: Object,
      default() {
        return {};
      },
    },
  },
  data() {
    return {
      loading: false,
      stdnoInfo: [],
      modalForm: {
        digit: 10,
        containsLetter: false,
        columns: [],
        relationList: [],
        columnChar: "",
      },
      cachedModalForm: null,
      curSelectColumn: -1,
      curSelectColumnLetters: [],
      rules: {
        digit: [
          {
            required: true,
            message: "请输入学号位数",
            trigger: "change",
          },
        ],
        columns: [
          {
            required: true,
            validator: (rule, value, callback) => {
              if (!value || !value.length) {
                return callback(new Error(`请选择字母所在列`));
              }
              callback();
            },
            trigger: "change",
          },
        ],
        columnChar: [
          {
            required: true,
            validator: (rule, value, callback) => {
              if (!/^[A-Z]{1,10}$/.test(value)) {
                return callback(new Error(`只能输入大写字母，长度不超过10`));
              }

              const chars = Array.from(new Set((value || "").split(""))).join(
                ""
              );
              if (chars !== value) {
                return callback(new Error(`大写字母不可重复`));
              }

              callback();
            },
            trigger: "change",
          },
        ],
      },
    };
  },
  computed: {
    headStdnoData() {
      return {
        examNumberStyle: "FILL",
        fillNumber: this.modalForm.digit,
        containsLetter: this.modalForm.containsLetter,
        relationList: this.modalForm.relationList,
      };
    },
  },
  watch: {
    modalForm: {
      deep: true,
      handler() {
        const isChanged = this.checkConfigChanged();
        this.$emit("config-changed", isChanged);
      },
    },
  },
  mounted() {
    this.initData();
  },
  methods: {
    async initData() {
      const data = await schoolSetStdnoInfo(this.school.id);
      this.stdnoInfo = data.result;
      const config = data.result[0].value;
      if (!config) {
        this.modalForm = {
          digit: 10,
          containsLetter: false,
          columns: [],
          relationList: [],
          columnChar: "",
        };
        this.updateCachedModalForm();
        return;
      }

      this.modalForm = {
        digit: config.digit || 10,
        containsLetter: config.containsLetter,
        columns: [],
        relationList: config.relationList || [],
        columnChar: "",
      };
      this.modalForm.columns = this.modalForm.relationList.map(
        (item) => item.columnIndex
      );
      if (this.modalForm.columns.length) {
        this.curSelectColumn = this.modalForm.columns[0];
        this.selectColumnChange();
      }

      this.updateCachedModalForm();
    },
    updateCachedModalForm() {
      this.cachedModalForm = JSON.parse(JSON.stringify(this.modalForm));
    },
    checkConfigChanged() {
      if (!this.cachedModalForm) return false;
      return (
        JSON.stringify(this.modalForm) !== JSON.stringify(this.cachedModalForm)
      );
    },
    columnChange() {
      const relationList = this.modalForm.relationList || [];
      const relationMap = {};
      relationList.forEach((item) => {
        relationMap[item.columnIndex] = item.letters;
      });

      this.modalForm.columns.sort((a, b) => a - b);

      this.modalForm.relationList = this.modalForm.columns.map(
        (columnIndex) => {
          const letters = relationMap[columnIndex] || [];
          return {
            columnIndex,
            letters,
          };
        }
      );

      if (
        this.modalForm.columns.length &&
        !this.modalForm.columns.includes(this.curSelectColumn)
      ) {
        this.curSelectColumn = this.modalForm.columns[0];
        this.selectColumnChange();
      }
    },
    selectColumnChange() {
      const curRelation = this.modalForm.relationList.find(
        (item) => item.columnIndex === this.curSelectColumn
      );
      this.modalForm.columnChar = curRelation
        ? curRelation.letters.join("")
        : "";
      this.curSelectColumnLetters = curRelation ? curRelation.letters : [];
    },
    validateField(field) {
      return new Promise((resolve, reject) => {
        this.$refs.modalFormComp.validateField(field, (unvalid) => {
          if (unvalid) {
            reject(false);
          } else {
            resolve(true);
          }
        });
      });
    },
    async columnCharChange() {
      const res = await this.validateField("columnChar").catch(() => {});
      if (!res) {
        this.curSelectColumnLetters = [];
        return;
      }

      const curRelation = this.modalForm.relationList.find(
        (item) => item.columnIndex === this.curSelectColumn
      );
      if (!curRelation) return;
      curRelation.letters = this.modalForm.columnChar.split("");
      this.curSelectColumnLetters = curRelation.letters;
    },
    async confirm() {
      const valid = await this.$refs.modalFormComp.validate().catch(() => {});
      if (!valid) return;

      if (this.loading) return;
      this.loading = true;

      const val = {
        digit: this.modalForm.digit,
        containsLetter: this.modalForm.containsLetter,
        relationList: this.modalForm.containsLetter
          ? this.modalForm.relationList
          : [],
      };

      const datas = deepCopy(this.stdnoInfo);
      datas[0].value = val;
      const res = await schoolSetStdnoUpdate({
        param: datas,
        schoolId: this.school.id,
      }).catch(() => {});
      this.loading = false;

      if (!res) return;
      this.updateCachedModalForm();
      this.$emit("config-changed", false);
      this.initData();
    },
  },
};
</script>

<style lang="scss" scoped>
.school-set-stdno {
  width: 1000px;
  display: flex;
  justify-content: space-between;
  .el-form {
    flex-grow: 2;
  }

  .card-head-body {
    width: 340px;
    flex-grow: 0;
    flex-shrink: 0;
  }

  .head-stdno {
    border: 1px solid #000;
    height: 240px;
  }
}
</style>
