package clear

import (
	qu "qfw/util"
	"regexp"
	"strings"
)

var SpecialSymbols map[string]interface{}
var SymmetricMap map[string]string
var AsyReg, AllReg, MesReg *regexp.Regexp
var CommonWords *regexp.Regexp      //通用词正则
var SymField map[string]interface{} //对称符号过滤字段
var AsyField map[string]interface{} //特殊符号过滤字段
var MesField map[string]interface{} //乱码过滤字段
var SymInterCon []string            //对称符号中间内容处理
var SymmetricDelete map[string]bool //对称符号之间的内容是否删除

func init() {
	qu.ReadConfig("./res/specialsymbols.json", &SpecialSymbols)
	if SymmetricDelete == nil {
		SymmetricDelete = map[string]bool{}
	}
	//通用词
	cw, _ := SpecialSymbols["commonwords"].(string)
	CommonWords = regexp.MustCompile(cw)
	//对称符号
	tmp1 := SpecialSymbols["symmetric"].(map[string]interface{})
	SymField = tmp1["field"].(map[string]interface{})
	symmetricArr := tmp1["symbol"].([]interface{})
	SymmetricMap = make(map[string]string)
	allSymbol := ""
	for _, val := range symmetricArr { //SymmetricMap
		symap := val.(map[string]interface{})
		tmpArr := qu.ObjArrToStringArr(symap["text"].([]interface{}))
		isdelete, _ := symap["symdelete"].(bool) //对称符号之间的内容是否删除
		s1 := strings.Replace(tmpArr[0], "\\", "", -1)
		s2 := strings.Replace(tmpArr[1], "\\", "", -1)
		SymmetricDelete[s1] = isdelete
		SymmetricDelete[s2] = isdelete
		allSymbol = tmpArr[0] + tmpArr[1] + allSymbol
		SymmetricMap[s2] = s1
	}
	allSymbol = "[" + allSymbol + "]"
	AllReg = regexp.MustCompile(allSymbol)
	//特殊符号
	tmp2 := SpecialSymbols["asymmetric"].(map[string]interface{})
	AsyField = tmp2["field"].(map[string]interface{})
	asymmetricArr := qu.ObjArrToStringArr(tmp2["symbol"].([]interface{}))
	asymmetric := ""
	for _, val := range asymmetricArr {
		asymmetric = asymmetric + val
	}
	if asymmetric != "" {
		asymmetric = "[" + asymmetric + "]"
		AsyReg = regexp.MustCompile(asymmetric)
	}
	//乱码
	tmp3 := SpecialSymbols["messycode"].(map[string]interface{})
	MesField = tmp3["field"].(map[string]interface{})
	messycodeArr := qu.ObjArrToStringArr(tmp3["symbol"].([]interface{}))
	messycodeStr := ""
	for _, v := range messycodeArr {
		messycodeStr = messycodeStr + v
	}
	if messycodeStr != "" {
		messycodeStr = "[" + messycodeStr + "]"
	}
	MesReg = regexp.MustCompile(messycodeStr)
	SymInterCon = qu.ObjArrToStringArr(SpecialSymbols["symintercon"].([]interface{}))

	//	text := []rune("江西省建筑工程建设监理有限公司关于《江西泰和乌鸡林下生态养殖系统》申报第五批中国重要农业文化遗产与《泰和乌鸡产业（2020-2030）发展规划》编制）竞争性磋商招标公告（第二次）")
	//	for i := 1; i <= 2; i++ {
	//		text = AnotherRemoveStart(text)
	//		qu.Debug(string(text))
	//	}
}

//去除首尾空格、换行、回车
func RemoveHESpace(text string) string {
	defer qu.Catch()
	if len(text) > 0 {
		tmp := cutSpace.ReplaceAllString(strings.Replace(text, "　", " ", -1), "")
		text = replaceSymbol(tmp, spaces)
	}
	return text
}

func RemoveHESymCode(val string) string {
	defer qu.Catch()
	text := []rune(val)
	if len(text) > 0 {
		for i := 1; i <= 2; i++ { //循环处理两次
			if len(text) > 0 {
				//text = RemoveStart(i, text)
				text = AnotherRemoveStart(text)
			}
		}
	}
	//单引号和双引号特殊处理
	text = DealSinAndDouQuotes(text)
	return string(text)
}

