package ext

import (
	"github.com/PuerkitoBio/goquery"
	qu "qfw/util"
	"regexp"
	"strings"
)

var FilialeReg1 = regexp.MustCompile("(.{1,3})分(公司|院|校|行)$")
var FilialeReg2 = regexp.MustCompile(".*[(（](.*)[)）].*")
var FilialeReg3 = regexp.MustCompile(".*(集团|公司|大学)(.*)(公司|院|所|校)")

var CleanRegionReg1 = regexp.MustCompile(".*公司")

var FixedTelReg = regexp.MustCompile("0[0-9]{2,3}\\-[2-9][0-9]{6,7}")

var CleanDetailReg1 = regexp.MustCompile("(北京时间)")
var XjbtReg *regexp.Regexp = regexp.MustCompile("^(新疆生产建设兵团|新疆兵团)")
var SensitiveReg = regexp.MustCompile("(上一[条篇]|下一[条篇])[:：].*")

// 取特殊类数据
func GetFilialeByBuyerInfo(buyer string) string {
	if FilialeReg1.MatchString(buyer) {
		return FilialeReg1.FindString(buyer)
	}
	if FilialeReg2.MatchString(buyer) {
		return FilialeReg2.ReplaceAllString(buyer, "${1}")
	}
	if FilialeReg3.MatchString(buyer) {
		return FilialeReg3.ReplaceAllString(buyer, "${2}")
	}

	return ""
}

// 最终确认~指定地域
func ConfirmUniqueRegionInfo(regions map[string]map[string]map[string]string, area *string, city *string, district *string) bool {
	if len(regions) > 1 || len(regions) == 0 {
		return false
	}
	for k, v := range regions {
		*area = k
		if len(v) == 1 {
			for k1, v1 := range v {
				*city = k1
				if len(v1) == 1 {
					for k2, _ := range v1 {
						*district = k2
					}
				}
			}
		}
	}
	if *area != "" && *city != "" && *district != "" {
		return true
	}
	return false
}

// 完整信息
func CompleteRegionInfo(area *string, city *string, district *string) {
	if *area == "北京" {
		*city = "北京市"
		if *district == "北京朝阳" { //特殊情况(北京朝阳中西医结合急诊抢救中心:5a84079740d2d9bbe88bad90)
			*district = "朝阳区"
		}
	} else if *area == "天津" {
		*city = "天津市"
	} else if *area == "上海" {
		*city = "上海市"
	} else if *area == "重庆" {
		*city = "重庆市"
	}
	if *area == "" {
		*area = "全国"
		*city = ""
		*district = ""
	}
}

// 根据词获取所有的地域 ~ 暂时不采用三级简称提取城市
func (e *ExtractTask) takeRegionsFromWords(text string, isAddress bool, isBrief bool, regionsArr *[]map[string]string) {
	//全称匹配
	for pos_full, trie_full := range e.Trie_Fulls {
		if trie_full.Get(text) {
			infoArr := []map[string]string{}
			if pos_full == 0 {
				if province := e.ProvinceMap[text]; province != "" {
					infoArr = append(infoArr, map[string]string{"area": province, "city": "", "district": ""})
					SplicingRegionsInfo(isAddress, regionsArr, infoArr)
				}
			} else if pos_full == 1 {
				if data := e.CityFullMap[text]; data != nil {
					if data.P.Brief != "" && data.Name != "" {
						infoArr = append(infoArr, map[string]string{"area": data.P.Brief, "city": data.Name, "district": ""})
						SplicingRegionsInfo(isAddress, regionsArr, infoArr)
					}
				}
			} else if pos_full == 2 {
				citys := e.DistrictCityMap[text]
				for _, c := range citys {
					if c.P.Brief != "" && c.Name != "" && text != "" {
						infoArr = append(infoArr, map[string]string{"area": c.P.Brief, "city": c.Name, "district": text})
					}
				}
				SplicingRegionsInfo(isAddress, regionsArr, infoArr)
			}
			break
		}
	}
	//简称匹配
	for pos_sim, trie_sim := range e.Trie_Sims {
		if trie_sim.Get(text) {
			infoArr := []map[string]string{}
			if pos_sim == 0 {
				if text != "" {
					infoArr = append(infoArr, map[string]string{"area": text, "city": "", "district": ""})
					SplicingRegionsInfo(isAddress, regionsArr, infoArr)
				}
			} else if pos_sim == 1 {
				if csMap := e.CityBriefMap[text]; csMap != nil {
					if csMap.P.Brief != "" && csMap.Name != "" {
						infoArr = append(infoArr, map[string]string{"area": csMap.P.Brief, "city": csMap.Name, "district": ""})
						SplicingRegionsInfo(isAddress, regionsArr, infoArr)
					}
				}
			} else if pos_sim == 2 {
				if isBrief {
					citysArr := e.DistrictSimAndAll[text]
					for _, full_citys := range citysArr {
						for district, c := range full_citys {
							if c == nil || c.P == nil || c.Name == "" {
								continue
							}
							if c.P.Brief != "" && c.Name != "" && district != "" {
								infoArr = append(infoArr, map[string]string{"area": c.P.Brief, "city": c.Name, "district": district})
							}
						}
						SplicingRegionsInfo(isAddress, regionsArr, infoArr)
					}
				}
			}
			break
		}
	}
}

