import { CARD_VERSION } from "../enumerate";
import { deepCopy } from "../plugins/utils";

const initIndex = {
  question: 1,
  absent: 1,
  breach: 1,
  paperType: 1,
  examNumber: 1,
  selective: 1,
  pageNumber: 1,
};

/**
 * 格式文档：https://doc.qmth.com.cn/pages/viewpage.action?pageId=19661052
 */
export default {
  data() {
    return {
      fillAreaIndex: {
        ...initIndex,
      },
      VALID_ELEMENTS_FOR_EXTERNAL: [
        "LOCATOR",
        "BARCODE",
        "CARD_HEAD",
        "FILL_QUESTION",
        "FILL_LINE",
        "EXPLAIN",
        "COMPOSITION",
      ],
      curPageOffsetInfo: {},
      curPageDom: null,
    };
  },
  methods: {
    getFillAreaIndex(type) {
      return this.fillAreaIndex[type]++;
    },
    getElementHumpName(cont) {
      return cont
        .split("_")
        .map((item) => item[0] + item.substr(1).toLowerCase())
        .join("");
    },
    getPreviewElementById(id) {
      return document.getElementById(`preview-${id}`);
    },
    parsePageExchange(pages) {
      const npages = deepCopy(pages);
      // 单页题卡不显示页码涂块
      this.curPageOffsetInfo = document
        .getElementById(`preview-page-box-0`)
        .getBoundingClientRect();
      const pageNumberInfo =
        pages.length <= 2 ? null : this.getPageNumberInfo();

      npages.forEach((page, pindex) => {
        this.curPageDom = document.getElementById(`preview-page-box-${pindex}`);
        this.curPageOffsetInfo = this.curPageDom.getBoundingClientRect();

        let exchange = {
          card_type: 2,
          page_size: page.pageSize,
          page_image: "",
          locator: this.getLocatorInfo(this.curPageDom),
          fill_locator: [],
          check_area: {
            black_line: [],
            white_line: [],
          },
          barcode: [],
          qrcode: [],
          ocr_area: [],
          info_area: [],
          fill_area: [],
          answer_area: [],
          extension: {
            barcode: [],
            fill_area: [],
            ocr_area: [],
            qrcode: [],
          },
        };
        const elements = [
          page.globals,
          ...page.columns.map((column) => column.elements),
        ];

        elements.forEach((elemGroup) => {
          elemGroup.forEach((element) => {
            if (this.VALID_ELEMENTS_FOR_EXTERNAL.includes(element.type)) {
              const funcName = this.getElementHumpName(element.type);
              // console.log(funcName);
              const info = this[`get${funcName}Info`](element);
              Object.entries(info).forEach(([key, vals]) => {
                exchange[key] = exchange[key].concat(vals);
              });
            }
          });
        });

        if (!(pindex % 2) && pageNumberInfo) {
          let pnoInfo = deepCopy(pageNumberInfo);
          pnoInfo[0].index = this.getFillAreaIndex("pageNumber");
          exchange.fill_area = exchange.fill_area.concat(pnoInfo);
        }

        // 课程代码条码
        const extraInfo = this.getExtraInfo(this.curPageDom);
        Object.entries(extraInfo).forEach(([key, vals]) => {
          exchange.extension[key] = exchange.extension[key].concat(vals);
        });

        // 考生承诺书
        const uAreas = this.getUndertakingInfo(this.curPageDom);
        exchange.info_area.push(...uAreas);

        page.exchange = exchange;
      });

      this.fillAreaIndex = { ...initIndex };

      return npages;
    },
    getUndertakingInfo(pageDom) {
      const areas = [];
      const undertakingDom = pageDom.querySelector(".elem-undertaking");
      if (undertakingDom) {
        areas.push(this.getOffsetInfo(undertakingDom));
      }

      return areas;
    },
    getExtraInfo(pageDom) {
      const info = {
        barcode: [],
      };
      const courseBarDom = pageDom.querySelector(".course-barcode");
      if (courseBarDom) {
        info.barcode.push({
          field: "courseCode",
          area: this.getOffsetInfo(courseBarDom),
        });
      }

      return info;
    },
    getPageNumberInfo() {
      const dom = document.getElementById(`preview-page-box-0`);
      let options = [];
      dom
        .querySelector(".page-number-rect-list")
        .childNodes.forEach((item, index) => {
          options[index] = this.getOffsetInfo(item);
        });
      // console.log(options);
      return [
        {
          field: "pageNumber",
          index: 1,
          single: true,
          horizontal: true,
          items: [
            {
              main_number: null,
              sub_number: null,
              options,
              recog_info: [],
            },
          ],
        },
      ];
    },
    getLocatorInfo(curPageDom) {
      let tops = [];
      curPageDom
        .querySelector(".page-locator-top")
        .childNodes.forEach((item) => {
          tops.push(this.getOffsetInfo(item));
        });

      let bottoms = [];
      curPageDom
        .querySelector(".page-locator-bottom")
        .childNodes.forEach((item) => {
          bottoms.push(this.getOffsetInfo(item));
        });
      return {
        top: tops,
        bottom: bottoms,
      };
    },
    getCardHeadInfo(element) {
      const dom = this.getPreviewElementById(element.id);
      const headArea = this.getOffsetInfo(dom);
      let fill_area = [];
      let barcode = [];
      // 学生学号
      if (element.examNumberStyle === "FILL") {
        // fill_area
        let listInfos = [];
        dom
          .querySelectorAll(".stdno-fill-list")
          .forEach((questionItem, questionIndex) => {
            let options = [];
            questionItem.childNodes.forEach((optionItem, optionIndex) => {
              options[optionIndex] = this.getOffsetInfo(optionItem);
            });
            listInfos[questionIndex] = {
              main_number: null,
              sub_number: null,
              options,
              recog_info: [],
            };
          });

        fill_area.push({
          field: "examNumber",
          index: this.getFillAreaIndex("examNumber"),
          single: false,
          horizontal: false,
          items: listInfos,
        });
      } else {
        // barcode
        const stdnoDom =
          element.columnNumber <= 2
            ? dom.querySelector(".head-stdno").parentNode
            : dom.querySelector(".head-stdno");
        barcode.push({
          field: "examNumber",
          area: this.getOffsetInfo(stdnoDom),
        });
      }
      // 缺考涂填
      if (element.examAbsent && !element.isSimple) {
        fill_area.push({
          field: "absent",
          index: this.getFillAreaIndex("absent"),
          single: true,
          horizontal: true,
          items: [
            {
              main_number: null,
              sub_number: null,
              options: [
                this.getOffsetInfo(dom.querySelector(".dynamic-miss-area")),
              ],
              recog_info: [],
            },
          ],
        });
      }
      // 违纪标记
      if (element.discipline && !element.isSimple) {
        fill_area.push({
          field: "breach",
          index: this.getFillAreaIndex("breach"),
          single: true,
          horizontal: true,
          items: [
            {
              main_number: null,
              sub_number: null,
              options: [
                this.getOffsetInfo(dom.querySelector(".dynamic-breach-area")),
              ],
              recog_info: [],
            },
          ],
        });
      }
      // A/B卷类型
      if (element.aOrB && !element.isSimple) {
        // if (element.paperType === "PRINT") {
        //   // barcode
        //   barcode.push({
        //     field: "paperType",
        //     area: this.getOffsetInfo(
        //       dom.querySelector(".dynamic-aorb-barcode")
        //     ),
        //   });
        // }

        if (element.paperType === "FILL") {
          // fill_area
          let options = [];
          dom
            .querySelector(".head-dynamic-aorb")
            .querySelectorAll(".head-dynamic-rect")
            .forEach((optionItem, optionIndex) => {
              options[optionIndex] = this.getOffsetInfo(optionItem);
            });
          fill_area.push({
            field: "paperType",
            index: this.getFillAreaIndex("paperType"),
            single: false,
            horizontal: true,
            items: [
              {
                main_number: null,
                sub_number: null,
                options,
                recog_info: [],
              },
            ],
          });
        }
      }

      return {
        info_area: [headArea],
        fill_area,
        barcode,
      };
    },
    getFillQuestionInfo(element) {
      const dom = this.getPreviewElementById(element.id);
      const single = !element.isMultiply;
      const horizontal = element.optionDirection === "horizontal";

      let fillAreas = [];
      dom.querySelectorAll(".group-item").forEach((groupItem) => {
        let listInfos = [];

        groupItem
          .querySelectorAll(".question-item")
          .forEach((questionItem, questionIndex) => {
            let options = [];
            questionItem.childNodes.forEach((optionItem, optionIndex) => {
              if (optionIndex)
                options[optionIndex - 1] = this.getOffsetInfo(optionItem);
            });
            listInfos[questionIndex] = {
              main_number: element.topicNo,
              sub_number: questionItem.firstChild.textContent * 1,
              options,
              recog_info: [],
            };
          });
        fillAreas.push({
          field: "question",
          index: this.getFillAreaIndex("question"),
          single,
          horizontal,
          items: listInfos,
        });
      });

      return {
        fill_area: fillAreas,
      };
    },
    getFillLineInfo(element) {
      const dom = this.getPreviewElementById(element.id);
      let sub_numbers = [];
      for (
        let i = element.startNumber,
          len = element.startNumber + element.questionsCount;
        i < len;
        i++
      ) {
        sub_numbers.push(i);
      }

      return {
        answer_area: [
          {
            main_number: element.topicNo,
            sub_number: sub_numbers.join(),
            area: this.getOffsetInfo(dom),
          },
        ],
      };
    },
    getExplainInfo(element) {
      const dom = this.getPreviewElementById(element.id);

      return {
        answer_area: [
          {
            main_number: element.topicNo,
            sub_number: element.serialNumber,
            area: this.getOffsetInfo(dom),
          },
        ],
      };
    },
    getCompositionInfo(element) {
      const dom = this.getPreviewElementById(element.id);

      return {
        answer_area: [
          {
            main_number: element.topicNo,
            sub_number: 1,
            area: this.getOffsetInfo(dom),
          },
        ],
      };
    },
    getOffsetInfo(dom) {
      const {
        width: domW,
        height: domH,
        left: domL,
        top: domT,
      } = dom.getBoundingClientRect();
      const {
        width: pageW,
        height: pageH,
        left: pageL,
        top: pageT,
      } = this.curPageOffsetInfo;

      // [x,y,w,h]
      const infos = [
        (domL - pageL) / pageW,
        (domT - pageT) / pageH,
        domW / pageW,
        domH / pageH,
      ];

      return infos.map((num) => num.toFixed(10) * 1);
    },
    getPageModel({ cardConfig, pages, answers = {} }) {
      let npages = this.parsePageExchange(pages);
      return JSON.stringify(
        {
          version: CARD_VERSION,
          cardType: "STANDARD",
          cardConfig,
          pages: npages,
          answers,
        },
        (k, v) => (k.startsWith("_") ? undefined : v)
      );
    },
  },
};