func RemoveStart(i int, text []rune) []rune {
	defer qu.Catch()
	if len(text) > 0 {
		pairedIndex := make(map[int]int)
		symbolIndex := make(map[string][]int) //记录符号和当前索引位置
		surplusMax := -1                      //记录多余的反符号最大值
		positiveMax := -1                     //记录多余的正符号最大值
		removeLength := 0
		length := len(text)
		for index, t := range text {
			now := AllReg.FindString(string(t))
			if len(now) > 0 { //匹配到符号
				if index == 0 {
					lock.Lock()
					fdSymbol := SymmetricMap[now]
					lock.Unlock()
					if fdSymbol != "" { //去除第一个反符号
						text = text[1:len(text)]
					} else if len(now) > 0 { //第一个是正符号，记录索引位置
						tmpArr := []int{index}
						symbolIndex[now] = tmpArr
					}
				} else {
					lock.Lock()
					fdSymbol := SymmetricMap[now]
					lock.Unlock()
					if fdSymbol != "" && fdSymbol != now { //反向符号，找出对称的正向符号(fdSymbol != now:处理正反向符号是"或者')
						tmp := symbolIndex[fdSymbol]
						if len(tmp) == 0 { //多出来的反向符号,记录最大值
							if index > surplusMax {
								surplusMax = index
							}
						} else {
							nowIndex := tmp[len(tmp)-1]              //索引位置
							symbolIndex[fdSymbol] = tmp[:len(tmp)-1] //匹配索引位置后，删除之前的记录
							if len(symbolIndex[fdSymbol]) == 0 {
								delete(symbolIndex, fdSymbol)
							}
							//将成对的符号的index记录，
							if index == length-1 {
								pairedIndex[index] = nowIndex
							}
							pairedIndex[nowIndex] = index
						}
					} else { //正向符号,加入symbolIndex记录索引
						tmpArr := []int{}
						if len(symbolIndex[now]) > 0 { //有该符号的索引位置
							tmpArr = symbolIndex[now]
							tmpArr = append(tmpArr, index)
						} else { //没有该符号的索引位置
							tmpArr = []int{index}
						}
						symbolIndex[now] = tmpArr
					}
				}
			}
		}
		if i == 1 || i == 3 { //第一次清理首尾符号
			if len(symbolIndex) != 0 { //多余的正符号索引位置
				for _, arr := range symbolIndex {
					for j, l := range arr {
						if j == 0 && l == 0 {
							text = text[1:] //删除text开头的正向符号
							removeLength = 1
						}
					}
				}
			}
			firstOpposite := pairedIndex[0]
			if firstOpposite != 0 {
				text = text[firstOpposite+1:]
				removeLength = firstOpposite + 1
			}
			lastOpposite := pairedIndex[length-1]
			if lastOpposite > 0 { //有对称的正向符号,删除其中间内容
				text = text[:lastOpposite-removeLength]
			} else if surplusMax == length-1 { //没有对称，只删除最后一个反符号
				text = text[:length-1-removeLength]
			}
		}
		if i == 2 { //第二次清理多余的符号
			if len(symbolIndex) != 0 { //多余的正符号索引位置
				for _, arr := range symbolIndex {
					for _, l := range arr {
						if positiveMax < l {
							positiveMax = l
						}
					}
				}
			}
			//有多余反向符号，删除之前部分 surplusMax所有多余反向符号的最大索引
			if surplusMax != -1 && surplusMax < positiveMax {
				text = text[surplusMax+1:]
				//多余正符号删除之后部分（优先删除反符号之前部分）//发发发发发发发发[发)发发发发发发发发发发发发
				if positiveMax != -1 && surplusMax < positiveMax {
					text = text[:positiveMax-surplusMax-1]
				}
			} else if surplusMax != -1 && surplusMax > positiveMax {
				text = text[surplusMax+1:]
			}
		}
	}
	return text
}

//乱码
func RemoveMessycode(text string) string {
	defer qu.Catch()
	if len(text) > 0 {
		text = MesReg.ReplaceAllString(text, "")
	}
	return text
}

//特殊符号
func RemoveAsy(text string) string {
	defer qu.Catch()
	if len(text) > 0 {
		textRune := []rune(text)
		first := string(textRune[0])
		last := string(textRune[len(textRune)-1])
		if AsyReg.MatchString(first) {
			textRune = textRune[1:]
		}
		if len(textRune) > 0 && AsyReg.MatchString(last) && len(text) > 0 {
			textRune = textRune[:len(textRune)-1]
		}
		text = string(textRune)
	}
	return text
}

