import Vue from 'vue'
import RequestManager from '~/service/RequestManager.js';

let _vm = new Vue()
export default class Utils {
  static toDepthObject (obj) {
    var target = {};
    for (var key in obj) {
      var keyArr = key.split("_"); //以下划线或分割
      var tempobj = target;
      for (var i = 0; i < keyArr.length - 1; i++) {
        if (tempobj[keyArr[i]])
          tempobj = tempobj[keyArr[i]];
        else {
          tempobj[keyArr[i]] = {};
          tempobj = tempobj[keyArr[i]];
        }
      }
      //给叶子元素赋值
      tempobj[keyArr[keyArr.length - 1]] = obj[key];
    }
    return target;
  }
  static flatObject (obj, target, pkey) {
    target = target || {};
    for (var key in obj) {
      var nkey = pkey ? pkey + "_" + key : key;
      if (!obj[key])
        target[nkey] = obj[key];
      else if (obj[key] instanceof Array)
        target[nkey] = obj[key];
      else if (obj[key] instanceof Date)
        target[nkey] = obj[key];
      else if (typeof obj[key] == "object")
        if (Object.keys(obj[key]).length === 3 && obj[key].hasOwnProperty("empty") && obj[key].hasOwnProperty("keepsort") && obj[key].hasOwnProperty("rows")) {
          target[nkey] = obj[key];
        } else {
          Utils.flatObject(obj[key], target, nkey); //递归赋值
        }
      else
        target[nkey] = obj[key];
    }
    return target;
  }
  static copyValueFromVO (model, vo) {
    for (let key in vo) {
      // console.log(key);
      // console.log(vo[key]);
      if (model[key] != undefined && vo[key] != null) {
        //遍历参数的键
        if (typeof vo[key] === "object") {
          // console.log("11111");
          this.copyValueFromVO(model[key], vo[key]); //值是对象就再次调用函数
        } else {
          // console.log("44444");
          model[key] = vo[key]; //基本类型直接复制值
        }
      }
    }
  }

  static showXml (str) {
    var text = str
    //去掉多余的空格
    text = '\n' + text.replace(/(<\w+)(\s.*?>)/g, function ($0, name, props) {
      return name + ' ' + props.replace(/\s+(\w+=)/g, " $1");
    }).replace(/>\s*?</g, ">\n<");

    //把注释编码
    text = text.replace(/\n/g, '\r').replace(/<!--(.+?)-->/g, function ($0, text) {
      var ret = '<!--' + escape(text) + '-->';
      return ret;
    }).replace(/\r/g, '\n');

    //调整格式
    var rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/mg;
    var nodeStack = [];
    var output = text.replace(rgx, function ($0, all, name, isBegin, isCloseFull1, isCloseFull2, isFull1, isFull2) {
      var isClosed = (isCloseFull1 == '/') || (isCloseFull2 == '/') || (isFull1 == '/') || (isFull2 == '/');
      var prefix = '';
      if (isBegin == '!') {
        prefix = Utils.getPrefix(nodeStack.length);
      }
      else {
        if (isBegin != '/') {
          prefix = Utils.getPrefix(nodeStack.length);
          if (!isClosed) {
            nodeStack.push(name);
          }
        }
        else {
          nodeStack.pop();
          prefix = Utils.getPrefix(nodeStack.length);
        }
      }
      var ret = '\n' + prefix + all;
      return ret;
    });

    var prefixSpace = -1;
    var outputText = output.substring(1);

    //把注释还原并解码,调格式
    outputText = outputText.replace(/\n/g, '\r').replace(/(\s*)<!--(.+?)-->/g, function ($0, prefix, text) {
      if (prefix.charAt(0) == '\r')
        prefix = prefix.substring(1);
      text = unescape(text).replace(/\r/g, '\n');
      var ret = '\n' + prefix + '<!--' + text.replace(/^\s*/mg, prefix) + '-->';
      return ret;
    });
    outputText = outputText.replace(/\s+$/g, '').replace(/\r/g, '\r\n');
    return outputText
  }

  static getPrefix (prefixIndex) {
    var span = '    ';
    var output = [];
    for (var i = 0; i < prefixIndex; ++i) {
      output.push(span);
    }
    return output.join('');
  }

