"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.formatSlateToMd = void 0;
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/esm/objectSpread2"));
var _slate = require("slate");
var _isPunctuationMark = _interopRequireDefault(require("../../utils/is-punctuation-mark"));
var _helper = require("../../extension/plugins/link/helper");
const formatInlineChildren = children => {
  return children.reduce((ret, item, index) => {
    if (index === 0) return [item];
    let prev = ret[ret.length - 1];
    if (prev.type === item.type && item.type === 'text') {
      prev.value = prev.value + item.value;
    } else if (prev.type === item.type && item.type === 'strong') {
      const prevChild = prev.children[0];
      const nextChild = item.children[0];
      prev.children = [{
        type: 'text',
        value: prevChild.value + nextChild.value
      }];
    } else if (prev.type === item.type && item.type === 'emphasis') {
      const prevChild = prev.children[0];
      const nextChild = item.children[0];
      if (prevChild.type === nextChild.type && prevChild.type === 'text') {
        prev.children = [{
          type: 'text',
          value: prevChild.value + nextChild.value
        }];
      } else if (prevChild.type === nextChild.type && prevChild.type === 'strong') {
        prev.children = [{
          type: 'strong',
          children: [{
            type: 'text',
            value: prevChild.children[0].value + nextChild.children[0].value
          }]
        }];
      } else {
        ret.push(item);
      }
    } else {
      ret.push(item);
    }
    return ret;
  }, []);
};
const generateDefaultText = value => {
  return {
    type: 'text',
    value: value || ''
  };
};
const transformTextNode = textNode => {
  let mdNode = {
    type: 'text',
    value: textNode.text
  };

  // code = true, override text type
  if (textNode['code']) {
    mdNode = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, mdNode), {}, {
      type: 'inlineCode'
    });
  }

  // blob = true, add strong parent
  if (textNode['bold']) {
    mdNode['value'] = mdNode.value ? mdNode.value.trim() : '';
    if ((0, _isPunctuationMark.default)(mdNode.value)) {
      // https://symbl.cc/en/200B/
      mdNode['value'] = mdNode.value + '​';
    }
    mdNode = {
      type: 'strong',
      children: [mdNode]
    };
  }

  // italic = true, add emphasis parent
  if (textNode['italic'] && mdNode.type === 'strong') {
    mdNode = {
      type: 'emphasis',
      children: [mdNode]
    };
  } else if (textNode['italic']) {
    mdNode['value'] = mdNode.value ? mdNode.value.trim() : '';
    if ((0, _isPunctuationMark.default)(mdNode.value)) {
      // https://symbl.cc/en/200B/
      mdNode['value'] = mdNode.value + '​';
    }
    mdNode = {
      type: 'emphasis',
      children: [mdNode]
    };
  }
  return mdNode;
};
const transformInlineChildren = (result, item) => {
  // image
  if (item.type && item.type === 'image') {
    const {
      data
    } = item;
    let image = {
      type: 'image',
      url: data.src,
      alt: data.alt || null,
      title: data.title || null
    };
    if (data.height || data.width) {
      image = {
        type: 'html',
        value: "<img src=\"".concat(data.src, "\" alt=\"").concat(data.alt, "\" title=\"").concat(data.title, "\" width=\"").concat(data.width, "\" height=\"").concat(data.height, "\" />")
      };
    }
    result.push(image);
    return result;
  }

  // link
  if (item.type && item.type === 'link') {
    const link = {
      type: 'link',
      url: (0, _helper.getElementHref)(item),
      title: item.title || null,
      children: [transformTextNode(item.children[0])]
    };
    result.push(link);
    return result;
  }
  if (item.type && item.type === 'column') {
    const data = item.data;
    const newNode = {
      text: "{".concat(data.name, "}")
    };
    const column = transformTextNode(newNode);
    result.push(column);
    return result;
  }
  if (item.type && item.type === 'html') {
    result.push(item);
    return result;
  }

  // text
  const nodes = transformTextNode(item);
  result.push(nodes);
  return result;
};
const transformNodeWithInlineChildren = node => {
  const {
    children
  } = node;
  const defaultChildren = [generateDefaultText()];
  if (!children || !Array.isArray(children) || children.length === 0) {
    return defaultChildren;
  }
  const result = [];
  children.forEach(item => transformInlineChildren(result, item));

  // format result
  return formatInlineChildren(result.flat());
};
const transformHeader = node => {
  const level = node.type.replace('header', '');
  return {
    type: 'heading',
    depth: parseInt(level),
    children: transformNodeWithInlineChildren(node)
  };
};
const transformParagraph = node => {
  const {
    children
  } = node;
  if (!Array.isArray(children) || children.length === 0) {
    return {
      type: 'paragraph',
      children: transformNodeWithInlineChildren(node)
    };
  }
  const voidNodeTypes = ['image', 'column', 'formula'];
  const hasBlock = children.some(item => voidNodeTypes.includes(item.type));
  const hasHtml = children.some(item => item.type === 'html');
  if (!hasHtml && !hasBlock && _slate.Node.string(node).length === 0) {
    return {
      type: 'paragraph',
      children: [
      // https://symbl.cc/en/200B/
      generateDefaultText('​')]
    };
  }
  return {
    type: 'paragraph',
    children: transformNodeWithInlineChildren(node)
  };
};
const transformBlockquote = node => {
  const {
    children
  } = node;
  return {
    type: 'blockquote',
    children: children.map(child => {
      const handler = elementHandlers[child.type];
      return handler(child);
    }).flat() // flat
  };
};
const transformCheckList = node => {
  return {
    type: 'list',
    ordered: false,
    start: null,
    spread: false,
    children: [{
      type: 'listItem',
      spread: false,
      checked: node.checked ? true : false,
      children: [transformParagraph(node)]
    }]
  };
};
const transformListContent = node => {
  return transformParagraph(node);
};
const transformListItem = node => {
  let loose = false;
  let spread = false;
  const {
    children
  } = node;
  // eslint-disable-next-line array-callback-return
  const newChildren = children.map(child => {
    if (child.type === 'paragraph') {
      return transformListContent(child);
    }
    if (child.type === 'code_block') {
      return transformCodeBlock(child);
    }
    if (child.type === 'blockquote') {
      return transformBlockquote(child);
    }
    if (child.type === 'unordered_list' || child.type === 'ordered_list') {
      return transformList(child);
    }
  });
  if (newChildren.length === 1) {
    loose = false;
    spread = false;
  } else if (newChildren.length === 2 && newChildren[1].type === 'list') {
    loose = true;
    spread = false;
  } else {
    loose = true;
    spread = true;
  }
  return {
    type: 'listItem',
    loose,
    spread,
    checked: null,
    children: newChildren
  };
};
const transformList = node => {
  const {
    children
  } = node;
  const newChildren = children.map(child => transformListItem(child));
  let loose = false;
  let spread = false;
  for (let node of newChildren) {
    if (node.loose === true) {
      loose = true;
    }
    if (node.spread === true) {
      spread = true;
    }
  }
  return {
    type: 'list',
    ordered: node.type === 'ordered_list',
    // ordered_list | unordered_list
    start: 1,
    loose,
    spread,
    children: newChildren
  };
};
const transformTableCell = cell => {
  return {
    type: 'tableCell',
    children: transformNodeWithInlineChildren(cell)
  };
};
const transformTableRow = row => {
  const {
    children: cells
  } = row;
  return {
    type: 'tableRow',
    children: cells.map(cell => transformTableCell(cell))
  };
};
const transformTable = node => {
  const {
    children: rows,
    align
  } = node;
  return {
    type: 'table',
    align: align,
    children: rows.map(row => transformTableRow(row))
  };
};
const transformCodeLine = node => {
  var _node$children$;
  const text = ((_node$children$ = node.children[0]) === null || _node$children$ === void 0 ? void 0 : _node$children$.text) || '';
  return text;
};
const transformCodeBlock = node => {
  const {
    children
  } = node;
  return {
    type: 'code',
    lang: node.lang ? node.lang : null,
    value: children.map(child => transformCodeLine(child)).join('\n')
  };
};
const transformFormula = node => {
  const data = node.data;
  return {
    type: 'math',
    value: data.formula
  };
};
const transformAsParagraph = node => {
  const paragraph = {
    type: 'paragraph',
    children: [{
      text: _slate.Node.string(node)
    }]
  };
  return transformParagraph(paragraph);
};
const transformDivider = () => ({
  type: 'thematicBreak'
});
const elementHandlers = {
  'paragraph': transformParagraph,
  'header1': transformHeader,
  'header2': transformHeader,
  'header3': transformHeader,
  'header4': transformHeader,
  'header5': transformHeader,
  'header6': transformHeader,
  'blockquote': transformBlockquote,
  'table': transformTable,
  'check_list_item': transformCheckList,
  'ordered_list': transformList,
  'unordered_list': transformList,
  'code_block': transformCodeBlock,
  'formula': transformFormula,
  'divider': transformDivider
};
const formatSlateToMd = children => {
  // const validChildren = children.filter(child => elementHandlers[child.type]);
  const validChildren = children;
  return validChildren.map(child => {
    const handler = elementHandlers[child.type];
    if (handler) {
      return handler(child);
    } else {
      return transformAsParagraph(child);
    }
  }).flat();
};
exports.formatSlateToMd = formatSlateToMd;