func OtherClean(field, text string) string {
	text = RemoveHESpace(text) //去除首尾空格
	if AsyField[field] != nil {
		text = RemoveAsy(text) //特殊符号
	}
	if SymField[field] != nil { //对称符号
		text = RemoveHESymCode(text)
	}
	if MesField[field] != nil { //乱码
		text = RemoveMessycode(text)
	}
	text = RemoveHESpace(text) //去除首尾空格
	return text
}

func AnotherRemoveStart(text []rune) []rune {
	defer qu.Catch()
	if len(text) > 0 {
		delstrarr := []string{}
		pairedIndex := make(map[int]int)      //对称符号索引位置
		symbolIndex := make(map[string][]int) //记录符号和当前索引位置
		surplusMax := -1                      //记录多余的反符号最大值
		positiveMax := -1                     //记录多余的正符号最大值
		removeLength := 0
		//tmpLength := 0 //记录对称符号间内容的长度
		nb := 0
		length := len(text)
		for index, t := range text {
			now := AllReg.FindString(string(t))
			if len(now) > 0 { //匹配到符号
				if index == 0 {
					lock.Lock()
					fdSymbol := SymmetricMap[now]
					lock.Unlock()
					if fdSymbol != "" { //去除第一个反符号
						text = text[1:len(text)]
					} else if len(now) > 0 { //第一个是正符号，记录索引位置
						tmpArr := []int{index}
						symbolIndex[now] = tmpArr
					}
				} else {
					lock.Lock()
					fdSymbol := SymmetricMap[now]
					lock.Unlock()
					if fdSymbol != "" { //反向符号，找出对称的正向符号
						tmp := symbolIndex[fdSymbol]
						if len(tmp) == 0 { //多出来的反向符号,记录最大值
							if index > surplusMax {
								surplusMax = index
							}
						} else {
							nowIndex := tmp[len(tmp)-1]              //索引位置
							symbolIndex[fdSymbol] = tmp[:len(tmp)-1] //匹配索引位置后，删除之前的记录
							if len(symbolIndex[fdSymbol]) == 0 {
								delete(symbolIndex, fdSymbol)
							}
							//将成对的符号的index记录，
							if index == length-1 {
								pairedIndex[index] = nowIndex
							}
							pairedIndex[nowIndex] = index
							//tmpLength = tmpLength + len(text[nowIndex:index+1])
						}
					} else { //正向符号,加入symbolIndex记录索引
						tmpArr := []int{}
						if len(symbolIndex[now]) > 0 { //有该符号的索引位置
							tmpArr = symbolIndex[now]
							tmpArr = append(tmpArr, index)
						} else { //没有该符号的索引位置
							tmpArr = []int{index}
						}
						symbolIndex[now] = tmpArr
					}
				}
			}
		}
		//处理文本中有对称符号的情况
		tmptext, ismatch, delindex := DelContext(pairedIndex, text)
		if ismatch {
			return tmptext
		}
		if len(delindex) > 0 {
			for s, e := range delindex {
				delstrarr = append(delstrarr, string(text[s:e+1]))
			}
		}
		//例：“教育部高等教育教学评估中心数据中心升级改造”项目 -> 教育部高等教育教学评估中心数据中心升级改造项目
		if surplusMax == -1 && positiveMax == -1 {
			i := pairedIndex[0]
			if i > 0 {
				end := text[i+1:]
				for _, r := range SymInterCon {
					if r == string(end) {
						tmptext := text[1:i]
						tmptext = append(tmptext, end...)
						return []rune(tmptext)
					}
				}
			}
		}
		if len(symbolIndex) != 0 { //多余的正符号索引位置
			for _, arr := range symbolIndex {
				for j, l := range arr {
					if j == 0 && l == 0 {
						text = text[1:] //删除text开头的正向符号
						removeLength = 1
						nb = nb + 1
					}
					if positiveMax < l { //记录最大正向索引
						positiveMax = l
					}
				}
			}
		}
		firstOpposite := pairedIndex[0]                             //第一个正符号对应反符号的位置
		if firstOpposite != 0 && SymmetricDelete[string(text[0])] { //删除开头由对称符号包括的内容：(2019年大兴)新城地（区公共厕）所及附属(改造发斯蒂芬)-->新城地（区公共厕）所及附属(改造发斯蒂芬)
			text = text[firstOpposite+1:]
			removeLength = firstOpposite + 1
			nb = nb + removeLength
		}
		lastOpposite := pairedIndex[length-1] //最后一个符号
		lenew := len(text)
		if lastOpposite > 0 && lenew > 0 && SymmetricDelete[string(text[lenew-1])] { //删除结尾由对称符号包括的内容：新城地（区公共厕）所及附属(改造发斯蒂芬)-->新城地（区公共厕）所及附属
			//na = length - lastOpposite
			text = text[:lastOpposite-removeLength]
		} else if surplusMax == length-1 { //没有对称，只删除最后一个反符号
			text = text[:length-1-removeLength]
			//na = na + 1
		}
		//有多余反向符号，删除之前部分 surplusMax所有多余反向符号的最大索引
		if surplusMax != -1 && surplusMax > firstOpposite && surplusMax < length-1 {
			if (lastOpposite > 0 && surplusMax < lastOpposite) || (lastOpposite == 0) { //发发发发发发}发(发发发发发发)
				beforedel := text
				deleteindex := surplusMax - nb
				text = text[surplusMax-nb+1:]
				nb = surplusMax + 1
				//非对称符号清理后判断剩余部分长度小于6，取删除部分
				if len(CommonWords.ReplaceAllString(string(text), "")) < 6 { //{"_id":ObjectId("5d42425ba5cb26b9b7850640")}
					result := beforedel[:deleteindex]
					return result
				}
			}
		}

		//多余正符号删除之后部分（优先删除反符号之前部分）//（发发{发发）发发发发发发发发发发发发发发发（发{发）
		if positiveMax != -1 && positiveMax != 0 && positiveMax > surplusMax && positiveMax > firstOpposite { ////发发发发发发]发发{
			if (lastOpposite > 0 && positiveMax < lastOpposite) || (lastOpposite == 0) { //发发发发发发发发{发发发发发（发发）
				text = text[:positiveMax-nb]
			}
		}
		if len(delstrarr) > 0 {
			for _, rep := range delstrarr {
				lenew := len(text)
				if lenew > 0 && strings.HasPrefix(rep, string(text[0])) { //要清理的内容是开头和结尾部分，清理
					text = []rune(strings.Replace(string(text), rep, "", -1))
				}
				lenew = len(text)
				if lenew > 0 && strings.HasSuffix(rep, string(text[lenew-1])) {
					text = []rune(strings.Replace(string(text), rep, "", -1))
				}
			}
		}
	}
	return text
}

