
function isFormulaItem(ele){
  return ele.type == 'Element' || ele.type == 'ParamData'
}

function parseFormula(arr,resultFormula,processFormula,isAllFun){
  let tmpArr = [];//放置这一层的数组
  for (let i = 0; i < arr.length; i++) {
    tmpArr.push(arr[i]);
    if(arr[i].type != "Function"){
      isAllFun = false;
    }
  }
  if(isAllFun){
    for (let i = 0; i < tmpArr.length; i++) {
      parseArguments(resultFormula[0],tmpArr[i]);
      parseFormula(arr[i].children,resultFormula,processFormula,isAllFun);
    }
  }else{
    for (let i = 0; i < tmpArr.length; i++) {
      if(tmpArr[i].type == 'Function'){
        let obj = {
          children:[],
          name:"临时占位",
          selected:false,
          type:"Element",
        }
        parseProcessFormula(arr[i],obj);
        processFormula.push(Object.assign({},obj))
        delete obj.children;
      }else if(tmpArr[i].name){
        processFormula.push(tmpArr[i]);
      }
    }
  }
}

//解析方法里面的参数
function parseArguments(ele,funObj){
  let fcReg = /(FC\.\S+\()(.+)\)/;
  let fun = {
    example:funObj.example,
    name:funObj.name,
    template:funObj.template,
  };
  //console.log(funObj)
  //特殊公式需要number
  if(funObj.number){
    fun.number = funObj.number;
  }
  let argTextArr = funObj.children;//放参数文本的数组

  //根据逗号位置分割参数
  let index = 0;
  let argSpliceArr = [[]];
  while (index < argTextArr.length) {
    if(argTextArr[index].type =='Comma'){
      argSpliceArr.push([]);
    }else{
      argSpliceArr[argSpliceArr.length-1].push(argTextArr[index])
    }
    index++
  }

  fun.arguments = [];

  let tmpArr = fcReg.exec(funObj.template.ft);
  let argList = tmpArr[2].split(",");//括号里面参数部分#1,#2..

  argList.forEach((argText,index)=>{
      //只用动态的
      if(argText.indexOf('#')>-1){
        if(argSpliceArr[index].length>1){
          if(fun.name == '判断'){
            fun.arguments.push(ifFunArgumentsHandle(argSpliceArr[index]))
          }else{
            //是前面的计算结果
            fun.arguments.push(ele)
          }

        }else{
          let arg = argSpliceArr[index][0];
          if(!arg){
            fun.arguments.push(undefined)
          }else if( arg.type == 'Element'){
            fun.arguments.push(arg)
          }else if( arg.type == 'ParamData'){
            fun.arguments.push(arg)
          }else if(arg.type == 'Function'){
            fun.arguments.push(ele)
          }else if(arg.type == 'Text'){
            fun.arguments.push(arg.tag)
          }else{
            fun.arguments.push(undefined)
          }
        }
      }
    })

  ele.children.push(fun);
}

function parseProcessFormula(funObj,ele){
  parseArguments(ele,funObj);
  let inFun = false;//是不是有Function
  let endEle = null;//认为最下面一层第一个元素是显示的元素
  for (let i = 0; i < funObj.children.length; i++) {
    if(funObj.children[i].type == 'Function'){
      parseProcessFormula(funObj.children[i],ele);
      inFun = true;
    }else if(isFormulaItem(funObj.children[i]) && !endEle){
      endEle = funObj.children[i];
    }
  }
  if(!inFun){
    //console.log(endEle)
    //把临时的属性改为最终找到的
    if(endEle.type == 'Element'){
      ele.id = endEle.id;
      ele.name = endEle.name;
      ele.tableElementKey = endEle.tableElementKey;
    }else if(endEle.type == 'ParamData'){
      ele.id = endEle.id;
      ele.name = endEle.name;
      ele.v = endEle.v;
      ele.k = endEle.k;
      ele.type = "ParamData";
    }
    
  }

}

