import React, { useEffect, useRef, useMemo , useState } from 'react'
import 'katex/dist/katex.min.css';
import marked, { getTocContent, cleanToc, getMathExpressions, resetMathExpressions } from '../common/marked';
import 'code-prettify';
import dompurify from 'dompurify';
// import { getEmoji } from '../forge/Main/emoji';
import axios from 'axios';

import { renderToString } from 'katex'

const preRegex = /<pre[^>]*>/g;
const strRegexSub = /:([a-zA-Z_]+):/g;
const quoteRegex = /\[[#][0-9]{0,}\]\(\/(.*?)\/(.*?)\/issues\/[0-9]{0,}\)/g;
function _unescape(str) {
  let div = document.createElement('div')
  div.innerHTML = str
  return div.childNodes.length === 0 ? "" : div.childNodes[0].nodeValue
}



export default ({
  value = '',
  className,
  style = {},
  url,
  owner=undefined,
  projectsId=undefined
}) => {
  const [ issues , setIssues ] = useState([]);

  useEffect(()=>{
    if(owner&&projectsId){
      getIssueList();
    }
  },[owner,projectsId])

  function getIssueList(){
    axios.get(`/v1/${owner}/${projectsId}/issues`,{params:{
      only_name:true,sort_direction:"desc",sort_by:"issues.created_on"
    }}).then(result=>{
      if(result){
        let data = result.data.issues;
        setIssues(data);
      }
    })
  }

  let str = String(value);
  const html = useMemo(() => {
    let rs = marked(str);
    const math_expressions = getMathExpressions();
    if (str.match(/\[TOC\]/)) {
      rs = rs.replace("<p>[TOC]</p>", getTocContent())
      cleanToc()
    }
    // 循环匹配所有emoji
    // let matchStr = str.match(strRegexSub);
    // if(matchStr && matchStr.length>0){
    //   for(var i=0;i < matchStr.length;i++){
    //     rs = rs.replace(matchStr[i],getEmoji(matchStr[i]));
    //   }
    // }
    if(owner && projectsId && issues && issues.length>0){
      let matchQuote = str.match(quoteRegex);
      if(matchQuote && matchQuote.length>0){
        let getIndexReg = /(?<=#)(.+?)(?=\])/g;
        for(var x=0;x<matchQuote.length;x++){
          let getIndex = matchQuote[x].match(getIndexReg);
          if(getIndex && getIndex.length>0 && getIndex[0]){
            let index = getIndex[0];
            let filter = issues.filter(f=>f.project_issues_index.toString() === index);
            if(filter && filter.length === 1){
              let content = `#${index}:${filter[0].subject}`;
              rs = rs.replace(`#${index}`,content);
            }else{
              let content = `<span>#${index}(已删除)</span>`;
              rs = rs.replace(`<a href="`+`/${owner}/${projectsId}/issues/${index}`+`">#${index}</a>`,content);
            }
          }
        }
      }
    }
    
    rs = rs.replace(/(__special_katext_id_\d+__)/g, (_match, capture) => {
      const { type, expression } = math_expressions[capture];
      return renderToString(_unescape(expression) || '', { displayMode: type === 'block', throwOnError: false, output: 'html' })
    })
    rs = rs.replace(/▁/g, "▁▁▁")
    resetMathExpressions()
    return dompurify.sanitize(rs)
  }, [str,issues]);

  // 锚点跳转，链接地址里含#对应的id
  useEffect(()=>{
    if(url && url.hash && html){
      let u = url.hash;
      if(u){
        let id = decodeURIComponent(u.split("#")[1]);
        let ele = document.getElementById(id);
        if(ele){
          window.scrollTo(0, ele.offsetTop);
        }
      }
    }
  },[url,html])

  const el = useRef();
  function onAncherHandler(e) {
    let target = e.target;
    if (target.tagName.toUpperCase() === 'A') {
      let ancher = target.getAttribute('href');
      if (ancher && ancher.startsWith('#')) {
        e.preventDefault()
        let viewEl = document.getElementById(ancher.replace('#', ''))
        if (viewEl) {
          viewEl.scrollIntoView(true)
        }
      }
    }
  }

  useEffect(() => {
    if (el.current && html) {
      if (html.match(preRegex)) {
        window.PR.prettyPrint()
      }
    }
    if (el.current) {
      el.current.addEventListener('click', onAncherHandler)
      return () => {
        el.current.removeEventListener('click', onAncherHandler)
        resetMathExpressions()
        cleanToc()
      }
    }
  }, [html, el.current, onAncherHandler])
  return (
    <div
      ref={el}
      style={style}
      className={`${className ? className : ''} markdown-body`}
      dangerouslySetInnerHTML={{ __html: html }}
    ></div>
  )
}
