import { setEntityFieldValue } from "../../../src/utils/util";

export interface ScanRuleSet {
  [key: string]: { outs: any[]; adaptations: any[] }
}
export function formatScanRuleSets(ruleList: any[]) {
  const scanRuleSets: ScanRuleSet = {}
  // 从配置的解析规则中获取所有使用的条码解析规则， （因为有的配置的是规则分组，并且有可能值设置只使用了分组中的某几个规则，）
  // 输出为 {规则编码：[ outs:[{returnedValue:'返回值的编码',pageVariable:'设置到'}], adaptations:[] ]} 的结构
  // 获取到这个结构后，再去后端调用，获取规则的详细信息(适配条件，输出字段的匹配规则)
  ruleList.forEach((ruleSet: any) => {
    if (ruleSet.type === 'group') {
      // 当时规则组时，需要获取每条值设置的规则，并存放到scanRuleSets
      ruleSet.outs.forEach((valueSet: any) => {
        if (!scanRuleSets[valueSet.ruleCode]) {
          scanRuleSets[valueSet.ruleCode] = { outs: [], adaptations: [] }
        }
        scanRuleSets[valueSet.ruleCode].outs.push(valueSet)
      })
    } else {
      scanRuleSets[ruleSet.code] = { outs: ruleSet.outs, adaptations: [] }
    }
  })
  return packageScanRuleSets(scanRuleSets)
}

function packageScanRuleSets(scanRuleSets: ScanRuleSet) {
  //  获取规则的详细信息(适配条件，输出字段的匹配规则)
  return new Promise((resolve, reject) => {
    //
    if (Object.keys(scanRuleSets).length > 0) {
      //  Object.keys(scanRuleSets) 为当前配置使用的所有规则的编码
      window.$vueApp.config.globalProperties.$http
        .post(
          window['$vueApp'].config.globalProperties.baseAPI +
            '/dc/setting-barcode-analysis/by-codes',
          Object.keys(scanRuleSets)
        )
        .then((res: any) => {
          res.forEach((rule: any) => {
            // 遍历所有的规则，看哪些规则的输出字段需要设值，因为有可能配置的规则中只使用了部分输出字段
            const ruleOuts = JSON.parse(rule.barcodeAnalysisOuts)
            // 获取当前输入框配置的输出字段编码
            const needOutsFields = new Set()
            // 解析规则配置的"返回值编码（来自条码解析规则定义的输出字段，唯一值）"字段和"设置到"字段的映射
            const outsFiledsSet: any = {}
            scanRuleSets[rule.code].outs.forEach((valueSet: any) => {
              needOutsFields.add(valueSet.returnedValue)
              outsFiledsSet[valueSet.returnedValue] = valueSet.pageVariable
            })
            const filteredOutsField: any[] = []
            ruleOuts.forEach((outFiled: any) => {
              if (needOutsFields.has(outFiled.code)) {
                // 设置输出字段 需要设置到的变量
                outFiled.pageVariable = outsFiledsSet[outFiled.code]
                filteredOutsField.push(outFiled)
              }
            })
            scanRuleSets[rule.code].outs = filteredOutsField
            // 适配条件
            scanRuleSets[rule.code].adaptations = JSON.parse(rule.barcodeAnalysisAdaptations)
            resolve(scanRuleSets)
          })
        })
    } else {
      resolve(null)
    }
  })
}

/**
 * 解析扫描值
 * @param obj
 * return {value:扫描值,params:{},scanSet:{}}
 */