//处理if方法的参数
function ifFunArgumentsHandle(argArr){
  let arr = [];

  argArr.forEach((Element)=>{
    if(Element.type == 'Text' || Element.type == 'Logical'){
      arr.push(Element.tag)
    }else{
      if(Element.type == 'Function'){
                let rootObj = {root:null};
        getRootElement(Element.children,rootObj)
        arr.push(rootObj.root)
      }else{
        arr.push(Element);
      }
    }
  })

  return arr;
}

//获取嵌套里面根节点元素，认为是if显示的元素
function getRootElement(children,rootObj){
  let inFun = false;//是不是有Function
  let endEle = null;//认为最下面一层第一个元素是显示的元素
  children.forEach((Element)=>{
    if(Element.type == 'Function'){
      getRootElement(Element.children,rootObj);
      inFun = true;
    }else if(isFormulaItem(Element) && !endEle){
      endEle = Element;
    }
  })
  if(!inFun){
    //把临时的属性改为最终找到的
    rootObj.root = Object.assign({},endEle);
  }
}

export const formulaStringToArray = (text,elemap,formulaMap) => {

  // 匹配开始的FC.xxx(
  const startFCRegExp = /^FC\.([a-zA-Z]+)\(/;
  const startBracketsReg = /^\(/;//左括号
  const endBracketsReg = /^\)/;//右括号
  const elementReg = /^E\[(.[^\]]+_.[^\]]+)\]/;//元素
  const paramReg = /^WP\[(.[^\]]+)\]/;//节点参数
  const commaReg = /^,/;//逗号
  const operatorReg = /^(\+|-|\*|%)/;//加减乘除
  const wordReg = /^[\u4e00-\u9fa5\w0-9'"-]+/;//文本
  const logicalReg = /^(>=|<=|>|<|=|&&)/;//逻辑符号

  let elementMap = JSON.parse(elemap);//元素字典
  //console.log(formulaMap)

  let resArr = [];//结果数组
  let strIndex = 0;//位置索引
  let nuText = text;//未处理的字符串
  //let startStack = [];//方法体开始部分和左括号 放进来的栈
  let contentStack = [];//内容放进来的栈

  while (strIndex < text.length) {
    nuText = text.substring(strIndex);
    if(startFCRegExp.test(nuText)){
      //console.log('匹配FC开始部分')
      //匹配FC开始部分FC.xxx(
      let regRes = nuText.match(startFCRegExp);
      let startText = regRes[0];//匹配到的文本
      
      let obj = {};
      if(formulaMap[startText]){
        Object.assign(obj,formulaMap[startText]);
        Object.assign(obj,{
          type:'Function',
          children:[],
          tag:startText
        });
      }else{
        obj = {
          type:'Function',
          children:[],
          tag:startText
        }
      }
      //startStack.push(startText);
      contentStack.push(obj);

      strIndex += startText.length;//索引移动
    }else if(endBracketsReg.test(nuText)){
      //console.log('匹配右括号')
      //匹配右括号
      let endBrackets = nuText.match(endBracketsReg)[0];

      let popObj = contentStack.pop();
      let arrType = [];
      
      if(contentStack.length > 0){
        let content =contentStack[contentStack.length - 1];
        content.children.push(popObj);
        arrType = content.children;
      }else{
        //匹配完成最顶层的一整个方法体，或括号
        resArr.push(popObj);
        arrType = resArr;
      }

      if(popObj.type =='Brackets'){
        let brackArr = [];
        //如果是括号，把括号里面的提出一层
        popObj.children.forEach((ele)=>{
          brackArr.push(ele);
        })
        //补个右括号
        brackArr.push({
          type:'Brackets',
          selected:false,
          name:')',
        });
        arrType.push(...brackArr);
        delete popObj.children
      }
      //console.log(popObj,'pop')

      strIndex += endBrackets.length;//索引移动
    }else if(startBracketsReg.test(nuText)){
      //console.log('匹配左括号')
      //匹配左括号
      let startBrackets = nuText.match(startBracketsReg)[0];
      
      contentStack.push({
        type:'Brackets',
        children:[],
        selected:false,
        name:startBrackets,
        tag:startBrackets
      });

      strIndex += startBrackets.length;//索引移动
    }else if(elementReg.test(nuText)){
      //console.log('匹配元素')
      //匹配元素
      let eleArr = nuText.match(elementReg);
      let obj = {};
      if(elementMap[eleArr[1]]){
        Object.assign(obj,elementMap[eleArr[1]]);
        Object.assign(obj,{
          selected:false,
          children:[],
          tag:eleArr[0]
        });
      }else{
        obj = {
          type:'Element',
          name:eleArr[1].split('_')[1],
          tableElementKey:eleArr[1],
          children:[],
          selected:false,
          tag:eleArr[0]
        }
      }
      
      let content =contentStack[contentStack.length - 1];
      if(content){
        content.children.push(obj);
      }else{
        //如果没有，那就是在最上层
        resArr.push(obj);
      }

      strIndex += eleArr[0].length;//索引移动
    }else if(paramReg.test(nuText)){
      //console.log('匹配节点参数')
      //匹配节点参数
      let eleArr = nuText.match(paramReg);
      let obj = {};
      if(elementMap[eleArr[1]]){
        Object.assign(obj,elementMap[eleArr[1]]);
        Object.assign(obj,{
          selected:false,
          children:[],
          tag:"paramData"
        });
      }else{
        obj = {
          type:'ParamData',
          name:elementMap[eleArr[1]].name,
          v:elementMap[eleArr[1]].v,
          k:elementMap[eleArr[1]].k,
          children:[],
          selected:false,
          tag:"paramData"
        }
      }
      
      let content =contentStack[contentStack.length - 1];
      if(content){
        content.children.push(obj);
      }else{
        //如果没有，那就是在最上层
        resArr.push(obj);
      }

      strIndex += eleArr[0].length;//索引移动
    }else if(commaReg.test(nuText)){
      //console.log('匹配逗号')
      //匹配逗号
      let comma = nuText.match(commaReg)[0];

      contentStack[contentStack.length - 1].children.push({
        type:'Comma',
        tag:comma
      });

      strIndex += comma.length;//索引移动
    }else if(logicalReg.test(nuText)){
      //console.log('逻辑符号')
      let logical = nuText.match(logicalReg)[0];

      contentStack[contentStack.length - 1].children.push({
        type:'Logical',
        tag:logical
      });

      strIndex += logical.length;//索引移动

    }else if(operatorReg.test(nuText)){
      //console.log('匹配加减乘除')
      //匹配加减乘除
      let operator = nuText.match(operatorReg)[0];
      let obj = {
        type:'Operator',
        name:operator,
        selected:false,
        tag:operator,
      };
      if(formulaMap[operator]){
        obj.example = formulaMap[operator].example;
        obj.template = formulaMap[operator].template;
      }

      if(contentStack.length > 0){
        //不然就在方法体或括号里面
        contentStack[contentStack.length - 1].children.push(obj);
      }else{
        //如果没有，那就是在最上层
        resArr.push(obj);
      }

      strIndex += operator.length;//索引移动
    }else if(wordReg.test(nuText)){
      //匹配文本
      let word = nuText.match(wordReg)[0];
      console.log('匹配文本',word)
      if(word == "''"){
        word = "";
      }

      let obj = {
        type:'Text',
        tag:word
      };

      let content =contentStack[contentStack.length - 1];
      if(content){
        content.children.push(obj);
      }else{
        //如果没有，那就是在最上层
        obj.name = word;
        obj.selected = false;
        resArr.push(obj);
      }

      strIndex += word.length?word.length:2;//索引移动
    }
    else{
      console.log('匹配不到：',nuText)
      //匹配不到
      strIndex++
    }
  }

  let resultFormula = [{
    children:[],
    name:"临时占位",
    selected:false,
    type:"Element",
  }]

  let processFormula = []
  let isAllFun = true;//一层全是方法，有其他说明到了显示层

  //从顶层开始
  parseFormula(resArr,resultFormula,processFormula,isAllFun);

  //console.log(contentStack)
  console.log(resArr);
  console.log(resultFormula);
  console.log(processFormula);

  return {
    processFormula:processFormula,
    resultFormula:resultFormula,
  };
}
