// const _text_styles_ = ["bold", "underline", "italic", "sup", "sub"];

import { RichTextBlockJSON, RichTextJSON, RichTextSectionJSON } from "@/types";

let _container = document.createElement("div");
let clozeIndex = 0;
/**
 * 将富文本 JSON 渲染到指定的元素中
 *
 * @param {RichTextJSON} body
 * @param {HTMLDivElement} container
 */
export function renderRichText(body: RichTextJSON, container?: HTMLDivElement) {
  _container = container || document.createElement("div");
  clozeIndex = 0;
  const sections = body?.sections || [];
  const nodes = [] as Array<Node>;
  sections.forEach((section) => {
    nodes.push(renderSection(section));
  });
  if (_container != undefined) {
    // container.classList.add("rich-text");
    while (_container.hasChildNodes()) {
      _container.removeChild(_container.lastChild as Node);
    }
    nodes.forEach((node) => {
      _container.appendChild(node);
    });
  }

  return _container;
}

/**
 * @param {RichTextSectionJSON} section
 * @returns {HTMLDivElement} 返回根据 section 渲染好的 HTMLDivElement
 */
function renderSection(section: RichTextSectionJSON) {
  const blocks = section.blocks || [];
  const inline = blocks.length > 1;
  const node = document.createElement("div");
  // node.style = "display: flex;";
  blocks.forEach((block) => {
    node.appendChild(renderBlock(block, inline));
  });
  return node;
}

/**
 * @param {RichTextBlockJSON} block
 * @param {Boolean} inline 图片是否以 inline 的样式展示
 * @returns {HTMLElement} 返回根据 block 渲染好的 HTMLElement
 */
function renderBlock(block: RichTextBlockJSON, inline: boolean) {
  // let node = document.createElement('span')
  // let classList = node.classList
  let node;
  if (block.type === "text") {
    // classList.add('text')
    // if (block.param != undefined) {
    //     _text_styles_.forEach(style => {
    //         if (block.param[style] === true) {
    //             classList.add(style)
    //         }
    //     })
    // }
    if (
      block.param &&
      (block.param.underline || block.param.bold || block.param.italic)
    ) {
      let uNode: Node | null = null,
        bNode: Node | null = null,
        iNode: Node | null = null;
      if (block.param.underline) {
        uNode = document.createElement("u");
      }
      if (block.param.bold) {
        bNode = document.createElement("b");
      }
      if (block.param.italic) {
        iNode = document.createElement("i");
      }
      // 将不为空的元素依次append
      node = ([uNode, bNode, iNode] as Array<Node>)
        .filter((v) => v)
        .reduceRight((p, c) => {
          c.appendChild(p);
          return c;
        });

      let childNode = node;

      for (let i = 0; i < 3; i++) {
        if (childNode && childNode.hasChildNodes()) {
          childNode = childNode.childNodes[0];
        }
      }

      childNode.textContent = block.value;
    } else {
      node = document.createTextNode(block.value);
    }
  } else if (block.type === "image") {
    node = document.createElement("img");
    if (inline === true) {
      node.classList.add("inline");
    }

    node.src = block.value;

    // param
    if (block.param) {
      const { width, height } = block.param;
      width && (node.style.width = width + "px");
      height && (node.style.height = height + "px");
    }
  } else if (block.type === "audio") {
    node = document.createElement("audio");
    node.className = "audio";
    node.src = block.value;
    node.controls = true;
  } else if (block.type === "cloze") {
    node = document.createElement("span");
    node.innerHTML = `___${++clozeIndex}___`;
  }

  return node as Node;
}