// 是否拼接数据~且根据地址类~首地域判断
func SplicingRegionsInfo(isAddress bool, regionsArr *[]map[string]string, infoArr []map[string]string) {
	if isAddress {
		if len(*regionsArr) == 0 { //第一次
			for _, info := range infoArr {
				*regionsArr = append(*regionsArr, info)
			}
		} else {
			for _, info := range infoArr {
				area := qu.ObjToString(info["area"])
				city := qu.ObjToString(info["city"])
				isUseful := false
				for _, v := range *regionsArr {
					v_area := qu.ObjToString(v["area"])
					v_city := qu.ObjToString(v["city"])
					if area == v_area {
						if v_city != "" {
							if v_city == city {
								isUseful = true
								break
							}
						} else {
							isUseful = true
							break
						}
					}
				}
				if isUseful {
					*regionsArr = append(*regionsArr, info)
				}
			}
		}
	} else {
		for _, info := range infoArr {
			*regionsArr = append(*regionsArr, info)
		}
	}
}

// 文本取地域   from  1~jsondata文本   2~其他文本
func (e *ExtractTask) GetRegionFromText(text string, regions *map[string]map[string]map[string]string, isAddress bool, isBrief bool, from int) []map[string]interface{} {
	regionValues := []map[string]interface{}{}
	if text == "" {
		return regionValues
	}
	wordsArr := []string{}
	if from == 1 {
		wordsArr = e.Seg_PCD.Cut(text, true)
	} else if from == 2 {
		wordsArr = e.Seg_SV.Cut(text, true)
	}
	//词组清洗
	wordsArr = CleanRegionTextWords(wordsArr)
	regionsArr := []map[string]string{}
	for _, word := range wordsArr {
		e.takeRegionsFromWords(word, isAddress, isBrief, &regionsArr)
	}
	for _, v := range regionsArr {
		area := qu.ObjToString(v["area"])
		city := qu.ObjToString(v["city"])
		district := qu.ObjToString(v["district"])
		UpdateRegionsInfo(area, city, district, regions)
		regionValues = append(regionValues, map[string]interface{}{"area": area, "city": city, "district": district})
	}
	return regionValues
}

// 更新方法
func UpdateRegionsInfo(area, city, district string, regions *map[string]map[string]map[string]string) {
	if (*regions)[area] == nil {
		city_info := map[string]map[string]string{}
		district_info := map[string]string{}
		if city != "" {
			if district != "" {
				district_info[district] = district
			}
			city_info[city] = district_info
		}
		(*regions)[area] = city_info //新增
	} else {
		city_info := (*regions)[area]
		if city != "" {
			district_info := map[string]string{}
			if city_info[city] != nil {
				district_info = city_info[city]
			}
			if district != "" {
				district_info[district] = district
			}
			city_info[city] = district_info
			(*regions)[area] = city_info
		}
	}
}

