/**
 * 将编辑器的 HTMLDivElement 转为我们需要的 JSON.stringify(RichTextJSON)
 *
 * @param {HTMLDivElement} editor
 *
 * @returns {String} JSON.stringify(RichTextJSON)
 */
export function toJSON(editor) {
  let newSections = [];
  const nodesSectionsCollector = toNodeSections(editor);
  nodesSectionsCollector.forEach((section) => {
    let newSection = { blocks: [] };
    section.forEach((elem) => {
      const newBlock = toJSONBlock(elem);
      if (newBlock) newSection.blocks.push(newBlock);
    });

    if (!newSection.blocks.length) {
      // 空行特殊处理
      newSection.blocks = [{ type: "text", value: "", param: null }];
    }
    newSections.push(newSection);
  });
  // console.log(newSections);

  /** @type {RichTextJSON} */
  const result = { sections: newSections };
  return result;
  // return JSON.stringify(result, null);
}

function toNodeSections(node) {
  let sections = [];
  let curSection = [];

  const checkIsDiv = (elem) => {
    return elem.nodeType == Node.ELEMENT_NODE && elem.nodeName === "DIV";
  };

  const parseNode = (node) => {
    node.childNodes.forEach((elem) => {
      if (checkIsDiv(elem) && curSection.length) {
        sections.push(curSection);
        curSection = [];
      }

      if (elem.childNodes && elem.childNodes.length) {
        parseNode(elem);
      } else {
        curSection.push(elem);
      }
    });
  };

  parseNode(node);

  if (curSection.length) {
    sections.push(curSection);
  }

  // console.log(sections);
  return sections;
}

/**
 * 目前限定结构只有三层 u b i
 *
 * @param {Node} e
 * @param {String} tag
 */
function checkAncestorElementTag(e) {
  let parentNode = e.parentNode;
  let elementTags = [];
  let validTags = ["I", "B", "U", "SUB", "SUP"];
  while (parentNode && !parentNode.className.includes("v-editor-body")) {
    if (validTags.includes(parentNode.nodeName)) {
      elementTags.push(parentNode.nodeName);
    }
    parentNode = parentNode.parentNode;
  }
  return elementTags;
}

/**
 * 将 HTML Node 转为 block (JSON)
 * @param {Node} e
 * @returns {RichTextBlockJSON}
 */
function toJSONBlock(e) {
  /** @type {RichTextBlockJSON} */
  let block = {};
  if (e.nodeType === Node.TEXT_NODE) {
    block.type = "text";
    block.value = e.textContent;
    const elementTags = checkAncestorElementTag(e);
    let param = {
      italic: elementTags.includes("I"),
      bold: elementTags.includes("B"),
      underline: elementTags.includes("U"),
      sup: elementTags.includes("SUP"),
      sub: elementTags.includes("SUB"),
    };
    const allFalse = !Object.values(param).some((v) => v);
    block.param = allFalse ? null : param;
  } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "U") {
    block.type = "text";
    block.value = e.textContent;
    block.param = { underline: true };
  } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "B") {
    block.type = "text";
    block.value = e.textContent;
    block.param = { bold: true };
  } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "I") {
    block.type = "text";
    block.value = e.textContent;
    block.param = { italic: true };
  } else if (
    e.nodeType == Node.ELEMENT_NODE &&
    e.nodeName === "IMG" &&
    e.dataset.isImage
  ) {
    block.type = "image";

    // change base64 image size, draw canvas
    block.value = e.src;
    block.param = {
      width: e.clientWidth,
      height: e.clientHeight,
    };
    // 公式latex表达式
    if (e.dataset.latex) {
      block.param.latex = e.dataset.latex;
    }
  } else if (
    e.nodeType == Node.ELEMENT_NODE &&
    e.nodeName === "IMG" &&
    e.dataset.isAudio
  ) {
    block.type = "audio";
    // 音频使用云端地址
    block.value = e.dataset.audioSrc;
    block.param = { duration: e.dataset.duration };
  } else if (
    e.nodeType == Node.ELEMENT_NODE &&
    e.nodeName === "IMG" &&
    e.dataset.isAnswerPoint
  ) {
    block.type = "cloze";
    block.value = e.dataset.order * 1;
    block.param = null;
  } else if (e.nodeType == Node.ELEMENT_NODE && e.nodeName === "BR") {
    block.type = "text";
    block.value = "";
    block.param = null;
  } else {
    console.log("toJSONBlock: 非法", e);
  }

  // if (block.type === "text" && block.value === "") {
  //   block = null; // 返回null的block，从json中剔除
  // }
  return block;
}
