import {
  RichBlock,
  RichImageBlock,
  RichSection,
  RichTextBlock,
  RichTextJSON,
} from './types';

export default function useRender() {
  function renderRichText(body: RichTextJSON) {
    const editorContainer = document.createElement('div');

    const sections = body.sections || [];
    const nodes = [] as HTMLParagraphElement[];
    sections.forEach((section) => {
      nodes.push(renderSection(section));
    });

    nodes.forEach((node) => {
      editorContainer.appendChild(node);
    });

    return editorContainer.innerHTML;
  }

  function renderSection(section: RichSection) {
    const blocks = section.blocks || [];
    const inline = blocks.length > 1;
    const node = document.createElement('p');
    blocks.forEach((block) => {
      const bnode = renderBlock(block, inline);
      if (bnode) node.appendChild(bnode);
    });
    return node;
  }

  function renderBlock(block: RichBlock, inline: boolean): HTMLElement | null {
    if (block.type === 'text') {
      return renderText(block as RichTextBlock);
    }

    if (block.type === 'image') {
      return renderImage(block as RichImageBlock, inline);
    }

    return null;
  }

  function renderText(block: RichTextBlock) {
    let node = null;

    if (block.param) {
      const nodeParams = {
        u: 'underline',
        strong: 'bold',
        em: 'italic',
        sup: 'sup',
        sub: 'sub',
      };
      const nodeNames = ['u', 'strong', 'em', 'sup', 'sub'] as Array<
        keyof typeof nodeParams
      >;

      const nodes = nodeNames
        .filter(
          (nodeName) =>
            block.param &&
            block.param[nodeParams[nodeName] as keyof RichTextBlock['param']]
        )
        .map((nodeName) => {
          return document.createElement(nodeName);
        });
      // @ts-ignore
      nodes.push(document.createTextNode(block.value));

      // 将不为空的元素依次append
      node = nodes.reduceRight((p, c) => {
        c.appendChild(p);
        return c;
      });
    } else {
      node = document.createTextNode(block.value);
    }
    return node as HTMLElement;
  }

  function renderImage(block: RichImageBlock, inline: boolean) {
    const node = document.createElement('img');
    if (inline) node.classList.add('inline');

    node.src = block.value;
    // node.dataset.isImage = true;
    // param
    if (block.param) {
      // 公式latex表达式
      if (block.param.latex) node.dataset.latex = block.param.latex;
      if (block.param.width) node.style.width = `${block.param.width}px`;
      if (block.param.height) node.style.height = `${block.param.height}px`;
    }

    return node;
  }

  return {
    renderRichText,
  };
}