// 同组合并后合理性校验
func ReasonableGroupRegionInfo(datas map[string]map[string]map[string]string) map[string]map[string]map[string]string {
	if len(datas) > 2 || len(datas) == 0 { //省份超限，无效
		return map[string]map[string]map[string]string{}
	}
	uncity, undistrict := 0, 0
	for _, v := range datas {
		uncity += len(v)
		for _, v1 := range v {
			undistrict += len(v1)
		}
	}

	if uncity > 3 {
		regions_1 := map[string]map[string]map[string]string{}
		for k, v := range datas {
			city_info := map[string]map[string]string{}
			if len(v) == 1 {
				city_info = v
			}
			regions_1[k] = city_info
		}
		//计算当前
		uncity_district := 0
		for _, v := range regions_1 {
			for _, v1 := range v {
				uncity_district += len(v1)
			}
		}
		if uncity_district > 3 {
			regions_2 := map[string]map[string]map[string]string{}
			for k, v := range regions_1 {
				city_info := map[string]map[string]string{}
				for k1, v1 := range v {
					district_info := map[string]string{}
					if len(v1) == 1 {
						district_info = v1
					}
					city_info[k1] = district_info
				}
				regions_2[k] = city_info
			}
			return regions_2
		}
		return regions_1
	}

	if undistrict > 3 {
		new_regions := map[string]map[string]map[string]string{}
		for k, v := range datas {
			city_info := map[string]map[string]string{}
			for k1, v1 := range v {
				district_info := map[string]string{}
				if len(v1) == 1 {
					district_info = v1
				}
				city_info[k1] = district_info
			}
			new_regions[k] = city_info
		}
		return new_regions
	}
	return datas
}

// 两组比对~找寻补充，排除数据
func AnalysisIsUniqueInfo(regions map[string]map[string]map[string]string, all_regions *map[string]map[string]map[string]string) {
	if len(regions) == 0 {
		return
	}
	if len(*all_regions) == 0 {
		*all_regions = regions
		return
	}
	regionsArr := splitRegionsInfos(regions)          //目标数据
	all_regionsArr := splitRegionsInfos(*all_regions) //源数据
	new_all_regionsArr := []map[string]string{}       //新数据
	for _, info := range regionsArr {
		area := qu.ObjToString(info["area"])
		if (*all_regions)[area] == nil {
			continue
		}
		unmatchInfo1 := ScreenOutReasonableRegionInfo(info, &all_regionsArr, &new_all_regionsArr)
		if unmatchInfo1 != nil { //降级匹配~最多二级
			unmatchInfo2 := ScreenOutReasonableRegionInfo(unmatchInfo1, &all_regionsArr, &new_all_regionsArr)
			if unmatchInfo2 != nil { //降级匹配~最多一级
				ScreenOutReasonableRegionInfo(unmatchInfo2, &all_regionsArr, &new_all_regionsArr)
			}
		}
	}
	//根据最新有效地域组~重新构建所有信息
	reset_regions_infos := map[string]map[string]map[string]string{}
	if len(new_all_regionsArr) > 0 {
		for _, v := range new_all_regionsArr {
			area := qu.ObjToString(v["area"])
			city := qu.ObjToString(v["city"])
			district := qu.ObjToString(v["district"])
			UpdateRegionsInfo(area, city, district, &reset_regions_infos)
		}
		*all_regions = reset_regions_infos
	}
}