  /**
   * 执行checkAll之后根据返回的错误信息定位
   * @param {Object} fieldErrors 错误信息
   * @param {Array} formFields 表单字段
   * @returns El-Tab实例
   */
  static positioningErrorMsg (fieldErrors, formFields) {
    if (fieldErrors == undefined || fieldErrors == null || Object.keys(fieldErrors).length === 0) {
      return null;
    }
    let firstErrorItem = null
		// 顺序
    for (let i = 0; i < formFields.length; i++) {
			const field = formFields[i];
			const fieldError = fieldErrors[field.prop];
			field.validateState = null
			field.validateMessage = null;
      if (fieldError) {
        field.validateState = 'error';
				field.validateMessage = fieldError;
        if (!firstErrorItem) {
          firstErrorItem = field
        }
      }
    }
    let firstErrorTab = null, collapsePanel = null
    if (firstErrorItem) {
      let parentVC = firstErrorItem
      while (!firstErrorTab) {
        const vcName = parentVC.$options.componentName
        // 没有Tabs的表单
        if (vcName === "ElForm") {
          break;
        }
        if (vcName === "ElTabPane") {
          firstErrorTab = parentVC
          break;
        }
        if (vcName === "ElCollapseItem") {
          collapsePanel = parentVC;
        }
        parentVC = parentVC.$parent;
      }
      if (firstErrorTab) {
        const tabs = firstErrorTab.$parent
        tabs.currentName = firstErrorTab.name
      }
      if (collapsePanel && collapsePanel.collapse.activeNames.indexOf(collapsePanel.name) < 0) {
        collapsePanel.collapse.activeNames.push(collapsePanel.name)
      }
      setTimeout(() => {
        // 滚动到指定节点
        firstErrorItem.$el.scrollIntoView({
          // 值有start,center,end,nearest,当前显示在视图区域中间
          block: 'center',
          // 值有auto、instant,smooth,缓动动画(当前是慢速的)
          behavior: 'smooth'
        })
      }, 0)
    }
    return firstErrorTab;
  }

  /**
   * 表单自身的validate方法执行后,错误提示定位
   * @param {Array} formFields 表单字段
   * @returns El-Tab实例
   */
  static formValidateTips (formFields) {
    let firstErrorItem = null
    // 顺序
    for (let i = 0; i < formFields.length; i++) {
      const field = formFields[i];
      if (field.validateState === 'error') {
        firstErrorItem = field
        break;
      }
    }
    let firstErrorTab = null, collapsePanel = null
    if (firstErrorItem) {
      let parentVC = firstErrorItem
      while (!firstErrorTab) {
        const vcName = parentVC.$options.componentName
        // 没有Tabs的表单
        if (vcName === "ElForm") {
          break;
        }
        if (vcName === "ElTabPane") {
          firstErrorTab = parentVC
          break;
        }
        if (vcName === "ElCollapseItem") {
          collapsePanel = parentVC;
        }
        parentVC = parentVC.$parent;
      }
      if (firstErrorTab) {
        const tabs = firstErrorTab.$parent
        tabs.currentName = firstErrorTab.name
      }
      if (collapsePanel && collapsePanel.collapse.activeNames.indexOf(collapsePanel.name) < 0) {
        collapsePanel.collapse.activeNames.push(collapsePanel.name)
      }
      setTimeout(() => {
        // 滚动到指定节点
        firstErrorItem.$el.scrollIntoView({
          // 值有start,center,end,nearest,当前显示在视图区域中间
          block: 'center',
          // 值有auto、instant,smooth,缓动动画(当前是慢速的)
          behavior: 'smooth'
        })
      }, 0)
    }
    return firstErrorTab;
  }

  static reflectCheck (key) {
    return async function (rule, value, callback) {
      //调用具体的check
      const res = await this.executeCheck(key)
      if (Object.hasOwnProperty.call(res.fieldErrors, key)) {
        callback(new Error(res.fieldErrors[key]))
      } else {
        callback();
      }
    }
  }

