/**
 * 对消息按照内容进行切片，切片采用react渲染
 * 核心知识点 1正则表达式  2JSX children 3多维数组
 * 切片顺序常用功能优先，可以减少数组维度
 * 表情 > mention > 引用（换行）> 链接
 */

import React, { Component } from 'react';
import css from './index.scss';
import emojiConfig from './EmojiConfig/index';

class PlainMessage extends Component {

  /**
   * 切片函数
   * @param text 文本
   * @param reg 正则
   * @param emit 匹配结果转换器
   * @param next 余下文本切片
   * @returns {*}
   */
  getSlices = (text, reg, emit, next) => {
    const matchs = text.match(reg); // 匹配的结果 进行相关替换
    console.log('matchs',matchs)
    if(matchs === null) {
      // 没有匹配
      return next ? next(text) : text; // 没有匹配继续下一个切片
    }
    const slices = text.split(reg); // 切片后的文本 继续下一个切片
    console.log('slice',slices)
    let items = []
    for (let i=0; i<slices.length; i++) {
      const ele = <span key={i}>{next ? next(slices[i]) : slices[i]}{emit ? emit(matchs[i]): matchs[i]}</span>
      const children = ele.props.children
      items = items.concat(children)
    }
    return items;
  }

  // 高亮解析
  getHighLights = (text) => {
    console.log('high light 0',text)
    const reg = /\<span.*?\>.+?\<\/span\>/g
    return this.getSlices(text, reg, this.getHighLight, this.getEmojis)
  }

  getHighLight = (text) => {
    console.log('high light 1',text)
    if(!text) {
      return null
    }
    const reg = /\<span.*\>(.*)\<\/span\>/
    const res = text.match(reg)
    console.log('high light 2',res)
    if(res) {
      return <span className="s-primary">{res[1]}</span>
    }else{
      return text
    }
  }

  // 表情解析
  getEmojis = (text) => {
    const reg = /:\S*?:|\[\S*?\]/g;
    return this.getSlices(text, reg, this.getEmoji, this.getMentions)
  }
  getEmoji = (text) => {
    // :small: [微笑]
    for(const i of emojiConfig) {
      const { size, data } = i
      if(data[text]) {
        return <img className={css[size]} src={data[text]} alt='' />
      }
    }
    return text
  }
  // mention @ 解析
  getMentions = (text) => {
    const reg = /<@[^<(?=@)]+?\|.+?>/g;
    return this.getSlices(text, reg, this.getMention, this.getNewLines)
  }
  getMention = (text) => {
    // <@account|name>
    if(!text) {
      return null
    }
    const res = /<@([^<(?=@)]+?)\|(.+?)>/g.exec(text);
    if(!res) {
      return null
    }
    const account = res[1];
    const name = res[2];
    return account && name ? <span className={css.mention}>@{name === 'all' ? '所有人' : name}</span> : null
  }

  // 换行解析
  getNewLines = (text) => {
    const reg = /\n/g;
    const emit = (t) => {
      return t ? <br /> : null
    }
    return this.getSlices(text, reg, emit)
  }


  render() {
    const { text } = this.props;
    return (
      <p className={css.plain}>{this.getHighLights(text)}</p>
    );
  }
}

export default PlainMessage;