// 选取规则方法
func ScreenOutReasonableRegionInfo(info map[string]string, regions_infosArr *[]map[string]string, new_regions_infosArr *[]map[string]string) map[string]string {
	area := qu.ObjToString(info["area"])
	city := qu.ObjToString(info["city"])
	district := qu.ObjToString(info["district"])
	is_Exist := false
	for _, s := range *regions_infosArr {
		s_area := qu.ObjToString(s["area"])
		s_city := qu.ObjToString(s["city"])
		s_district := qu.ObjToString(s["district"])
		if s_area == area && s_city == city && s_district == district {
			is_Exist = true
			*new_regions_infosArr = append(*new_regions_infosArr, info)
		} else {
			//判断是否为补充原则
			if area != "" && city != "" && district != "" { //3级补2级 3级补2级
				if s_area == area && s_city == city && s_district == "" {
					is_Exist = true
					*new_regions_infosArr = append(*new_regions_infosArr, info)
				} else if s_area == area && s_city == "" && s_district == "" {
					is_Exist = true
					*new_regions_infosArr = append(*new_regions_infosArr, info)
				}
			} else if area != "" && city != "" && district == "" { //2级补1级
				if s_area == area && s_city == "" {
					is_Exist = true
					*new_regions_infosArr = append(*new_regions_infosArr, info)
				}
			}
		}
	}

	//若没有补充~针对二三级 再次进行去掉末位一级，再次进行一轮比对
	if !is_Exist {
		if area != "" && city != "" && district != "" {
			return map[string]string{"area": area, "city": city, "district": ""}
		}
		if area != "" && city != "" && district == "" {
			return map[string]string{"area": area, "city": "", "district": ""}
		}
	}
	return nil
}

// 拆分地域数据~目的更好的合并选取
func splitRegionsInfos(infos map[string]map[string]map[string]string) []map[string]string {
	infosArr := []map[string]string{}
	for k, v := range infos {
		if len(v) > 0 {
			for k1, v1 := range v {
				if len(v1) > 0 {
					for k2, _ := range v1 {
						infosArr = append(infosArr, map[string]string{"area": k, "city": k1, "district": k2})
					}
				} else {
					infosArr = append(infosArr, map[string]string{"area": k, "city": k1, "district": ""})
				}
			}
		} else {
			infosArr = append(infosArr, map[string]string{"area": k, "city": "", "district": ""})
		}
	}
	return infosArr
}

// 日志流程记录~组级别
func LogProcessRecordingForGroupInfo(key string, valueArr []string, fieldInfos map[string]interface{}, groupInfos map[string]map[string]map[string]string, finallyInfos map[string]map[string]map[string]string, logRecordInfo *[]map[string]interface{}) {
	groupArr := splitRegionsInfos(groupInfos)
	finalluArr := splitRegionsInfos(finallyInfos)
	data := map[string]interface{}{
		key + "_value":   valueArr,
		key + "_group":   groupArr,
		"finally_region": finalluArr,
	}
	for k, v := range fieldInfos {
		data[k] = v
	}
	*logRecordInfo = append(*logRecordInfo, data)
}

// 日志流程记录~第二链路
func LogProcessRecordingForSupplement(logRecordInfo *[]map[string]interface{}, data map[string]interface{}) {
	*logRecordInfo = append(*logRecordInfo, data)
}

// 日志流程记录~初步
func LogProcessRecordingForTentative(key string, valueArr interface{}, finallyInfos map[string]map[string]map[string]string, logRecordInfo *[]map[string]interface{}) {
	finallyArr := splitRegionsInfos(finallyInfos)
	data := map[string]interface{}{
		key + "_value":   valueArr,
		"finally_region": finallyArr,
	}
	*logRecordInfo = append(*logRecordInfo, data)
}

// 重构地域逻辑顺序
func (e *ExtractTask) IsConsecutionRegion(site string) bool {
	isReset := false
	if tmp := e.SiteCityMap[site]; tmp != nil {
		if tmp.T == "学校" || tmp.T == "军队" || tmp.T == "政府采购" || tmp.T == "公共资源" ||
			tmp.T == "人民政府" || tmp.T == "政府门户" || tmp.T == "在线审批平台" {
			isReset = true
		}
	}
	return isReset
}