  static generateUUID () {
    var d = new Date().getTime();
    if (window.performance && typeof window.performance.now === "function") {
      d += performance.now(); //use high-precision timer if available
    }
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
      var r = (d + Math.random() * 16) % 16 | 0;
      d = Math.floor(d / 16);
      return (c == 'x' ? r : (r & 0x3 | 0x8)).toString(16);
    });
    return uuid;
  }

  static copyCustomFromModel (customModel, model) {
    for (let key in customModel) {
      if (typeof customModel[key] == "object") {
        this.copyCustomFromModel(customModel[key], model[key])
      } else {
        customModel[key] = model[key]
      }
    }
  }
  // 值分别为:Number、String、Boolean、Null、Undefined、Symbol、Object、Array、Function、Date
  static typeOf (data) {
    return Object.prototype.toString.call(data).slice(8, -1);
  }
  // 把后端返回给前端的数据,和前端定义的model进行赋值
  static copyValueFromVoData (model, data) {
    if (data != undefined && data != null) {
      let keysList = Object.keys(model)
      keysList.map((key) => {
        if (data[key] !== undefined && data[key] !== null) {
          if (this.typeOf(model[key]) === 'Object') {
            this.copyValueFromVoData(model[key], data[key])
          } else {
						model[key] = data[key];
          }
        }
			})
      // 处理复制modifySet的问题
      if (data['modifySet'] && data['modifySet'].length > 0) {
				_vm.$set(model, 'modifySet', data['modifySet'])
			}
			if (data['markSet'] && data['markSet'].length > 0) {
				_vm.$set(model, 'markSet', data['markSet'])
			}
			if (data['markSetX'] && data['markSetX'].length > 0) {
				_vm.$set(model, 'markSetX', data['markSetX'])
			}
    }
	}
	// 格式化ptspta列表
	static formatPtspta (ptsptaData, fn) {
		let list = []
		if (ptsptaData) {
			let tempData = Object.keys(ptsptaData)
			tempData.map((item) => {
				if (ptsptaData[item] && ptsptaData[item].pts && (ptsptaData[item].pts.extkey||ptsptaData[item].pts.bankno)) {
					list.push(fn(ptsptaData[item]))
				}
			})
		}
		return list
	}
	// 前端导出excel
	static exportToExcel (datas, excelName, sheetName) {
		const XLSX = require('xlsx') 
		let workSheet = XLSX.utils.aoa_to_sheet(datas)
		let workBook = XLSX.utils.book_new()
		let sn = 'sheet1'
		if (sheetName) {
			sn = sheetName
		}
		XLSX.utils.book_append_sheet(workBook, workSheet, sn)
		XLSX.writeFile(workBook, excelName)
  }
  

  static testSwiftZ(valStr){
    for(let i = 0;i<valStr.length;i++){
      let c = valStr.charAt(i)
      if(c !='\n' &&  c!='\r' && SWIFTZ_CHARS.indexOf(c)<0){
        return false
      }
    }
    return true
  }

  static getGidTextValidator(row,col){
    return function(rule,value,callback){
      let arr = Utils.convertGidHtmlRowAndCol(col,value)
      if(arr.length > row){
        return callback(new Error(`要求${row}*${col},格式化后会有${arr.length}行的文本,超出${arr.length - row}行`))
      }
      callback()
    }
  }

  //格式化文本
  static convertGidHtmlRowAndCol(col,text){
    text = this.convertGidHtmlToPlainText(text)
    return this.convertCol(col,text)
  }

  static convertGidHtmlToPlainText(text){
    return text
    .replace(/<br\/?>/g,"\n")  //br换行  
    .replace(/<[^>]+>/g,"")    //起始会计字符去掉
      .replace(/<\/(p|div|h\d|li)>/g,"\n") //块级元素替换为换行
      .replace(/<\/\w+>/g,"\n")  //内联元素结尾标签去掉
      .replace("\r\n","\n")
      .replace("\n{2,}","\n") //连续换行只保留一行
      .trim()
  }

  static convertCol(col,text){
    let srcArr = text.split(/[\r\n]{1,2}/g);
    let newArr = []
    for(let i=0;i<srcArr.length;i++){
      let arr = this.convertSingleLineCol(col,srcArr[i])
      newArr.push(...arr)
    }
    return newArr
  }


  static convertSingleLineCol(col,text){
    let arr =[]
    let left = text
    let wordBeg = -1;
    while(left.length > col){
      for(let i=0;i<col;i++){
        let cStr = left.charAt(i);
        let preStr = (i > 0 ? left.substring(i - 1, i) : "");
        let nextStr = left.substring(i + 1, i + 2);
        if(/[\w]/g.test(cStr) || (','== cStr && /[\d]/g.test(preStr) && /[\d]/g.test(nextStr)) || ('.'==cStr && /[\d]/g.test(nextStr))){
          if(wordBeg == -1){
            wordBeg = i;
          }
        }else{
          wordBeg = -1
        }
      }
      if(wordBeg > 0){
        let line = left.substring(0,wordBeg).trim() 
        arr.push(line)
        left = left.substring(wordBeg).trim()
        wordBeg = -1
      }else{
        let line = left.substring(0,col).trim()
        arr.push(line)
        if(col <= left.length){
          left = left.substring(col).trim()
        }
      }
    }
    //末尾仍有字符
    if(left && left.trim()){
      arr.push(left.trim())
    }
    return arr
  }
}

export const SWIFTZ_CHARS = " *\r!\"#%&'()+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz{";

export function convertLockMsg(rtnmsg,premsg){
  let msg = premsg||''
  //锁定人是自己,但是交易是别的交易
  if(rtnmsg.data.usrId == window.sessionStorage.userName){
    msg = `当前业务数据已被【${rtnmsg.data.trnLabel}】交易锁定,请先退出该交易`;
  }
  else if (rtnmsg.data && rtnmsg.data.usrId) {
    msg = msg + "锁定人为" + rtnmsg.data.usrId + ",锁定交易为【" + rtnmsg.data.trnLabel+"】"
  }

  return msg
}
//队列模式输出
const requestManager = new RequestManager()
export function syncMsgbox(options){
  return requestManager.pushRequest(this.$msgbox.bind(this,options))
}