export function analysisScanValue(scanValue: any, scanRuleSets: ScanRuleSet) {
  if (!scanValue || !scanRuleSets) {
    return null
	}
  const scanSets = Object.values(scanRuleSets)
  for (let i = 0; i < scanSets.length; i++) {
    const scanSet: any = scanSets[i]
    //检查是否匹配
    const adaptations = scanSet.adaptations
    let validStr = ''
    for (let k = 0; k < adaptations.length; k++) {
      const adap = adaptations[k]
      const indexs = _getScanIndexs(scanValue, adap.startIndex, adap.endIndex)
      const startIndex = indexs[0]
      const endIndex = indexs[1]
      let paramValue = scanValue.substring(startIndex, endIndex)
      let compareValue = adap.value
      //比较条件为times时,把operate设置为==
      let operate = adap.operate
      if (operate == 'times') {
        //出现的次数
        const realValue = paramValue.split(compareValue == undefined ? '' : compareValue).length - 1
        //替换为需要比较的次数
        compareValue = realValue
        paramValue = adap.times
        operate = '='
      }

      if (isNaN(paramValue) || isNaN(compareValue)) {
        paramValue = "'" + paramValue + "'"
        compareValue = "'" + compareValue + "'"
      }
      if (adap.leftBracket) {
        validStr += adap.leftBracket
      }
      if (operate == '<>') {
        operate = '!='
      } else if (operate == '=') {
        operate = '=='
      }
      if (operate == 'include' || operate == 'notinclude') {
        validStr += paramValue + '.indexOf(' + compareValue + ')'
        if (operate == 'include') {
          validStr += '>-1'
        } else {
          validStr += '<0'
        }
      } else {
        validStr += paramValue + operate + compareValue
      }
      if (adap.rightBracket) {
        validStr += adap.rightBracket
      }
      if (adap.joinStr && k + 1 < adaptations.length) {
        const joinStr = adap.joinStr == 'and' ? '&&' : '||'
        validStr += joinStr
      }
    }
    let res = false
    if (validStr) {
      try {
        console.log('validStr', validStr)
        res = eval('(' + validStr + ')')
        console.log('res', res)
      } catch (e) {
        console.log(e)
      }
    } else {
      res = true //没有规则表示都符合
    }
    //如果符合条件时,后续规则不验证
    if (res) {
      return executeAnalysisForScan(scanValue, scanSet)
    }
  }
  return null
}

/**
 * 处理条码解析
 * @param obj
 */
function executeAnalysisForScan(scanValue: any, scanSet: any) {
  if (!scanSet || !scanValue) {
    return
  }
  //解析获取指定的值
  const outs = scanSet.outs
  const params: any = {}
  outs.forEach((outJson: any) => {
    const fieldName = outJson.fieldName
    if (outJson.fixedValue != undefined) {
      params[fieldName] = outJson.fixedValue
    } else {
      let pValue = scanValue
      //分隔符后取值
      if (outJson.splitChar && outJson.splitNum) {
        const splitChar = outJson.splitChar == '|' ? outJson.splitChar : outJson.splitChar
        const strs = scanValue.split(splitChar)
        const splitNum = outJson.splitNum < 1 ? 1 : outJson.splitNum
        console.log(pValue, splitChar, strs, splitNum)
        if (splitNum <= strs.length) {
          pValue = strs[splitNum - 1]
        } else {
          pValue = ''
        }
      }
      //检查第二次分隔符后取值
      if (outJson.splitChar2 && outJson.splitNum2) {
        const splitChar2 = outJson.splitChar2 == '|' ? outJson.splitChar2 : outJson.splitChar2
        const strs: any = pValue.split(splitChar2)
        const splitNum2 = outJson.splitNum2 < 1 ? 1 : outJson.splitNum2
        console.log(pValue, splitChar2, strs, splitNum2)
        if (splitNum2 <= strs.length) {
          pValue = strs[splitNum2 - 1]
        } else {
          pValue = ''
        }
      }
      //有值时,判断是否有截取
      if (pValue.length > 0) {
        const indexs = _getScanIndexs(pValue, outJson.startIndex, outJson.endIndex)
        const startIndex = indexs[0]
        const endIndex = indexs[1]
        pValue = pValue.substring(startIndex, endIndex)
      }
      //获取值
      params[fieldName] = pValue
    }
  })
  return { value: scanValue, params: params, scanSet: scanSet }
}

/**
 * 获取有效的索引位置
 * @param value
 * @param startIndex
 * @param endIndex
 */
function _getScanIndexs(value: any, startIndex: any, endIndex: any) {
  startIndex = startIndex == undefined ? 0 : startIndex - 1
  startIndex = startIndex < 0 ? 0 : startIndex
  startIndex = startIndex > value.length - 1 ? value.length - 1 : startIndex
  endIndex = endIndex == undefined ? value.length : endIndex
  endIndex = endIndex > value.length ? value.length : endIndex
  endIndex = endIndex < 1 ? 1 : endIndex
  if (endIndex < startIndex) {
    endIndex = startIndex
  }
  return [startIndex, endIndex]
}

export function setScanAnalysisValue(entity: any, scanSet: any, params: any) {
  if (!scanSet) {
    return
  }
  const outs = scanSet.outs
  outs.forEach((outField: any) => {
    const fieldName = outField.fieldName
    const value = params[fieldName]
    let variableName = outField.pageVariable
    if (variableName && variableName.indexOf('${')>=0) {
      variableName = variableName.substring(2, variableName.length - 1)
    }
    
    setEntityFieldValue(entity, variableName, value)
  })
}