// 清洗项目名称
func CleanRegionProjectNameInfo(projectname string, buyer string) string {
	new_str := projectname
	if new_str == "" {
		return new_str
	}
	if buyer != "" {
		new_str = strings.ReplaceAll(projectname, buyer, "")
	}
	if CleanRegionReg1.MatchString(new_str) {
		new_str = CleanRegionReg1.ReplaceAllString(new_str, "")
	}
	return new_str
}

// 清洗文本词组
func CleanRegionTextWords(wordsArr []string) []string {
	if len(wordsArr) <= 1 {
		return wordsArr
	}
	newArr, index := []string{}, 0
	for k, v := range wordsArr {
		if k > 0 && (v == "路" || v == "街道") {
			index = k
			break
		}
	}
	if index > 0 {
		for k, v := range wordsArr {
			if k == index || k == index-1 {
				continue
			}
			newArr = append(newArr, v)
		}
		return newArr
	}

	//清除特殊词组~城区
	for _, v := range wordsArr {
		if v == "城区" {
			continue
		}
		newArr = append(newArr, v)
	}
	return newArr
}

// 链路补充~全称类
func (e *ExtractTask) LinkSpecialRuleFullStep(text string, area *string, city *string, district *string) {
	regions := map[string]map[string]map[string]string{}
	wordsArr := e.Seg_SV.Cut(text, true)
	for _, word := range wordsArr {
		for pos_full, trie_full := range e.Trie_Fulls {
			if pos_full == 3 {
				if trie_full.Get(word) {
					districts := e.StreetDistrictMap[word]
					for _, d := range districts {
						v_area, v_city, v_district := d.C.P.Brief, d.C.Name, d.Name
						UpdateRegionsInfo(v_area, v_city, v_district, &regions)
					}
				}
			}
		}
	}
	if len(regions) > 0 {
		if *area == "" || *area == "全国" { //新增原则
			LinkAddedRules(regions, area, city, district)
		} else { //补充原则
			LinkSuppleRules(regions, area, city, district)
		}
	}
}

// 链路补充~简称类
func (e *ExtractTask) LinkSpecialRuleBriefStep(text string, area *string, city *string, district *string) {
	regions := map[string]map[string]map[string]string{}
	wordsArr := e.Seg_SV.Cut(text, true)
	for _, word := range wordsArr {
		for pos_sim, trie_sim := range e.Trie_Sims {
			if pos_sim == 2 {
				if trie_sim.Get(word) {
					citysArr := e.DistrictSimAndAll[word]
					for _, full_citys := range citysArr {
						for d, c := range full_citys {
							if c == nil || c.P == nil || c.Name == "" {
								continue
							}
							if c.P.Brief != "" && c.Name != "" && d != "" {
								v_area, v_city, v_district := c.P.Brief, c.Name, d
								UpdateRegionsInfo(v_area, v_city, v_district, &regions)
							}
						}
					}
				}
			}
		}
	}
	if len(regions) > 0 {
		if *area == "" || *area == "全国" { //新增原则
			LinkAddedRules(regions, area, city, district)
		} else { //补充原则
			LinkSuppleRules(regions, area, city, district)
		}
	}
}

// 新增原则
func LinkAddedRules(regions map[string]map[string]map[string]string, area *string, city *string, district *string) {
	if len(regions) == 1 {
		for k, v := range regions {
			*area = k
			if len(v) == 1 {
				for k1, v1 := range v {
					*city = k1
					if len(v1) == 1 {
						for k2, _ := range v1 {
							*district = k2
						}
					}
				}
			}
		}
	}
}

// 补充原则
func LinkSuppleRules(regions map[string]map[string]map[string]string, area *string, city *string, district *string) {
	for k, v := range regions {
		if *area == k {
			if len(v) == 1 {
				for k1, v1 := range v {
					*city = k1
					if len(v1) == 1 {
						for k2, _ := range v1 {
							*district = k2
						}
					}
				}
			}
		}
	}

}

// 取出排除表格之外的文本
func TextAfterRemoveTable(con string) string {
	doc2, _ := goquery.NewDocumentFromReader(strings.NewReader(con))
	doc2.Find("table").Remove()
	return doc2.Text()
}