func DelContext(pairedIndex map[int]int, text []rune) ([]rune, bool, map[int]int) {
	length := 0
	var result []rune
	ismatch := false
	delindex := map[int]int{}
	for s, e := range pairedIndex {
		if s < e {
			nowsym := string(text[s])
			if SymmetricDelete[nowsym] { //删除该对称中的内容
				delindex[s] = e
				continue
			}
			var tmp []rune
			tmp = text[s+1 : e]
			if len(tmp) > 2 { //排除对称符号中只有["工程","项目","采购","服务","监理","施工","设计"]
				for _, r := range SymInterCon {
					if strings.HasSuffix(string(tmp), r) && len(tmp) > length && len([]rune(strings.Replace(string(tmp), r, "", -1))) > 6 {
						ismatch = true
						result = tmp
						length = len(tmp)
					}
				}
			}
		}
	}

	return result, ismatch, delindex
}

func DealSinAndDouQuotes(text []rune) []rune {
	stext := string(text)
	for _, v := range []string{"\"", "'"} {
		sReg := regexp.MustCompile(v)
		sIndex := sReg.FindAllStringIndex(stext, -1)
		length := len(sIndex)
		if length > 0 {
			if len(sIndex)%2 == 0 { //符号是成对出现的
				si := sIndex[0][0]
				ei := sIndex[length-1][1]
				//val := stext[si:ei]
				if si == 0 { //以单双引号开头
					end := stext[ei:]
					for _, r := range SymInterCon {
						if r == string(end) {
							tmptext := stext[1 : ei-1]
							tmptext += end
							return []rune(tmptext)
						}
					}
				}
			} else { //符号是非成对出现的(将最后一个符号前内容清理掉)
				i := sIndex[length-1][1]
				return []rune(stext[i:])
			}
		}
	}
	return text
}
