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

export default function useParser() {
  function parseRichText(editorContainer: HTMLDivElement) {
    const newSections = [] as RichSection[];
    const nodesSectionsCollector = parseNodeSections(editorContainer);
    nodesSectionsCollector.forEach((section) => {
      const newSection = { blocks: [] as RichBlock[] };
      section.forEach((elem) => {
        const newBlock = parseBlockJson(elem);
        newSection.blocks.push(newBlock);
      });

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

    const result = { sections: newSections } as RichTextJSON;
    return result;
  }

  function parseNodeSections(node: HTMLElement) {
    const sections = [] as HTMLElement[][];
    let curSection = [] as HTMLElement[];

    const checkIsDiv = (elem: HTMLElement) => {
      return elem.nodeType === Node.ELEMENT_NODE && elem.nodeName === 'P';
    };

    const parseNode = (nnode: HTMLElement) => {
      nnode.childNodes.forEach((elem) => {
        const nelem = elem as HTMLElement;
        if (checkIsDiv(nelem) && curSection.length) {
          sections.push(curSection);
          curSection = [];
        }

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

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

    return sections;
  }

  function checkAncestorElementTag(e: HTMLElement) {
    let parentNode = e.parentNode as HTMLElement;
    const elementTags = [];
    const validTags = ['EM', 'STRONG', 'U', 'SUB', 'SUP'];
    while (parentNode && !parentNode.className?.includes('ql-editor')) {
      if (validTags.includes(parentNode.nodeName)) {
        elementTags.push(parentNode.nodeName);
      }
      parentNode = parentNode.parentNode as HTMLElement;
    }
    return elementTags;
  }

  function parseBlockJson(e: HTMLElement) {
    // 图片
    if (e.nodeType === Node.ELEMENT_NODE && e.nodeName === 'IMG') {
      return parseImageJson(e as HTMLImageElement);
    }
    // 文本
    if (e.nodeType === Node.TEXT_NODE || e.nodeType === Node.ELEMENT_NODE) {
      return parseTextJson(e);
    }

    // 空div和br直接返回空段落
    const block = {} as RichBlock;
    if (e.nodeType === Node.ELEMENT_NODE && ['BR', 'P'].includes(e.nodeName)) {
      block.type = 'text';
      block.value = '';
    } else {
      console.log('toJSONBlock: 非法', e);
    }
    return block;
  }

  function parseTextJson(e: HTMLElement) {
    const block = {} as RichBlock;
    if (e.nodeType === Node.TEXT_NODE) {
      block.type = 'text';
      block.value = e.textContent || '';
      const elementTags = checkAncestorElementTag(e);
      const param = {
        italic: elementTags.includes('EM'),
        bold: elementTags.includes('STRONG'),
        underline: elementTags.includes('U'),
        sup: elementTags.includes('SUP'),
        sub: elementTags.includes('SUB'),
      };
      const allFalse = !Object.values(param).some((v) => v);
      block.param = allFalse ? undefined : param;
    }

    if (e.nodeType === Node.ELEMENT_NODE) {
      block.type = 'text';
      block.value = e.textContent || '';
      if (e.nodeName === 'U') {
        block.param = { underline: true };
      } else if (e.nodeName === 'B') {
        block.param = { bold: true };
      } else if (e.nodeName === 'I') {
        block.param = { italic: true };
      }
    }

    return block;
  }

  function parseImageJson(e: HTMLImageElement) {
    const block = {} as RichBlock;

    block.type = 'image';
    block.value = e.src;
    block.param = {
      width: e.clientWidth,
      height: e.clientHeight,
    };
    return block;
  }

  return {
    parseRichText,
  };
}