//同组合并的地域数据
//func MergeGroupRegionInfo(datas_1, datas_2 map[string]map[string]map[string]string) map[string]map[string]map[string]string {
//	regions := map[string]map[string]map[string]string{}
//	if len(datas_1) > 0 && len(datas_2) == 0 {
//		return datas_1
//	}
//	if len(datas_2) > 0 && len(datas_1) == 0 {
//		return datas_2
//	}
//	for k, v := range datas_1 {
//		area, city, district := "", "", ""
//		area = k
//		if len(v) > 0 {
//			for k1, v1 := range v {
//				city = k1
//				if len(v1) > 0 {
//					for k2, _ := range v1 {
//						district = k2
//						UpdateRegionsInfo(area, city, district, &regions)
//					}
//				} else {
//					UpdateRegionsInfo(area, city, district, &regions)
//				}
//			}
//		} else {
//			UpdateRegionsInfo(area, city, district, &regions)
//		}
//	}
//
//	for k, v := range datas_2 {
//		area, city, district := "", "", ""
//		area = k
//		if len(v) > 0 {
//			for k1, v1 := range v {
//				city = k1
//				if len(v1) > 0 {
//					for k2, _ := range v1 {
//						district = k2
//						UpdateRegionsInfo(area, city, district, &regions)
//					}
//				} else {
//					UpdateRegionsInfo(area, city, district, &regions)
//				}
//			}
//		} else {
//			UpdateRegionsInfo(area, city, district, &regions)
//		}
//	}
//	return regions
//}

//临时修复校验~~~
//func (e *ExtractTask) temporaryRepairRegionSite() {
//	sess := ju.Site_Mgo.GetMgoConn()
//	defer ju.Site_Mgo.DestoryMongoConn(sess)
//	q, total, isok := map[string]interface{}{}, 0, 0
//	it := sess.DB(ju.Site_Mgo.DbName).C("site").Find(&q).Sort("_id").Select(map[string]interface{}{
//		"area":     1,
//		"city":     1,
//		"district": 1,
//	}).Iter()
//	for tmp := make(map[string]interface{}); it.Next(&tmp); total++ {
//		if total%10000 == 0 {
//			log.Debug("cur index ", total, "~", isok)
//		}
//		area := qu.ObjToString(tmp["area"])
//		city := qu.ObjToString(tmp["city"])
//		district := qu.ObjToString(tmp["district"])
//		isUpdate := false
//		if area == "" {
//			isUpdate = true
//			area = "全国"
//			city = ""
//			district = ""
//		} else {
//			if province := e.ProvinceMap[area]; province != "" {
//				isUpdate = true
//				area = province
//			}
//			if city == "" {
//				district = ""
//			} else {
//				if csMap := e.CityBriefMap[city]; csMap != nil {
//					if csMap.P.Brief == area && csMap.Name != "" {
//						isUpdate = true
//						city = csMap.Name
//					}
//				} else { //市区~为省份的情况
//					if e.CityMap[city] == "" {
//						fmt.Println("市异常~", tmp["_id"])
//					}
//				}
//				if district != "" {
//					citysArr := e.DistrictSimAndAll[district]
//					if len(citysArr) == 1 {
//						full_city := citysArr[0]
//						for d, _ := range full_city {
//							isUpdate = true
//							district = d
//						}
//					} else if len(citysArr) == 0 {
//						fullArr := e.DistrictCityMap[district]
//						if len(fullArr) == 0 {
//							fmt.Println("县异常~", tmp["_id"])
//						}
//					} else {
//
//					}
//				}
//			}
//		}
//		if isUpdate {
//			isok++
//			ju.Site_Mgo.UpdateById("site", BsonTOStringId(tmp["_id"]), map[string]interface{}{
//				"$set": map[string]interface{}{
//					"area":     area,
//					"city":     city,
//					"district": district,
//				},
//			})
//		}
//		tmp = make(map[string]interface{})
//	}
//	log.Debug("监测修复完毕~ ", total, "~", isok)
//
//}
